### File: docs/ai/docs/src/index.md

# AI

This section contains guides and resources for using AI to develop on Fuel.

## Data

To retrieve a single document containing all documentation data from the Fuel Network, including information on Sway, the FuelVM, and the Fuel Stack (TypeScript and Rust SDKs), you can visit the [markdown.fuel.network](https://markdown.fuel.network/). This page provides access to a single Markdown file containing all available documentation.

Alternatively, if you prefer a more structured format with separate Markdown files, you can download the latest documentation here: [markdown.fuel.network/multi-fuel-doc.zip](https://markdown.fuel.network/multi-fuel-doc.zip).

## Resources

- [Fuel MCP Server](https://github.com/FuelLabs/fuel-mcp-server)
- [Context7 MCP Server](https://context7.com/fuellabs/markdown)
- [Devin's DeepWiki](https://deepwiki.com/FuelLabs)


---

### File: docs/contributing/documentation.md


# Documentation Content

All documentation, with the exception of the guides and `intro` section, is pulled in to the `docs-hub` repo via git submodules.

All contributions to the content of the documentation should be done in the original repository.
Below, you will find a list indicating the locations of the source documentation for each book:

- [Sway & Forc](https://github.com/FuelLabs/sway/tree/master/docs/book/src)
- [Rust SDK](https://github.com/FuelLabs/fuels-rs/tree/master/docs/src)
- [TypeScript SDK](https://github.com/FuelLabs/fuels-ts/tree/master/apps/docs/src)
- [Wallet](https://github.com/FuelLabs/fuels-wallet/tree/master/packages/docs/docs)
- [GraphQL API](https://github.com/FuelLabs/fuel-graphql-docs/tree/main/docs)
- [Specs](https://github.com/FuelLabs/fuel-specs/tree/master/src)

## Style Guide

See the [Style Guide](/docs/contributing/style-guide) for guidance on how to edit or write documentation.

## Docs-related GitHub workflows

There are several GitHub actions that run against the docs in each repo to help catch issues. You can learn more about how each of these work in the [`github-actions`](https://github.com/FuelLabs/github-actions/blob/master/docs-hub/README.md) repo.


---

### File: docs/contributing/general.md


# General

You can find the repository for this website on [GitHub](https://github.com/FuelLabs/docs-hub/tree/master). For instructions on how to run the repository locally, see the [README](https://github.com/FuelLabs/docs-hub/blob/master/README.md).

## Contribution flow

This is a rough outline of what a contributor's workflow looks like:

- Create a feature branch off of the master branch, which is typically the base for your work.
- Make your changes, and commit your work.
- Run tests and make sure all tests pass.
- Push your changes to a branch in your fork of the repository and submit a pull request.
  - Use one of the following tags in the title of your PR:
    - `feat:` - A new feature
    - `fix:` - A bug fix
    - `docs:` - Documentation only changes
    - `style:` - Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
    - `refactor:` - A code change that neither fixes a bug nor adds a feature
    - `perf:` - A code change that improves performance
    - `test:` - Adding missing tests or correcting existing tests
    - `build:` - Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
    - `ci:` - Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
    - `chore:` - Other changes that don't modify `src` or test files
    - `revert:` - Reverts a previous commit
- Complete the contributor agreement on the PR if it is not already completed.
- Your PR will be reviewed and some changes may be requested.
  - Once you've made the requested changes, your PR must be re-reviewed and approved.
  - If the PR becomes out of date, you can use GitHub's 'update branch' button.
  - If there are conflicts, you can merge and resolve them locally. Then push to your PR branch. Any changes to the branch will require a re-review.
- GitHub Actions will automatically test all authorized pull requests.
- Use GitHub to merge the PR once approved.

### Linking issues

If the pull request resolves the relevant issues, and you want GitHub to close these issues automatically after it merged into the default branch, you can use the syntax (`KEYWORD #ISSUE-NUMBER`) like this:

```md
close #123
```

If the pull request links an issue but does not close it, you can use the keyword `ref` like this:

```md
ref #456
```

Multiple issues should use full syntax for each issue and separate by a comma, like:

```md
close #123, ref #456
```

## Reporting Bugs

If you notice any bugs in the live website, please create a [new issue](https://github.com/FuelLabs/docs-hub/issues/new) on GitHub with:

- a description of the bug
- step-by-step instructions for how to reproduce the bug


---

### File: docs/contributing/github-workflows.md


# Understanding the GitHub Workflows

The `docs-hub` repo uses GitHub Actions to automate the process of updating the documentation, checking for broken links, and more. This page explains the different workflows and how to fix them if they fail.

## DocSearch Scrap (`docs-scrapper.yml` )

This action updates the Algolia search index by scraping the live [docs.fuel.network](http://docs.fuel.network) site. It only runs when a Fuel contributor manually runs it.

## Guides (`guides.yml` )

This action runs a spell check on all the guides to catch any mispelled words. It also runs Playwright tests for some of the guides to make sure they work as expected.

The files checked for spelling are configured in `.spellcheck.yml`. This is also where you can configure what types of elements are ignored.

If the spell check test fails:

- look up the word in the question to verify it is a real word and is correctly spelled
- If it is a file name or is code, use backticks to ignore the word.
- If it is a real word that is spelled correctly, or an acronym that is either common or is defined already, add it to `spell-check-custom-words.txt`.

- If possible, rewrite the sentence.
- If it otherwise should be ignored, you can configure the pipeline in `.spellcheck.yml`.

To fix a failed guides test, refer to the [Guides Testing](/docs/contributing/guides/#testing) section.

## Links (`links.yml` )

This workflow tests the links in the docs-hub to make sure none are broken.

## PR Checks (`pr.yml` )

This workflow checks the name of the pull request, checks to make sure there are no dependency vulnerabilities, and runs a lint check for the markdown files and code.

To fix a failing PR title check, change the name of your PR so it uses the convention below:

```sh
Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit
```

To fix a failing audit check:

```bash
pnpm audit --fix
pnpm install
```

To fix a failing lint check:

```bash
pnpm lint:fix:all 
```

## Update Nightly (`update-nightly.yml` )

This workflow runs every day Monday through Friday to update the `nightly` version of the documentation. See the [Versions](/docs/contributing/versions) section for more information.


---

### File: docs/contributing/guides.md


# Guides

All guides can be found in the [`docs/guides`](https://github.com/FuelLabs/docs-hub/tree/master/docs/guides) folder of the `docs-hub` repo.

The guide content is in the [`docs/guides/docs`](https://github.com/FuelLabs/docs-hub/tree/master/docs/guides/docs) folder while the example code is found in the [`docs/guides/examples`](https://github.com/FuelLabs/docs-hub/tree/master/docs/guides/examples) folder.

Note that the some content is pulled in from submodules. To make any changes to the content or code from a submodule, you must make a pull request on the source repo.

## Style Guide

See the [Style Guide](/docs/contributing/style-guide) for guidance on how to edit or write guides.

## Testing

Some guides are tested with a GitHub workflow that runs on pull requests.
If you are creating a new guide, it is recommended you create a test using the `TestAction` component.

You can run the tests locally with the command below:

```sh
pnpm test:guides
```

Here is how it works:

Within the guide markdown files, there are `TestAction` components that are used run a Playwright test. The test follows each step in the guide based on these components and checks to see if everything works as expected. You can find the test files inside the `tests` folder.

The `TestAction` component accepts two props:

```tsx
[CodeImport snippet: comment=test-action-props, lines=undefined-undefined]
```

The `id`  must be a unique string id.
The `action`  prop contains information about the action to run the in test.

You can find examples for how to use this component in the [`docs/guides/docs`](https://github.com/FuelLabs/docs-hub/tree/master/docs/guides/docs) folder, you can find all of the action options in [`tests/utils/types.ts`](https://github.com/FuelLabs/docs-hub/blob/master/tests/utils/types.ts).

Refer to the [Playwright docs](https://playwright.dev/) for information on locators and selecting elements in a test.


---

### File: docs/contributing/index.md


# Contributing

🌟 **Welcome, and thank you for considering contributing to the Fuel docs!** 🌟

Before you get started, please take a moment to read through this contributing guide.
It contains important information and helpful tips for contributing to the Fuel documentation and guides.

- [General](/docs/contributing/general)
- [Documentation](/docs/contributing/documentation)
- [Guides](/docs/contributing/guides)
- [Style Guide](/docs/contributing/style-guide)
- [Versions](/docs/contributing/versions)
- [GitHub Workflows](/docs/contributing/github-workflows)


---

### File: docs/contributing/style-guide.md


# Style Guide

This style guide is a set of guidelines for writing and editing documentation. It's important to follow these guidelines to ensure that our documentation is consistent and easy to read.

## General Guidelines

### Writing

- Use a friendly and conversational tone of voice.
- Use an active voice (vs. a passive voice).
- Avoid long paragraphs or sentences.
- Always use accurate and verified information.
- Maintain consistency in style across pages and sections.
- Assume the reader does not have a lot of context. Keep in mind that readers have different levels of expertise.
- Don't use *click here* or *read this document* for links. Just link [the thing](https://en.wikipedia.org/wiki/The_Thing_(1982_film)) in context.
- Don’t use double negatives.

### Words

- Use second-person perspective (use *you*).
- Use American English.
- Use simple (but accurate) words.
- Avoid slang, jargon, or making up new words. Everything should be easy to translate into major languages.
- Avoid gendered words or pronouns like “his”, “her”, “manned”, etc.
- Define acronyms and abbreviations on first usage and if they're used infrequently.
- Use italics or bold text to emphasize a word. Avoid using all capital letters.
- Avoid using words that indicate time like “new feature”, as it may fall out-of-date quickly.
- Avoid the word “please” in an instruction.
- Avoid violent words.
- Don’t use offensive language.

### Code

- Use code examples whenever possible.
- Always specify the language of a code block.
- Avoid hard-coded examples, and instead import code examples from code that is routinely tested.
- Use comments to define code examples to be imported instead of line numbers that may change.
- Always wrap inline code in backticks.
- Always use code fences when showing commands and separate commands from console outputs. The user should be able to copy and paste the entire code in the code fence.
- Use descriptive variable names in code examples. Don’t use `foo` , `bar` , `baz` , etc.

### Organizing Information

- Use the standard HTML heading hierarchy: The first line should be an `h1` (use 1 # in markdown) and should be the only `h1` on the page. The subheadings shouldn’t skip a level, e.g. `h3` tags should only be inside `h2` tags.
- Organize information so that readers can skim the page and get an answer for the most common questions quickly. Use subheadings to call out important information, and use a blockquote to identify supplemental information.
- Avoid using tables.

### Graphics

- Don’t create complex flow-charts (having more than 5-6 items).
- Don't use images of text or code. Use the actual text or code in markdown format.

### Lists

- Use numbers, number-letter combinations (1.a, etc.), or bullet points for lists. Do not use Roman numerals or letters alone.

## Guides

If you are writing for a guide or the `intro` section, follow these additional guidelines:

### Components

To maintain accuracy and consistency, it is recommended to use the available React components within a guide whenever they apply. For example:

- Use the `CodeImport` and `TextImport` components instead of copying and pasting code or text.
- For images, use the `Box.Centered` component to center the image.
- For content only applicable to a certain version of the docs, use the `ConditionalContent` component.

You can find examples for how to these components within the [`docs/guides/docs`](https://github.com/FuelLabs/docs-hub/tree/master/docs/guides/docs) folder.

For a full list of components available, see the [`src/components/MDXRender.tsx`](https://github.com/FuelLabs/docs-hub/blob/master/src/components/MDXRender.tsx) component.

### Variables

There are several variables passed into the MDX context that you can use within a guide. You can find a full list in the [`src/components/MDXRender.tsx`](https://github.com/FuelLabs/docs-hub/blob/master/src/components/MDXRender.tsx) component.

You can then use these variables within a guide like so:

```mdx
The faucet URL is {props.faucetUrl}
```

Which would render as:
The faucet URL is {props.faucetUrl}


---

### File: docs/contributing/versions.md


# Versions

There are two version sets of the docs available in the `docs-hub`: `testnet`(the default version), and `nightly`.

- The default version set is compatible with the `latest` toolchain and testnet.
- The `nightly` version set reflects the latest releases on GitHub. These versions may not be compatible with each other.

## Updating the Nightly Versions

There is a Github action that runs every Monday and Thursday at 12:00 UTC to update the `nightly` versions of the docs.

You can also update the nightly versions locally by running the command below:

```sh
pnpm docs:update:nightly
```

The `nightly` versions should be kept at the latest release on GitHub for each tool.

## Updating the Default Versions

To change the default versions, update the [`src/config/versions.json`](https://github.com/FuelLabs/docs-hub/blob/master/src/config/versions.json) file and run this command:

```sh
pnpm docs:update
```

This command will both update the the default versions to match the configuration file and make sure the nightly versions are updated.

Here is how to decide what default versions to use:

- The Sway & `forc` versions should match what is on the `latest` toolchain.
- The version of the wallet SDK should match the version of the Fuel Wallet extension if it is compatible with the `latest` toolchain. If the extension is not yet compatible, use the latest release that is compatible.
- The version of the Rust SDK should be the latest release that is compatible with the default version of `forc`.
- The version of the TypeScript SDK should be the latest release that is compatible with the default version of `forc` and the Fuel wallet.
- The version of the GraphQL API and Specs books should reflect the version of `fuel-core` used in the latest testnet. These books currently do not have regular releases.


---

### File: docs/fuel-book/docs/src/conclusion/index.md

# Conclusion

Thank you for exploring the Fuel Book. We hope it has provided you with a deeper understanding of the motivations, philosophies, and technical innovations that drive our work. Fuel represents more than just a high-performance blockchain solution—it’s a vision for a decentralized future built on speed, security, and scalability.

As you continue your journey with Fuel, remember that our community thrives on collaboration and shared learning. Whether you're a developer, researcher, or blockchain enthusiast, we invite you to engage with our growing ecosystem, contribute your ideas, and help shape the future of decentralized technology.


---

### File: docs/fuel-book/docs/src/fuels-future/data-streaming.md

# Data Streaming

While many projects have focused energy on improving the performance of writing data to blockchains, less attention has been paid to optimizing how to read data from a blockchain. In the future, Fuel will radically restructure how data gets propagated from block-producers out to the various end-users of a network.

Current blockchain applications read data from a network by repeatedly “pinging” an RPC node, asking that node to provide the current state of the network and then checking for updates locally. This method of “polling” for new data is extremely inefficient for all parties, placing computational and network burdens on both the client and server. Furthermore, the “pull” nature of this system means that there will always be some extra latency introduced into the transaction. And in the world of finance, time is money.

Fuel aims to flip the data model on its head, creating a push/subscription model of disseminating data across a network. Fuel will enable block-producers to stream every phase of the transaction supply chain from their own servers, out through a network of lightweight relayers, on to end users. This allows users to have fast access to blockchain data without requiring unnecessary “polling”, and allows financial actors to have the fastest access to the financial information they care about.


---

### File: docs/fuel-book/docs/src/fuels-future/decentralized-block-building.md

# Decentralized Block Building

Fully decentralizing block production is the final step towards creating rollups that fully embody the important values of decentralized blockchains.

In addition to simply ensuring that blockchains remain permissionless and censorship-resistant, decentralized block-building will also expand the surface area for how applications can be developed.


---

### File: docs/fuel-book/docs/src/fuels-future/index.md

# Chapter 3 - Fuel's Future

Fuel Ignition's launch establishes the groundwork for a network of high-performance blockchains and diverse infrastructure, supporting numerous decentralized applications.

Post-mainnet, Fuel will introduce a range of advanced features to elevate blockchain technology.

- [3.1 - A Network of Interconnected L2s & L3s](./network-of-interconnection.md)
- [3.2 - Decentralized Block Building](./decentralized-block-building.md)
- [3.3 - SNAP Fast Finality Gadget](./snap-fast-finality-gadget.md)
- [3.4 - State Rehydration](./state-rehydration.md)
- [3.5 - Data Streaming](./data-streaming.md)


---

### File: docs/fuel-book/docs/src/fuels-future/network-of-interconnection.md

# A Network of Interconnected L2s & L3s

Fuel Ignition is the beach-head network, introducing the Fuel technology to the world. However, as the technology matures and the ecosystem grows, this technology will be used to power a growing ecosystem of modular rollups. Developers choose to launch independent chains either to customize the stack, to capture economic value, or simply to build an independent ecosystem for community building.

Fuel’s technology already enables the fastest execution and lowest fees, and future development will ensure these chains can easily interoperate with other chains throughout the ecosystem. Fuel’s light-clients, shared sequencer, combined with the SNAP finality gadget (described below) allow these chains to reduce their friction.


---

### File: docs/fuel-book/docs/src/fuels-future/snap-fast-finality-gadget.md

# SNAP Fast Finality Gadget

One of the most well-known limitations of rollups is the long periods of time needed to send messages from the layer-2 back up to the layer-1 chain. Users of optimistic rollups such as Arbitrum and Optimism face a notable drawback: a week-long wait period for asset withdrawals from the network.While ZK-rollups do offer reduced settlement times, the economics of proving mean that proofs (and therefore withdrawals) can still take up to 24 hours to process.

Fuel has proposed a theoretical new mechanism for substantially reducing the finality time of optimistic rollups. While the full details are [outlined in a post on ETHResearch](https://ethresear.ch/t/why-wait-a-week-fast-finality-optimistic-rollups/18868), the mechanism can be understood at a high level as using a bonded committee of operators to attest to both the validity of the chain, as well as the state of Ethereum not being censored.


---

### File: docs/fuel-book/docs/src/fuels-future/state-rehydration.md

# State Rehydration

Typical blockchain applications treat the chain’s state as a large, public, distributed database. These applications write data to the chain in a similar manner to how a Web2 application would write to a cloud-hosted database.
However, this imposes a large burden on the network, which must maintain this data on all nodes. The immutable nature of blockchains means this data is generally stored forever.

Fuel aims to address this issue using a technique known as “state rehydration”. This technique uses the blockchain as a system for maintaining consensus over state commitments, as opposed to a system for syncing a large database.

Specifically, this technique takes advantage of the fact that “calldata” and hashing are relatively inexpensive compared to state storage. State rehydration means that a transaction includes all the state data needed for an action, and this state will be validated against a single on-chain hash as a state commitment. In turn, an application will update the state by hashing the new state values, storing this “dehydrated” commitment in state, and emitting the full state in a log so it can be made available off-chain.

Many current parts of Fuel are considered “state rehydration”, such as predicates which require users to provide the account’s bytecode. Furthermore, some applications have taken state rehydration a step further, using UTXOs and predicates to provide further state reductions.

However, Fuel’s roadmap aims to bring state-rehydration to a level where it can power any arbitrary blockchain application. This requires a full integration between users, block-builders, and off-chain indexers, allowing various parties to pay to reconstruct the state in a completed block. This technique will leverage Fuel’s planned decentralized block-building mechanisms.


---

### File: docs/fuel-book/docs/src/glossary/index.md

# Glossary

**Contract:** Primitives allowing for building stateful applications on Fuel, facilitates complex stateful applications like AMMs, Vaults, etc.

**Context:** Provides policies that determine what features can some running FuelVM bytecode use, for example the ability to call smart contracts, use persistent storage, etc.

**Cryptography:** The practice of securing information and communications through mathematical techniques, ensuring data confidentiality, integrity, and authenticity in blockchain systems.

**Ephemeral scripting:** Scripts or code that are temporary and designed for short-term, single-use purposes. These scripts are typically used for tasks that do not require persistent state or long-term execution and are often discarded or removed after they fulfill their function.

**Ethereum Virtual Machine (EVM):** A decentralized computing environment that executes smart contracts on the Ethereum blockchain.

**Finality:** The point at which a transaction is considered permanently recorded on the blockchain and cannot be altered or reversed, providing assurance that it is completed.

**Forc:** A command-line toolchain that serves as the backbone of Fuel development. It supports everything from compiling Sway smart contracts to managing dependencies and deploying applications.

**Fuel Ignition:** Will be the first Fuel V2 rollup to go live on Ethereum Mainnet. It aims to surpass traditional EVM rollups by delivering a vastly improved execution design.

**Fuel Rust SDK:** A developer tool that allows developers to interact with Fuel’s blockchain using the Rust programming language. It offers a seamless experience for creating system-level applications and managing interactions with the Fuel Network.

**Fuel Typescript SDK:** A developer tool that allows developers to integrate Fuel into web applications. It simplifies interaction with the Fuel blockchain, making it easy for frontend developers to build decentralized applications that interact with Fuel’s infrastructure.

**Fuel Virtual Machine (FuelVM):** A high-performance execution environment for the Fuel Network that enables parallel transaction processing, achieving up to 21,000 transactions per second per core. It optimizes resource use and minimizes demands on full nodes, enhancing network sustainability and decentralization.

**Fuel Wallet SDK:** A developer tool that provides developers with the tools to create secure, user-friendly wallets that natively interact with the Fuel ecosystem. It ensures developers can easily build wallets that integrate into decentralized applications.

**Interoperability:** The ability of different networks to communicate and exchange assets or data seamlessly, enabling cross-chain functionality without intermediaries.

**Layer 1:** A base blockchain network (e.g., Bitcoin, Ethereum) responsible for processing and finalizing transactions directly on its ledger.

**Layer 2:** An off-chain scaling solution built on top of a Layer 1 blockchain to improve transaction speed and reduce costs while still relying on Layer 1 for security and finality.

**Merkle Tree:** A data structure used in blockchains to efficiently and securely verify large sets of transactions, by organizing them into a tree-like structure where each node is a cryptographic hash of its children.

**Native Assets:** Cryptocurrencies or tokens that are built into and exist directly on a blockchain, serving as the primary currency for that network.

**Optimistic Rollup:** A Layer 2 scaling solution that processes transactions off-chain while assuming they are valid by default, requiring participants to challenge fraudulent transactions within a specific time frame. If no challenges are made, the transactions are considered valid and finalized on the Layer 1 blockchain.

**Parallelism:** The ability to process multiple transactions simultaneously.

**Predicate:** A stateless smart account that allows transactions to execute in parallel without conflict.

**Proposer-Builder Separation (PBS):** Proposer-builder separation (PBS) is an Ethereum concept designed to enhance network scalability and security by splitting block building responsibilities into two distinct roles: block proposers and block builders.

**Rollup:** A Layer 2 scaling solution that batches multiple transactions into a single one and processes them off-chain, while still ensuring security and finality on the Layer 1 blockchain.

**Scalability:** The capability of a blockchain to handle an increasing number of transactions or users without compromising performance, security, or decentralization.

**Script:** Entrypoint for fuel transactions which dictates what happens as part of a Fuel transaction.

**State:** All the data a blockchain needs to store and maintain.

**State Tree:** A data structure used in blockchains to represent the current state of all accounts, smart contracts, and their balances. It allows for efficient storage and retrieval of state information, often enabling quick verification and updates during transaction processing.

**Sway:** a domain specific language (DSL) for modern blockchain programming which has familiar syntax, grammar and design ideology to Rust while incorporating blockchain specific functionality such as smart contract interface concepts.

**Throughput:** The number of transactions a blockchain can process within a given time frame, often measured in transactions per second (TPS).

**Unspent Transaction Output (UTXO):** The model used for tracking asset ownership, contracts, messages and transactions.

**Virtual Machine (VM):** An environment that executes smart contracts on a blockchain, enabling developers to run code in a decentralized manner without needing to interact with the underlying hardware.

**Zero Knowledge:** A cryptographic method that allows one party to prove to another that they know a value without revealing the value itself or any other information.


---

### File: docs/fuel-book/docs/src/index.md

# Introduction

Welcome to the Fuel Book, your comprehensive guide to Fuel. This book serves not only as a reference but also reflects our motivations for building Fuel and the philosophies we have incorporated into it.

Our main goal is to dive deeper into the "why" behind Fuel, moving beyond just the technicalities to explore the foundational philosophies and inspirations that guide our work.

We recognize that our audience encompasses developers, researchers, and blockchain enthusiasts. We’ve made it easier to find relevant information, and structured the book with specific sections tailored to different user needs:

**Table of Contents:** Quickly locate specific sections of interest.

**Key Terms and Glossary:** Throughout the book, you will come across terminology unique to the Fuel ecosystem and blockchain, so we included a glossary at the end.

**Visuals:** We also included diagrams and illustrations to clarify complex ideas.

**Further Reading:** At the end of each section, you’ll find recommendations for further reading and resources to deepen your understanding and provide additional context.

**Interactive Components:** For our hands-on learners, we’ve included links to our online resources and community forums. Connect with like-minded Fuel community members and developers to collaborate on learning or building!


---

### File: docs/fuel-book/docs/src/the-architecture/block-building-in-fuel.md

# Block Building in Fuel

Highlights:

- The Block Builder plays a pivotal role in block building within Fuel by processing messages and transactions, constructing blocks, and submitting them to Layer 1 while ensuring soft-finality on Layer 2.

- The Fuel Block Builder uses a messaging system to facilitate the transfer of information between Layer 1 and Layer 2, enabling both regular transactions and forced transaction inclusion. This feature empowers users to bypass potential censorship by relaying their transactions directly from Layer 1.

- To guarantee reliable processing of messages and transactions, the Block Builder appends a data height (da_height) to each block, linking it to a specific Layer 1 block. By utilizing Merkle trees to store commitments, the system ensures that all events are processed in a deterministic manner, allowing for transparent validation and slashing of the Block Builder if necessary.

- The Block Builder also processes local transactions, allowing users to send transactions directly to it for more efficient batching and compression. This method reduces transaction costs and accelerates soft finality, providing users - with quicker confirmations compared to traditional Layer 1 submissions.

- The Block Builder determines transaction ordering and manages miner extractable value (MEV) in Fuel. It prioritizes transactions based on the tips provided, contrasting with the first-in-first-out approach found in many other Layer 2 solutions, which optimizes user incentives within the network.

This section focuses on block building in Fuel and the role that the Block Builder plays in this process.

The Fuel Block Builder is a component in Fuel rollups, which is responsible for:

- Processing messages from L1 → L2

- Processing transactions in the mempool

- Building blocks and submitting them to the Layer 1

- Providing soft-finality on the Layer 2

## L1 → L2 processing

Fuel rollups have a messaging system (from L1 → L2 and vice versa), which we will discuss further in the next section on bridging. In addition to relaying bridge messages, this system allows transactions to be sent directly from L1, which is used for forced transaction inclusion.

The Fuel Block Builder uses a relay to receive messages and transactions from L1 → L2, we will discuss both of these cases individually now.

### L1 Messages

Block Builder receives relayed messages from Layer 1 emitted as L1 events. The message is then picked up as part of the block-building process; each message sent from the L1 has the following format:

| name      | type      | description                                                  |
|-----------|-----------|--------------------------------------------------------------|
| sender    | bytes[32] | The identity of the sender of the message on the L1          |
| recipient | bytes[32] | The recipient of the message on the Fuel Blockchain          |
| nonce     | bytes[32] | Unique identifier of the message assigned by the L1 contract |
| amount    | uint64    | The amount of the base asset transfer                        |
| data      | byte[]    | Arbitrary message data                                       |

The block builder creates an output of type `OutputMessage`, and after creating this output, it completes the message processing.

Applications can leverage these `OutputMessage(s)` as they see fit. One example is the deposit process, where the bridge contract mints new ETH on the L2 after receiving specific messages that prove deposits on the L1 (we will discuss this further in the next section).

### L1 Transactions and Forced Inclusion

Fuel provides forced inclusion of transactions. If a user feels the L2 block builder is attempting to censor, they can emit a serialized transaction from the L1 as an event, forcing the L2 block builder to include the transaction in the block building. This process, called “Forced Inclusion,” guarantees user censorship resistance.

The Fuel transactions sent from L1 are emitted as events via the L1 and have the following format:

| name                   | type      | description                                                        |
|------------------------|-----------|--------------------------------------------------------------------|
| nonce                  | bytes[32] | Unique identifier of the transaction assigned by the L1 contract   |
| max_gas                | uint64    | The maximum amount of gas allowed to use on Fuel Blockchain        |
| serialized_transaction | byte[]    | The serialized transaction bytes following canonical serialization |

Forced Inclusion allows the processing of all transaction types except `Mint`, which can only be created by the Fuel Block Builder. This exception does not restrict security guarantees for users' censorship resistance.

### Guarantees around L1 processing

How does the L2 guarantee it will always process messages or transactions sent from L1?

This is done by appending the `da_height`, i.e., the L1 block up to which the current block processes messages and transactions. A commitment for all the events and transactions is stored as part of the block header, using a Merkle tree and its root.

All events from L1 → L2 (both inbox messages and forced transactions), are ordered by their block number and the index in that block. Following this order allows us to find a deterministic way of creating this Merkle tree.

We create this Merkle tree and store the root in the `event_inbox_root` field as part of the block header.

Fuel blocks are subject to later challenges. If it's proven that a specific message or transaction was omitted or not processed, the responsible block builder can be penalized.

## Processing Local Transactions

Apart from processing messages and transactions from L1 → L2, the Block Builder is responsible for processing transactions sent to it locally. Users can send transactions to the Block Builder locally, collected in its Mempool, and then processed and sent to Layer 1.

By using clever batching and compression techniques (gzip or zstd) this system offers users lower transaction costs compared to direct Layer 1 submissions.

Another advantage of sending transactions directly to the Block Builder is getting faster soft finality on the L2. For a transaction sent via L1 to be processed, the L1 block must be finalized first.

## Block Building and Proposing

The Fuel Block Builder is required to bundle transactions into blocks and propose them to Layer 1 as part of processing transactions. Committed blocks on Fuel enter a ['Challenge Window'](./fuel-and-ethereum.md#challenge-window) after commitment. Once this window closes, the block and its corresponding state are considered to have reached 'L1 finality'.

Fuel Block Builder currently sends the block hash and block height as new updates to the onchain message portal, along with blobs containing transactions and other data,  to provide DA for that specific block.

## Transaction Ordering and MEV

The current Fuel Block Builder decides the priority of a transaction by sorting with `tip/max_gas`, which means unlike many other L2s, the network isn’t FIFO (First In First Out); this also means that in Fuel, the Priority of your transaction inclusion is:

- Directly proportional to the `tip` you provide as part of the transaction

- Inversely proportional to the `max_gas` you permit for your transaction

## Soft Finality

The Block Builder also plays a major role in providing soft finality for L2 transactions. As an L2 participant, you can choose the level of finality at which you're comfortable making business decisions.

When the Block Builder orders and processes your transaction, it provides a soft finality. This can be considered confirmed unless the Block Builder fails to finalize it on L1.

## Appendix

### Full Nodes

The [fuel-core](https://github.com/FuelLabs/fuel-core) software also allows you to run a Full Node. A Full Node collects the latest updates on Layer 2 from the peers and broadcasts incoming transactions to the network.

Full Nodes cannot build blocks; instead, they receive them as updates via p2p and re-execute them locally to maintain the correct state with complete verification.

By running the Full Node, you can, as a user, be given the ability to keep verifying the L2 yourself and, hence, also be able to send fraud proofs. You also get your own GraphQL endpoint, which can broadcast your transactions to the network.

All Fuel GraphQL providers run Full Nodes themselves to provide you with the latest Fuel state and allow you to broadcast transactions.


---

### File: docs/fuel-book/docs/src/the-architecture/fees-on-fuel.md

# Fees on Fuel

The Fuel ignition process introduces various fees and costs essential for utilizing the permissionless network. These can be categorized into the following types:

- **Transaction Fees:** A mandatory fee paid to validators for processing transactions and executing instructions on the network.
- **Tip:** An optional fee that allows users to boost their transactions in the processing order, ensuring faster execution.

## Fuel’s Approach to Transaction Fees

### Fee Structure

Fuel operates on a modular execution layer, emphasizing efficiency in gas computation and storage fees. Instead of relying on inflationary rewards, Fuel focuses on sustainable economics driven by transaction fees. [Learn more.](https://docs.fuel.network/docs/specs/fuel-vm/#script-execution)

### Parallel Execution for Low Fees

Fuel’s unique parallel transaction execution significantly reduces congestion. This results in:

- Lower transaction fees.
- Faster settlement times, which encourages a high volume of transactions.
  
This aligns with the long-term vision of most blockchains to sustain security through transaction fees rather than inflation.

## Transaction Fees in the Fuel Network

In the Fuel network, transaction fees are essential for incentivizing block builders to prioritize transactions and for maintaining network security and efficiency. Understanding how transaction fees are calculated and how they are used helps users make informed decisions on how to interact with the network.

## What Are Transaction Fees?

Transaction fees in Fuel are the costs that users must pay to process and execute their transactions on the network. These fees are dynamic and depend on several factors, including the gas consumed by the transaction, the gas price, and the gas limit set by the user.

Transaction fees are calculated based on gas consumption during the execution of the transaction. There are two main components that determine the cost:

- **Intrinsic Fees:** The fundamental costs associated with a transaction, including the byte size, processing of inputs/outputs, predicates and signature verification, and initializing the virtual machine (VM). These fees are incurred regardless of whether the transaction is successfully executed.  
- **Execution Fees:** Costs associated with the computational work performed during the transaction, determined by the complexity of operations such as smart contract execution, data manipulation, and VM computations.  

## Gas Consumption Breakdown  

- **Intrinsic Gas Fees:** These cover the basic costs of transaction handling, which include:  
  - Byte size of the transaction.  
  - Input/output processing.  
  - Predicate evaluation and signature verification.  
  - VM initialization (prior to executing scripts or predicates).  

- **Execution Gas Fees:** These fees account for the gas consumed during the execution phase of the transaction, such as:  
  - Smart contract execution.  
  - Data processing and storage.  
  - Interactions with decentralized applications (dApps) or other smart contracts.  
The total fee for a transaction is calculated using the following formula:

```python
def cost(tx, gasPrice) -> int:
   return gas_to_fee(min_gas(tx) + tx.gasLimit - unspentGas, gasPrice)
```

Where:

- `min_gas(tx)`: Minimum gas required for the transaction, covering intrinsic fees.
- `tx.gasLimit`: The maximum amount of gas that the user is willing to spend for this transaction.
- `unspentGas`: Gas left over after intrinsic costs and execution. This is collected by the block producer as a reward in the Fuel
  network.
- `gas_to_fee()`: Converts the total gas used (after considering min gas, gas limit, and unspent gas) into a fee based on the gasPrice.

The final transaction fee depends on the amount of gas consumed during execution and the gas price specified by the user.

If the transaction uses less gas than the gas limit set by the user, the leftover gas (referred to as unspent gas) is collected by  block builder as a reward.

`The block gas limit is 30000000`

## Tips in the Fuel Network

Tips are an additional fee provided by the user to incentivize block builders to prioritize their transaction. In Fuel, the priority of your transaction’s inclusion in the block is determined by both the tip and the max_gas (gas limit) you set for the transaction.

## What is a Tip?

A tip is an extra fee that the user adds on top of the minimum transaction fees to increase the likelihood that their transaction will be included in the next block. This tip directly incentivizes the block builder to prioritize the transaction.

- **Setting the Tip in a Transaction**

To set the tip in a transaction using the Fuel SDK, you can specify it in the transaction parameters. Here’s an example in TypeScript using the fuels library:

```typescript
import { bn, ScriptTransactionRequest } from 'fuels';

const transactionRequest = new ScriptTransactionRequest({
  tip: bn(10), // Sets the tip policy
  maxFee: bn(1), // Sets the max fee policy
});
```

In this example, the tip is set to 10 using the bn function to handle big numbers. The tip is an optional amount added to incentivize the block producer to include the transaction, ensuring faster processing for those willing to pay more.

## Fee Structure and Incentives

Fuel uses a dynamic fee model where transaction fees are adjusted based on network congestion, transaction complexity, and the user’s willingness to pay higher fees. Block builders are incentivized based on both the tip and max_gas (gas limit), creating a flexible and efficient system.

## Transaction Prioritization

In Fuel, transactions are prioritized by the block builder based on two main factors:

- **Tip:** The additional gas fee provided by the user to incentivize faster processing of the transaction. A higher tip means higher priority for inclusion in the block.
- **max_gas:** The maximum gas limit specified by the user for the transaction. A higher max_gas means the transaction may take longer to process, lowering its priority.

The priority of a transaction is:

- Directly proportional to the tip: Higher tips increase the transaction’s priority.
- Inversely proportional to the max_gas: A higher gas limit decreases the transaction’s priority.

This model encourages users to offer a higher tip to ensure quicker inclusion, while also considering the transaction’s gas limit to avoid excessively large transactions.

## Unspent Gas and Block Producer Rewards

After a transaction is executed, any leftover gas (`unspentGas`) is collected by the block producer as a reward.

- **UnspentGas:** The remaining Gas left over after intrinsic costs and execution. This is collected by the block producer as a reward in the Fuel
- **Block Producer Incentives:** Block producers are rewarded for processing transactions, both through the minimum fee (guaranteed for each transaction) and the unspent gas collected.

The unspent gas ensures that block producers are incentivized to prioritize transactions with higher tips and to optimize block space for better overall performance.

## Example Gas Calculation

Here’s a simplified example of how gas works in Fuel:

- **Transaction:** A user sends tokens to another account.
- **Gas Calculation:**
  - Compute Gas: CPU work required to validate the transaction.
  - Storage Gas: Updating the account balance in the blockchain.

If the gas limit is set to 10,000 and the gas price is 1 gwei, the total fee would be:

- 10,000 x 1 gwei = 10,000 gwei (or 0.00001 ETH ).

When a transaction involves script execution, the system sets up the virtual machine (VM) to run the transaction. It checks the amount of gas available for the transaction and starts running the script step by step.

For each step in the script, the system calculates how much gas it needs. If there isn’t enough gas left to run a step, it stops the process and “reverts” the transaction, meaning nothing changes except for the gas spent. If there’s enough gas, it continues running the script and deducts the gas used. [Learn more](https://docs.fuel.network/docs/fuel-book/the-architecture/transactions-on-fuel)

At the end of the transaction, the system updates a record (called the `receiptsRoot`) to show the results of the transaction. This process helps ensure that the transaction is handled efficiently and fairly, with gas being used properly.

## Fee Calculation Example

Let’s consider a transaction with the following parameters:

- Intrinsic Gas (`min_gas(tx)`): 10,000 gas
- Gas Limit (`tx.gasLimit`): 50,000 gas
- Unspent Gas (`unspentGas`): 5,000 gas
- Gas Price (`gasPrice`): 0.001 Fuel per gas unit

The transaction fee will be calculated as:

```python
min_gas = 10000
gasLimit = 50000
unspentGas = 5000
gasPrice = 0.001

# Total gas used for the transaction
totalGas = min_gas + gasLimit - unspentGas

# Convert gas to fee
fee = gas_to_fee(totalGas, gasPrice)
```

This fee is the final cost that the user will pay for the transaction, which includes both intrinsic and execution gas fees, adjusted based on the gas price. Note that `gasLimit` applies to transactions of type Script. `gasLimit` is not applicable for transactions of type Create and is defined to equal 0 in the above formula.

## Transaction Parameters

The following are the available parameters to control transaction behavior:

```typescript
const txParams: TxParams = {
  gasLimit: bn(70935),
  maxFee: bn(69242),
  tip: bn(100),
};
```

### Explanation of Parameters

- **Gas Limit (`gasLimit`):** The maximum amount of gas you're willing to allow the transaction to consume. If the transaction requires more gas than this limit, it will fail.
  - Example: `gasLimit: bn(70935)`
- **Max Fee (`maxFee`):** The maximum amount you're willing to pay for the transaction using the base asset. This allows users to set an upper limit on the transaction fee they are willing to pay, preventing unexpected high costs due to sudden network congestion or fee spikes.
  - Example: `maxFee: bn(69242)`
- **Tip (`tip`):** An optional amount of the base asset to incentivize the block producer to include the transaction, ensuring faster processing for those willing to pay more. The value set here will be added to the transaction maxFee.
  - Example: `tip: bn(100)`

--------

Fuel’s transaction fee model provides a balanced approach to cost and incentivization:

- Transaction Fees are composed of intrinsic and execution gas fees, with the `gasPrice` determining the final transaction cost.
- Tip and `max_gas` determine transaction priority, allowing users to prioritize their transactions by increasing the tip or adjusting the gas limit.

By setting parameters such as `gasLimit`, `maxFee`, `tip`, and others, users have full control over the cost and priority of their transactions, ensuring a flexible and efficient experience within the Fuel network.


---

### File: docs/fuel-book/docs/src/the-architecture/fuel-and-ethereum.md

# Fuel and Ethereum

Highlights:

- Fuel Ignition leverages Ethereum as its Layer 1 for settlement and data availability, aligning with Ethereum's core values of sustainability, security, and accessibility for everyday users. This choice emphasizes Fuel's commitment to building a long-term, decentralized ecosystem.

- By utilizing one of the most established and decentralized Layer 1 networks, Ethereum provides a robust foundation for Fuel’s rollup, ensuring reliable performance and security. Fuel's rollup inherits Ethereum's security model, which safeguards user funds and enables fraud-proof mechanisms directly on the Ethereum blockchain.

- Fuel allows seamless messaging between Layer 1 and Layer 2, ensuring that any message sent to Ethereum must be processed on Fuel and vice versa. This capability enhances user experience and guarantees censorship resistance.

- Users can easily deposit and withdraw ETH, transferring assets between Layer 1 and Layer 2. They can deposit ETH directly to Fuel and initiate withdrawals by burning tokens on Layer 2, with the system ensuring timely and secure processing.

- Fuel actively pursues innovation through techniques like hybrid proving, optimizing the proving system by reducing complexity and shortening challenge windows. By embracing a modular tech stack, Fuel remains adaptable, exploring integration with alternative Layer 1s and data availability solutions to enhance its ecosystem.

Fuel Ignition uses Ethereum as a Layer 1. We chose Ethereum as Fuel’s L1 for both Settlement and Data availability of the L2, because we think Fuel shares many of Ethereum’s values:

- Building for long-term sustainably

- Building with an emphasis on security

- Focus on consumer hardware and making participation in the protocol accessible  for ordinary people

Ethereum is one of the most decentralized L2s. Ethereum has a long-standing presence and has focused on a rollup-centric roadmap for years. These factors make it the ideal foundation for building a rollup.

![2.5 Fuel and Ethereum](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.5-fuel-and-ethereum-light.png)

## Inheriting Ethereum’s Security

Fuel’s flagship rollup, Ignition, inherits Ethereum’s security. The natural question from the previous statement is, what do we mean by inheriting Ethereum’s security?

Fuel uses Ethereum as the layer to keep users’ funds and propose its latest blocks and corresponding state updates. We deploy smart contracts that continuously get updates of Fuel Layer 2.

Then, we have fraud-proving performed directly on the Ethereum L1 to prove that something about the posted blocks or related state updates is wrong. We also allow permissionless messaging and transaction inclusion via the L1 to ensure the user doesn’t experience any censorship resistance.

This gives the user guarantees that as long as Ethereum is secure and the honest majority assumption for it is held:

- No fraud blocks or state updates can be sent
- Their funds are always safe on the Layer 1
- They can never be stopped from withdrawing them or being able to send any transaction to the L2 (forced inclusion)

Now, we will discuss each of the properties we described above.

## Messaging

Fuel allows for messaging between L1 → L2 and L2 → L1, which means you can send any arbitrary message from Layer 1 to Layer 2 and vice versa. The protocol guarantees that if a message is included in the L1, it has to be processed on the L2 and vice versa. Let’s discuss both of these cases individually.

### L1 → L2 Messaging

The [Fuel Message Portal](https://github.com/FuelLabs/fuel-bridge/blob/main/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol) facilitates message processing from L1 -> L2. Its method, [sendMessage](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L250), accepts the L2 recipient (a Fuel Address) and the corresponding message to be sent. After a successful call to this method, a [MessageSent](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L49) event is emitted on Layer 1.

As discussed in the section on block building, part of processing the Fuel blocks requires committing to some L1 block height, up to which the block builder processes messages and transactions, this forces the Block builder to include all messages from the L1 (as in case of failure, the builder can be slashed).

![2.5 L1 → L2 Messaging](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.5-l1-l2-messaging-light.png)

As part of processing the message blocks from the L1, the block builder looks at the event and mints an OutputMessage transaction to the particular Fuel address with the specific data.

### L2 → L1 Messaging

Fuel also allows messages from the L2 -> L1 to be sent using [MessageOut](https://github.com/FuelLabs/fuel-specs/blob/master/src/abi/receipts.md#messageout-receipt) receipts. Every Fuel block includes a receipt root, the root of all receipts that were part of the block. This allows anyone to make a call to the [relayMessage](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L188) function of the Fuel Message Portal; a Merkle proof of inclusion is required to perform for the message you are trying to process along with that, it checks whether the block for which the message is being processed has been finalized or not (i.e., it outside of the challenge window).

![2.5 L2 → L1 Messaging](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.5-l2-l1-messaging-light.png)

Processing the message on the L1 coming from the L2 is done by calling the specific L1 address to which the message is sent to with some desired payload.

## ETH Deposits and Withdrawals

A core part of using the Fuel rollup is depositing ETH from the L1 to Fuel and withdrawing it from the L2. We will discuss both of these scenarios individually.

### ETH Deposits

The user can call the [depositEth](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L256) function on the L1 to create a deposit. The method is payable, and emits a [messageSent](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L49) event with an empty payload, this makes the sequencer recognize this is a deposit made on the L1 and it mints a new eth coin corresponding to the value of the deposit for the user.

### ETH Withdrawals

Withdrawals on the L2 are made by burning the tokens on the L2 via the [L2 gateway](https://github.com/FuelLabs/fuel-bridge/blob/main/packages/fungible-token/bridge-fungible-token/implementation/src/main.sw#L147). Then, the gateway emits a [MessageOut](https://docs.fuel.network/docs/specs/abi/receipts/#messageout-receipt) receipt, which is part of the block header, allowing the relay of this message to Layer 1.

The Layer 1 [Message Portal](https://github.com/FuelLabs/fuel-bridge/blob/de18552d4a23c6ec1477c6532732dbcdc05a8c16/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol) contract has a [relayMessage](https://github.com/FuelLabs/fuel-bridge/blob/de18552d4a23c6ec1477c6532732dbcdc05a8c16/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L188) function (read [L2 → L1](#l2--l1-messaging) messaging for details); which allows for processing L2 messages aimed for L1, in the case of withdrawals, we send a message with the amount corresponding to the value the user has burned on the L2, and hence the [Message Portal](https://github.com/FuelLabs/fuel-bridge/blob/de18552d4a23c6ec1477c6532732dbcdc05a8c16/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol) contract provides the L1 recipient with their funds for withdrawal.

Note: A withdrawal requires the '[Challenge Window](#challenge-window)' to be cleared before being processed, and hence the user has to wait till the 'Challenge Window' (although there are [fast finality gadgets](http://ethresear.ch/t/why-wait-a-week-fast-finality-optimistic-rollups/18868) which can bring this down.)

## State Updates

Fuel uses Ethereum to submit new state updates. This is done using the [State Contract](https://github.com/FuelLabs/fuel-bridge/blob/main/packages/solidity-contracts/contracts/fuelchain/FuelChainState.sol) on Layer 1, where the blocks are committed by sending the block hash and block height. The contract also records the timestamp as part of the commitment for a particular block.

These state updates and the data posted as Blobs on Ethereum allow for challenging any state updates sent to the L1.

## Challenge Window

The challenge window is the time it takes for a block and related state posted on the L1 to be considered finalized. Finalization means any withdrawal or message part of this block can be processed on the L1. For now, the challenge window for Fuel is seven days.

Techniques like hybrid proving and other fast finality gadgets can reduce the duration of the challenge window; we are actively researching these areas and would encourage you to read [Nick Dodson’s post](http://ethresear.ch/t/why-wait-a-week-fast-finality-optimistic-rollups/18868) on faster finality gadgets for optimistic rollups.

## Hybrid Proving

Fuel believes in a philosophy of [zk-pragmatism](../why-fuel/the-fuel-way.md#zk-pragmatism); rather than playing bisection games on-chain like other rollups (which increase the complexity of the proving system)  or sending zk proofs for every bath like zk rollups (which increase the cost per transaction), Fuel makes a hybrid approach for its proving system.

The system runs in an optimistic setting. If someone in the system believes that a fraud state has been sent, they create a zk-proof off-chain of the claim and prove fraud in a single interaction with the L1. This reduces the proving system's complexity and limits the challenge window.

Hybrid proving is being developed, and prototyping is done with RISC-V-based zkVMs like SP-1 and RISC-0. You can read more about the proving system [here](https://fuel.mirror.xyz/gY0Clw114Ipnel1Bhrey9LCsxX94ly3I9yAfnSWYWTg).

## Appendix

### Alt-DAs and L1s

We have launched our flagship rollup with Eth as our L1 for settlement and data availability, but Fuel believes in creating a neutral and modular tech stack. The Fuel tech stack can be extended to launch on alt L1s like Bitcoin and Solana and with alt DAs like Celestia and Avail. If someone wants, they can even use the Fuel stack to launch their L1.

We will keep progressing our tech stack to be adaptable in multiple scenarios, resilient, and feasible on consumer-grade hardware.

### Blobs

EIP 4844 introduced Blobs as a cheaper way to get Data Availability for Ethereum rollups. Fuel block builders also use blobs, although this is a work in progress.

Fuel blocks are batched together in a bundle, compressed via popular techniques (gzip or zstd), and posted as blobs. Because blobs are fixed in size, uploading has to be done via a series of transactions.

Blobs and their exact implementation are still being finalized and will be live soon, but the above text summarizes the general approach for now.


---

### File: docs/fuel-book/docs/src/the-architecture/fuel-blocks.md

# Fuel Blocks

Highlights:

- In Fuel, blocks are constructed by Block Builders, who process both transactions and messages to create the blocks. Users send transactions either directly to the builder or through layer 1, while messages originate from layer 1. The Fuel and Ethereum section of the book provides further details on this process.

- Each Fuel block begins with a header that consists of three main fields: the Application Header, the Consensus Header, and Block Header Metadata. This structure facilitates efficient management and processing of block-related information.

- The Application Header records critical operational details for the Fuel rollup, comprising four essential components: the da_height, consensus_parameters_version, state_transition_bytecode_version, and generated fields. These components work together to ensure the rollup operates correctly and efficiently.

- The Consensus Header tracks the hash of the Application Header, providing a secure and verifiable method for maintaining consensus within the Fuel network. This header is crucial for ensuring the integrity of the block.

- Fuel blocks also include a Coinbase transaction, which enables block producers to collect fees for their work. This Mint transaction must be the last in the block and is capped at the total fees processed from all transactions within that block, ensuring a fair and controlled fee structure.

Blocks in Fuel are built by entities called Block Builders. Fuel blocks are made by processing transactions and messages. Transactions can be sent directly to the builder or via layer 1, while messages are sent from layer 1. In the Fuel and Ethereum section of the book, we expand further on messages and transactions sent from the L1.

## Block Header

A Fuel block header at the top consists of three fields:

- Application Header
- Consensus Header
- Block Header Metadata

```c++
pub struct BlockHeaderV1 {

    pub application: ApplicationHeader<GeneratedApplicationFields>,

    pub consensus: ConsensusHeader<GeneratedConsensusFields>,

    metadata: Option<BlockHeaderMetadata>,
}
```

### Application Header

The application header records essential information regarding the operation of the Fuel rollup.

The application header at the high level consists of four essential components:

```c++
pub struct ApplicationHeader<Generated> {

    pub da_height: DaBlockHeight,
 
    pub consensus_parameters_version: ConsensusParametersVersion,

    pub state_transition_bytecode_version: StateTransitionBytecodeVersion,

    pub generated: Generated,
}
```

#### da_height

The `da_height` field records the latest block L1 block until the messages sent from the L1 → L2 have been processed; this is helpful later in fraud proving to establish that a particular message was sent from the L1 to the L2 rollup but wasn’t processed as part of the block that included the messages up to the block of which it was part.

#### consensus_parameters_version

The Fuel rollup has a set of upgradeable [consensus parameters](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/#consensus-parameters), which are upgradable via Transactions of type `Upgrade`. For each consensus parameter upgrade, a new version for `consensus_paramters_version` must be assigned, helping us track which set of consensus parameters we are using while building a particular block.

#### state_transition_bytecode_version

The Fuel rollups keep the WASM compiled bytecode of their state transition function as part of the chain facilitating forkless upgrades for the Fuel rollups.

The new state transition function is uploaded via the `Upload` transactions, while the upgrade is done via the `Upgrade` transactions. Each upgrade updates the `state_transition_bytecode_version`, and this version helps keep track of which state transition function is being used to process transactions for a given block.

#### generated

The section contains various rollup-specific fields around execution for a specific block. The Fuel flagship rollup has the following fields for `generated`:

```c++
pub struct GeneratedApplicationFields {
    /// Number of transactions in this block.
    pub transactions_count: u16,
    /// Number of message receipts in this block.
    pub message_receipt_count: u32,
    /// Merkle root of transactions.
    pub transactions_root: Bytes32,
    /// Merkle root of message receipts in this block.
    pub message_outbox_root: Bytes32,
    /// Root hash of all imported events from L1
    pub event_inbox_root: Bytes32,
}
```

### Consensus Header

The consensus header is another top-level field for the Block Header for Fuel rollups, it is configurable and for the flagship Fuel rollup only keeps track of the hash of the Application Header.

```c++
pub struct GeneratedConsensusFields {
    /// Hash of the application header.
    pub application_hash: Bytes32,
}
```

### Block Header Metadata

The Block Header Metadata is used to track metadata. The current flagship Fuel rollup includes a field tracking the block ID, which represents the hash of the block header.

```c++
pub struct BlockHeaderMetadata {
    /// Hash of the header.
    id: BlockId,
}
```

## Coinbase Transaction

Fuel blocks contain a Coinbase transaction; block producers use Coinbase transactions to collect fees for building blocks. The Coinbase transaction is a `Mint` transaction, where the `mintAmount` cannot exceed the fees processed from all transactions in the block. The protocol also requires the Coinbase transaction to always be the last transaction in the block.


---

### File: docs/fuel-book/docs/src/the-architecture/index.md

# Chapter 2 - The Architecture

- [2.1 - The FuelVM](./the-fuelvm.md)
- [2.2 - Transactions on Fuel](./transactions-on-fuel.md)
- [2.3 - Fuel Blocks](./fuel-blocks.md)
- [2.4 - Block Building in Fuel](./block-building-in-fuel.md)
- [2.5 - Fuel and Ethereum](./fuel-and-ethereum.md)
- [2.6 - Security on Fuel](./security-on-fuel.md)
- [2.7 - Fees on Fuel](./fees-on-fuel.md)


---

### File: docs/fuel-book/docs/src/the-architecture/security-on-fuel.md

# Security on Fuel

Highlights:

- Fuel emphasizes security across its rollup ecosystem, particularly through its Security Council, which operates multi-signature wallets to oversee and upgrade various components of the stack. This council plays a critical role in safeguarding the network as Fuel navigates its transition to a fully permissionless system.

- The project recognizes the current centralization of block building and sequencing as a challenge. To address this, Fuel plans a phased approach to decentralize these processes, beginning with a shared sequencer accessible to all block builders before moving towards fully decentralized block building.

- Fuel proactively identifies and mitigates potential security attack vectors, including bugs in bridge contracts, Layer 2 client implementations, and the Sway compiler. By collaborating with diverse teams and engaging top security organizations, Fuel works to establish robust security protocols and multiple implementations to reduce the likelihood of vulnerabilities.

- The platform also tackles application-level bugs by developing secure support libraries in Sway and promoting best practices among developers. This focus on security fosters a more resilient ecosystem for application development.

- Fuel continuously upgrades its protocol to further enhance security, reducing reliance on the Security Council and minimizing risks associated with multi-signature compromise. The project also prioritizes rigorous auditing and testing of fraud-proving implementations to protect against false claims and ensure that legitimate builders receive fair treatment.

This section discusses the current security of Fuel Ignition and rollups.

## Fuel Security Council

Fuel currently has a security council that operates various multi-sigs to upgrade different parts of the stack.

Rollups are in an early stage of development, necessitating a security council to exercise caution before full decentralization. Network issues can be difficult to resolve, making this oversight crucial.

Developing a stack with type-2 security guarantees is a top priority in Fuel's roadmap.

## Block Building

Currently, block building and sequencing are centralized. Decentralizing these processes, especially block building, requires further development and careful consideration. Block building rights give the builder access to extract MEV from the system, which can impact user’s transactions and experience on the network.

Fuel is implementing a phased approach to decentralize block builders and sequencers.

Fuel will start with a decentralized sequencer set, i.e., a shared sequencer that block builders can use for all Fuel rollups. Decentralized block building will follow in the next phase.

## Security Attack Vectors

In this section, we list various attack vectors for the current system and we explore a path forward to tightening security.

### Bridge Contract Bugs

Fuel has a bridge that allows for messaging between L1 and L2; this messaging system creates the base for building a deposit and withdrawal system along with abilities like forced transaction inclusion and calling contracts L2 on L1.

If a bug in the contract implementation on the L1 or L2 compromises the roll-up system, which can include relaying fake messages and transactions from the L1 and L2. A compromise of the mult-sig can also lead to potential malicious upgrades of these contracts.

Fuel undergoes rigorous audits of its smart contracts with the best-in-class security auditors in the space and also participates in bug bounties to keep the possibility of this very low. These issues become more concerning in stage 2 settings, as the stage 1 setting does allow for reverting potential issues regarding bridge contracts.

### Layer 2 Client Bugs

Like any software, the Fuel execution client could have bugs that might be exploited to enable unintended behavior. If there is only one implementation of the execution client, a malicious actor might manipulate the system without being caught by a fraud-proof mechanism, as no alternative client would exist to validate or challenge the state. This risk is particularly relevant in L2 solutions that rely on a single execution client for ZK proving games or fraud-proof verification, making it a potential attack vector.

Fuel attempts to strengthen security around such scenarios by inviting various teams to collaborate on the stack and aiming for multiple implementations, followed by rigorous testing and security audits by the best security organizations in the industry.

### Sway Compiler Bugs

The Sway Language is a dominant language built on the Fuel VM. A bug in the Sway compiler could allow malicious bytecode to be part of a particular predicate, smart contract, or script, which the implementation didn’t desire. A similar issue was seen in the ETH ecosystem with Vyper, which you can follow [here](https://medium.com/rektify-ai/the-vyper-compiler-saga-unraveling-the-reentrancy-bug-that-shook-defi-86ade6c54265).

Fuel aims to avoid such a scenario by having some of the best talent working on its compiler, followed by rigorous testing and audits by leading security organizations in the industry. In the future, we also aim to have multiple implementations of the compiler, which could help discover a bug in the other implementations.

### Application Level Bugs

Application implementations often have bugs because they avoid some required checks or are built on top of libraries with an underlying bug.

Fuel aims to avoid these by creating best-in-class support libraries in Sway, which are well-audited and tested and safe to build on. These Sway libraries also promotes the usage of secure patterns through developer evangelism.

### Multisig Compromisation

If compromised, the security council's multi-sig can lead to severe issues, such as malicious upgrades or behavior in various parts of the stack.

Fuel aims to solve this by having a security council with a very high reputation and a lot of social capital attached to it. At the same time, continuous protocol upgrades minimize the need for the security council and always accelerate towards allowing for a stage 2 rollup stack.

### Fraud Proving Bugs

A bug in the fraud-proving implementation can cause challenges and slash for block builders who built correct blocks or could allow someone to fail to prove a faulty block. This can result in good builders being slashed or wrong states being finalized.

Fuel aims to solve this by initially correcting any such issues with the help of the security council while aiming for multiple implementations of the fraud-proving client or, if possible, multiple-proving system. The implementation is done with best security practices in mind and with regular system audits.


---

### File: docs/fuel-book/docs/src/the-architecture/the-fuelvm.md

# The FuelVM

Highlights:

- The FuelVM serves as the core of the Fuel stack, informed by insights from various virtual machine designs like the EVM and Solana's SVM.

- It supports state-minimized application development through features such as native assets and ephemeral scripting, promoting decentralized and accessible architecture.

- The UTXO model facilitates parallelized transaction execution, enhancing throughput and reducing latency by allowing concurrent processing of non-conflicting transactions.
The FuelVM is a register-based virtual machine, providing better performance compared to traditional stack-based designs and offering a structured instruction set for efficient operations.

- Predicates, scripts, and contracts are essential components of the FuelVM, enabling flexible spending conditions, transaction processing, and state management within its execution environments.

The FuelVM lies at the core of the whole Fuel stack; it was created by taking into account  years of learning from other virtual machine designs, like the EVM, Solana’s SVM and more.

The FuelVM enables developers to move away from stateful application designs often enabled by smart contracts by providing more feature-rich state-minimized facilities such as native assets, ephemeral scripting, and ephemeral spending conditions. By offering alternative methods for developers to build state-minimized applications, we enhance full node sustainability while maintaining a decentralized and accessible architecture, aligning with Ethereum’s core values.

In the following sections, we will discuss the key features of the FuelVM in detail.

## UTXO Model and Parallelization

Fuel’s parallelized transaction execution model serves as a cornerstone for its efficiency and scalability. Parallelization dramatically improves throughput and reduces latency compared to traditional sequential processing methods. It breaks tasks into smaller sub-tasks, executing them simultaneously across multiple processing units.

Parallelization is built upon a foundation of [Access Lists](https://docs.fuel.network/docs/specs/protocol/tx-validity/#access-lists) and the UTXO (Unspent Transaction Output) model, which works in tandem to enable concurrent processing of non-conflicting transactions.

Our tech leverages the UTXO model for performing transactions on Fuel. Transactions modeled through UTXOs handle everything from token transfers to smart contract calls.

Addresses on Fuel own unspent coins, allowing them to spend and perform transactions through the FuelVM.

![2.1 UTXO Model and Parallelization](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-utxo-model-and-parallelization-light.png)

Using the UTXO model helps achieve transaction parallelization. At runtime, users provide the inputs and outputs for their transaction. Transactions without overlap process in parallel, enabling Fuel to scale horizontally with the number of cores per machine.

## Register based design

The FuelVM operates as a register-based virtual machine, unlike the EVM and many others, which use a stack-based architecture.

Register-based virtual machines consistently outperform stack-based virtual machines.

The FuelVM includes 64 registers, each 8 bytes, with 16 reserved and 6-bit addressable.

| value | register |         name        |                                    description                                   |
|:-----:|:--------:|:-------------------:|:--------------------------------------------------------------------------------:|
| 0x00  | $zero    | zero                | Contains zero (0), for convenience.                                              |
| 0x01  | $one     | one                 | Contains one (1), for convenience.                                               |
| 0x02  | $of      | overflow            | Contains overflow/underflow of addition, subtraction, and multiplication.        |
| 0x03  | $pc      | program counter     | The program counter. Memory address of the current instruction.                  |
| 0x04  | $ssp     | stack start pointer | Memory address of bottom of current writable stack area.                         |
| 0x05  | $sp      | stack pointer       | Memory address on top of current writable stack area (points to free memory).    |
| 0x06  | $fp      | frame pointer       | Memory address of beginning of current call frame.                               |
| 0x07  | $hp      | heap pointer        | Memory address below the current bottom of the heap (points to used/OOB memory). |
| 0x08  | $err     | error               | Error codes for particular operations.                                           |
| 0x09  | $ggas    | global gas          | Remaining gas globally.                                                          |
| 0x0A  | $cgas    | context gas         | Remaining gas in the context.                                                    |
| 0x0B  | $bal     | balance             | Received balance for this context.                                               |
| 0x0C  | $is      | instructions start  | Pointer to the start of the currently-executing code.                            |
| 0x0D  | $ret     | return value        | Return value or pointer.                                                         |
| 0x0E  | $retl    | return length       | Return value length in bytes.                                                    |
| 0x0F  | $flag    | flags               | Flags register.                                                                  |

## The FuelVM Instruction Set

The FuelVM instructions are 4 bytes wide and have the following structure:

- Opcode: 8 bits
- Register Identifier: 6 bits
- Immediate value: 12, 18, or 24 bits, depending on the operation.

The FuelVM instruction set has been documented in detail here: <https://docs.fuel.network/docs/specs/fuel-vm/instruction-set>.

## Memory

FuelVM uses byte-indexed memory, configurable with the VM_MAX_RAM parameter. Hence, each instance of FuelVM can decide how much memory it wants to allocate for the VM.

Memory follows a stack and heap model. The stack begins from the left, immediately after the initialized VM data and call frame in a call context, while the heap starts at the byte indexed by VM_MAX_RAM.

Each byte allocation on the Stack increases the stack index by 1, and each byte allocation on the heap decreases its writable index by 1. Hence, the stack grows upwards, and the heap grows downwards.

![2.1 FuelVM Memory](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-memory-light.png)

The stack and the heap have the following essential registers associated with them:

- `$ssp` ( 0x05 ): Memory address of bottom of the current writable stack area.
- `$sp` ( 0x06 ): Memory address on top of current writable stack area (points to free memory).
- `$hp` ( 0x07 ): Memory address below the current bottom of the heap (points to used/OOB memory).

The FuelVM has ownership checks to ensure that contexts have a defined sense of ownership over particular regions in the memory and can only access memory from the region they own. We will elaborate more on this topic in later sections.

## Predicates, Scripts and Contracts

Understanding further concepts for Fuel requires grasping:

- Predicates
- Scripts
- Contracts

Let’s dive deeper.

### Predicates

Predicates are stateless programs that define spending conditions for native assets. Native assets go to predicates, and to determine whether they are spendable in a transaction, the FuelVM executes the bytecode and checks the boolean return value. If the returned value is true, the asset can be spent; if the returned value is false, then the transaction is invalid!

People can program various spending conditions, such as spending only if three out of five approve a transaction or if a transaction includes specific desired inputs and outputs, commonly known as intents.

Predicates operate statelessly, without persistent storage, and cannot call other smart contracts.

### Scripts

Scripts serve as the entry point for Fuel transactions, dictating the flow of the transaction. Like predicates, they lack persistent storage. However, they can call contract Inputs, which are part of the Fuel transaction and can have persistent storage of their own.

This enables Fuel to natively support advanced features such as multi-calls, conditional contract execution, and more.

### Contracts

Fuel provides support for smart contracts in its UTXO model. Smart contracts are stateful and can be called by other contracts. In Fuel, smart contracts are represented by the `InputContract` type. To learn more, refer to the section on InputContract.

The first call to a contract in a transaction occurs through a script, after which the contract can call other contracts.

Contracts have persistent storage, a key-value pair of 32-byte and 32-byte values. Various data structures are being considered to determine the optimal approach for committing to contract storage.

## Contexts

A context is a way to isolate the execution of various execution environments for predicate estimation and verification, scripts, and contracts. Each context has its memory ownership, which we will expand on later.

There are four types of contexts in Fuel:

- Predicate Estimation
- Predicate Verification
- Script Execution
- Calls

The first three are called External contexts, as the `$fp` is zero, while Calls are called Internal contexts and will have a non-zero value for `$fp`.

### Predicate Estimation

Fuel transactions provide `predicateGasUsed` for each predicate used. During verification, if predicateGasUsed is less than the total gas consumed during verification, the transaction reverts.

![2.1 Predicate Estimation](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-predicate-estimation-light.png)

The user performs Predictive Estimation locally or by calling a remote full node, which executes the predicate in the FuelVM and returns the total gas consumed.

Predicate estimation context cannot do persistent storage or make calls to Contracts.

### Predicate Verification

All predicate parts of the transaction are verified to return true before executing the transaction script. The FuelVM is used in the Predicate Verification context when verifying a transaction's predicates.

![2.1 Predicate Verification](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-predicate-verification-light.png)

Predicate verification context cannot do persistent storage or make calls to contracts.

### Script Execution

After verifying all predicates, the transaction script is executed; the script execution context cannot do persistent storage but can make calls to contract.

![2.1 Script Execution](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-script-execution-light.png)

### Calls

Call contexts execute contracts, offering flexibility, storing data persistently, and making contract calls.

Call context is created by either:

1. Script calling a smart contract
2. Contract calling a contract input

![2.1 Call Context](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-call-context-light.png)

Each call creates a “Call Frame”, which is pushed to the Stack. A call frame holds metadata on the stack, aiding the execution of the call context in the FuelVM. A call context cannot mutate the caller's state and only access its stack and heap.

<!-- markdownlint-disable MD052 -->
|          bytes          |     type    |   value  |                                  description                                  |
|:-----------------------:|:-----------:|:--------:|:-----------------------------------------------------------------------------:|
| Unwritable area begins. |             |          |                                                                               |
| 32                      | byte[32]    | to       | Contract ID for this call.                                                    |
| 32                      | byte[32]    | asset_id | asset ID of forwarded coins.                                                  |
| 8*64                    | byte[8][64] | regs     | Saved registers from previous context.                                        |
| 8                       | uint64      | codesize | Code size in bytes, padded to the next word boundary.                         |
| 8                       | byte[8]     | param1   | First parameter.                                                              |
| 8                       | byte[8]     | param2   | Second parameter.                                                             |
| 1*                      | byte[]      | code     | Zero-padded to 8-byte alignment, but individual instructions are not aligned. |
|  Unwritable area ends.  |             |          |                                                                               |
| *                       |             |          | Call frame's stack.                                                           |
<!-- markdownlint-enable MD052 -->

After a call context has successfully ended, its call frame is popped from the stack. However, any space allocated on the heap during the execution of the call context persists in memory.

A call context returns its value using the `$ret` and `$retl` registers. Large return values can be written to the heap and later read from the caller contexts.

## Memory Policies

After understanding the various contexts for executing the FuelVM, we now discuss the policies for reading and writing to memory in contexts.

### Read Policies for Context

A context can read any data from the stack in the range from the byte at index `0` (i.e., from the start of the memory ) to the highest ever `$sp` and between the current `$hp` and `VM_MAX_RAM` (i.e., until the end of the memory ) of the previous context that created the current context.

Any attempt to read from the region between the highest ever `$sp` during the context execution and the current `$hp` will return an error.

![2.1 Memory Read Policies](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-memory-read-policies-light.png)

What do we mean by the highest ever `$sp`?

Since the stack can be grown and shrunk in size, it is possible that during the execution of some context, the `$sp` went until, for example, index 1000, but then elements were popped out of the stack, and now the current `$sp` is 900. In this scenario, the highest ever `$sp` during the execution of this call context is 1000, and hence, the memory region until 1000 is readable for the stack!

### Write Policies for Context

A given context can write to any region between its `$ssp` and current `$hp`; hence, that memory region can be allocated and used for writing data.

Before writing to this memory region, allocate the bytes first. In the case of a stack, this is done using `CFE` and `CFEI` opcodes, while in the case of the heap, it is done via `an ALOC` opcode.

![2.1 Memory Write Policies](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-memory-write-policies-light.png)

Note: Remember that once a context completes, all values on the stack (i.e., the call frame and all values allocated on the stack during execution ) are wiped down. Still, heap allocation stays, and the following context can only write data below the `$hp` of the existing context.

## VM Initialization & Configuration

### Configuration

The VM can be configured by setting the following parameters:

|          name         |  type  | value |                   note                  |
|:---------------------:|:------:|:-----:|:---------------------------------------:|
| CONTRACT_MAX_SIZE     | uint64 |       | Maximum contract size, in bytes.        |
| VM_MAX_RAM            | uint64 | 2**26 | 64 MiB.                                 |
| MESSAGE_MAX_DATA_SIZE | uint64 |       | Maximum size of message data, in bytes. |

### VM Initialization

This section outlines the process during VM initialization for every VM run.
To initialize the VM, the following pushes to the stack sequentially:

1. Transaction hash (byte[32], word-aligned), computed as defined [here](https://docs.fuel.network/docs/specs/identifiers/transaction-id/).

2. Base asset ID (byte[32], word-aligned)

3. [MAX_INPUTS](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/) pairs of (asset_id: byte[32], balance: uint64), of:

    1. For [predicate estimation](https://docs.fuel.network/docs/specs/fuel-vm/#predicate-estimation) and [predicate verification](https://docs.fuel.network/docs/specs/fuel-vm/#predicate-verification), zeroes.

    2. For [script execution](https://docs.fuel.network/docs/specs/fuel-vm/#script-execution), the free balance for each asset ID seen in the transaction's inputs is ordered in ascending order. If there are fewer than MAX_INPUTS asset IDs, the pair has a zero value.

4. Transaction length, in bytes (uint64, word-aligned).

5. The [transaction, serialized](https://docs.fuel.network/docs/specs/tx-format/).

The following registers are then initialized (without explicit initialization, all registers are initialized to zero):

1. `$ssp = 32 + 32 + MAX_INPUTS*(32+8) + size(tx))`: the writable stack area starts immediately after the serialized transaction in memory (see above).

2. `$sp = $ssp:` writable stack area is empty to start.

3. `$hp = VM_MAX_RAM:` the heap area begins at the top and is empty to start.

## Further Readings

- Nick Dodson’s tweet on what makes FuelVM unique: https://x.com/IAmNickDodson/status/1542516357886988288
- Blockchain Capital’s blog on FuelVM and Sway: https://medium.com/blockchain-capital-blog/exploring-the-fuelvm-86cf9ccdc159
- UTXO Model by River.com: https://river.com/learn/bitcoins-utxo-model/


---

### File: docs/fuel-book/docs/src/the-architecture/transactions-on-fuel.md

# Transactions on Fuel

Highlights:

- Fuel utilizes the UTXO model for transactions, a method famously employed in the Bitcoin protocol. This method allows for advantages like parallel transaction execution. In this model, addresses can own native assets and spend these coins through transactions.

- There are five distinct categories of transactions in Fuel, classified based on their operations: Script, Create, Mint, Upgrade, and Upload. Categorization helps define the various functionalities that users can perform within the Fuel ecosystem.

- Fuel transactions are composed of several key components: Inputs, Scripts, Outputs, and Witnesses. Inputs consist of state elements that users access during the transaction and can include Coins, Contracts, and Messages.

- The structure of a Fuel transaction allows for the inclusion of smart contracts as inputs, which can maintain persistent storage and can be utilized to execute complex operations beyond simple transactions, unlike the limitations faced by the Bitcoin protocol.

- Witnesses play a crucial role in Fuel transactions by providing digital signatures and verification for spending coins. Block builders fill in these fields and exclude them from the transaction ID, allowing for flexible data handling in transaction processing.

Fuel uses the UTXO model for transactions on its blockchain. The model is popularly used in the Bitcoin protocol and has various advantages, including parallel transaction execution.

In Fuel, addresses can own native assets and spend coins with transactions. Fuel categorizes transactions into five types based on their blockchain operations:

1. Script
2. Create
3. Mint
4. Upgrade
5. Upload

![2.2 Transaction Types](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-types-light.png)

Fuel uses the UTXO model for transactions, introducing specific constructs we'll explore before examining the various transaction types:

- Inputs
- Script
- Outputs
- Witnesses

We'll explore Fuel transaction components in detail before examining individual transaction types.

## Inputs

Fuel transactions use three types of Inputs, which are state elements accessed by users:

1. Coins
2. Contracts
3. Messages

### Coins

Coins are units for some asset that a user can spend as part of the transaction. Fuel natively supports multiple assets, unlike chains that only support one base asset (such as ETH for Ethereum). Asset creation is built into Fuel's protocol. For more details, see the native assets section in the appendix.

Users can own various denominations of certain assets in different numbers of Coins. For example, a Fuel address A can have a balance of some asset 100, with four coins of 25 denominations each, and some address B can have a balance of 100 for the same asset, but three coins of denomination 10, 40, 50.

![2.2 Input Coins](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-input-coins-light.png)

An Input Coin has the following parameters attached:

|         name        |    type   |                     description                     |
|:-------------------:|:---------:|:---------------------------------------------------:|
| txID                | byte[32]  | Hash of transaction.                                |
| outputIndex         | uint16    | Index of transaction output.                        |
| owner               | byte[32]  | Owning address or predicate root.                   |
| amount              | uint64    | Amount of coins.                                    |
| asset_id            | byte[32]  | Asset ID of the coins.                              |
| txPointer           | TXPointer | Points to the TX whose output is being spent.       |
| witnessIndex        | uint16    | Index of witness that authorizes spending the coin. |
| predicateGasUsed    | uint64    | Gas used by predicate.                              |
| predicateLength     | uint64    | Length of predicate, in instructions.               |
| predicateDataLength | uint64    | Length of predicate input data, in bytes.           |
| predicate           | byte[]    | Predicate bytecode.                                 |
| predicateData       | byte[]    | Predicate input data (parameters).                  |

The transaction invalidity rules for this input type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/input/#inputcoin).

### Contracts

A common question about the UTXO model concerns implementing smart contracts beyond ephemeral scripts.

Bitcoin's limited support for complex smart contracts stems from several core issues:

- Bitcoin script is not Turing complete, meaning you cannot do things like loops inside Bitcoin

- Bitcoin scripts in transactions lack persistent storage, limiting the blockchain's functionality.

Many incorrectly attribute Bitcoin's limitations to its UTXO model. However, these constraints stem from deliberate design choices. At Fuel, we embrace the UTXO model while supporting full Turing-complete smart contracts with persistent storage. We solve this problem by making stateful smart contracts an input for Fuel transactions.

Contracts have persistent storage and can own native assets. Users consume contracts by using the contracts as input for transactions. Then, users can call various external functions attached to contracts via the ephemeral script attached to the transaction.

![2.2 Input Contracts](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-input-contracts-light.png)

| name        | type      | description                                                             |
|-------------|-----------|-------------------------------------------------------------------------|
| txID        |  byte[32] | Hash of transaction.                                                    |
| outputIndex | uint16    | Index of transaction output.                                            |
| balanceRoot | byte[32]  | Root of amount of coins owned by contract before transaction execution. |
| stateRoot   | byte[32]  | State root of contract before transaction execution.                    |
| txPointer   | TXPointer | Points to the TX whose output is being spent.                           |
| contractID  | byte[32]  | Contract ID.                                                            |

When signing over contracts, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are initialized to zero values, which the block builder later fills in. This helps avoid concurrency issues with Contracts, as previously seen in the Cardano model.

When interacting with an AMM contract on Fuel, the process follows a specific flow. You begin by including the contract as an input to your transaction. Next, you call the external methods within an ephemeral script. Finally, you emit the contract as an output. This emitted contract can then be consumed as an input for the subsequent transaction involving this particular AMM contract. This approach allows for efficient state management and seamless interaction with the AMM on the Fuel platform.

The transaction invalidity rules for this input type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/input/#inputcontract).

### Messages

The Block Builder creates messages created as part of sending messages from the L1 to the L2. Messages make deposits to the Fuel rollups from the L1 possible, and we will discuss them in better detail later in the Fuel & Ethereum section.

**NOTE:** An Input Message can only be consumed as an Input as part of a transaction, and is then destroyed from the UTXO set.

![2.2 Input Messages](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-input-messages-light.png)

A fuel InputMessage consists of the following parameters:

|         name        |   type   |                       description                       |
|:-------------------:|:--------:|:-------------------------------------------------------:|
| sender              | byte[32] | The address of the message sender.                      |
| recipient           | byte[32] | The address or predicate root of the message recipient. |
| amount              | uint64   | Amount of base asset coins sent with message.           |
| nonce               | byte[32] | The message nonce.                                      |
| witnessIndex        | uint16   | Index of witness that authorizes spending the coin.     |
| predicateGasUsed    | uint64   | Gas used by predicate execution.                        |
| dataLength          | uint64   | Length of message data, in bytes.                       |
| predicateLength     | uint64   | Length of predicate, in instructions.                   |
| predicateDataLength | uint64   | Length of predicate input data, in bytes.               |
| data                | byte[]   | The message data.                                       |
| predicate           | byte[]   | Predicate bytecode.                                     |
| predicateData       | byte[]   | Predicate input data (parameters).                      |

The transaction invalidity rules for this input type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/input/#inputmessage).

## Scripts

Fuel scripts are ephemeral scripts that express the various actions taken during a transaction; a script can call the contracts provided as inputs or perform other arbitrary computation.

Fuel implements multi-call functionality through scripts, enabling efficient batch transactions. This approach allows users to:

1. Provide up to [MAX_INPUTS](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/) contracts in a single transaction

2. Call external methods on these multiple contracts

As mentioned in the FuelVM section, the FuelVM is in the Script Context, scripts cannot have their own persistent storage.

## Outputs

Fuel transactions have Outputs, which define the creation of new UTXOs post-transaction; these Outputs can then be inputs for the next set of transactions.

There are five types of possible Output types in a Fuel transaction:

1. Coin
2. Contract
3. Change
4. Variable
5. ContractCreated

One thing to note is we have three Outputs dealing with Coins, and the table below summarizes the core differences (we will expand more in further sections):

|         | OutputCoin | OutputChange      | OutputVariable         |
|---------|------------|-------------------|------------------------|
| Amount  | Static     | Automatically set | Set by script/contract |
| AssetID | Static     | Static            | Set by script/contract |
| To      | Static     | Static            | Set by script/contract |

**NOTE:** A Coin Output (Coin, Change, Variable) with an amount of zero leads to the pruning of the output from the UTXO set, which means coin outputs of amount zero are not part of the UTXO set.

### OutputCoin

Output Coins are new coins sent to a Fuel Address, which become spendable as Input Coins in further transactions.

|   name   |   type   |              description             |
|:--------:|:--------:|:------------------------------------:|
| to       | byte[32] | Receiving address or predicate root. |
| amount   | uint64   | Amount of coins to send.             |
| asset_id | byte[32] | Asset ID of coins.                   |

![2.2 Output Coins](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-coin-light.png)

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputcoin).

### OutputContract

OutputContracts are newly generated contract outputs that become available as InputContracts for a specific contract ID in subsequent transactions utilizing this contract as an Input. They contain the newly updated index, balanceRoot, and stateRoot of the contract after being processed as part of the transaction.

**NOTE:** Every InputContract part of the transaction must always have a corresponding Output Contract.

![2.2 Output Contract](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-contract-light.png)

|     name    |   type   |                               description                              |
|:-----------:|:--------:|:----------------------------------------------------------------------:|
| inputIndex  | uint16   | Index of input contract.                                               |
| balanceRoot | byte[32] | Root of amount of coins owned by contract after transaction execution. |
| stateRoot   | byte[32] | State root of contract after transaction execution.                    |

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputcontract).

### OutputChange

An OutputChange, included as one of our outputs for a specific assetId, enables the recovery of any unused balance from the total input balance provided in the transaction for that assetId.

For example, an OutputChange can collect any ETH not spent as gas or any USDC not swapped as part of a DEX transaction.

![2.2 Output Change](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-change-light.png)

**NOTE:** There can only be one OutputChange per `asset_id in a transaction`.

|   name   |   type   |              description             |
|:--------:|:--------:|:------------------------------------:|
| to       | byte[32] | Receiving address or predicate root. |
| amount   | uint64   | Amount of coins to send.             |
| asset_id | byte[32] | Asset ID of coins.                   |

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputchange).

### OutputVariable

OutputVariable acts as a placeholder for coins created in the execution of scripts and contracts since they can create a coin of an arbitrary amount and to an arbitrary user. This is useful in scenarios where the exact output amount and owner cannot be determined beforehand.

**NOTE:** This means every transaction using mint internally will need an OutputVariable for that particular assetID.

![2.2 Output Variable](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-variable-light.png)

Consider a scenario where a contract transfers its output coin to a user only upon receiving a correct value. In this case, we can utilize a variable output at the end of the transaction. This output may or may not have a value attached to it, depending on whether the condition is met and have an arbitrary owner.

Variable Outputs are used via the [TRO](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/#tro-transfer-coins-to-output) opcode.

|   name   |   type   |              description             |
|:--------:|:--------:|:------------------------------------:|
| to       | byte[32] | Receiving address or predicate root. |
| amount   | uint64   | Amount of coins to send.             |
| asset_id | byte[32] | Asset ID of coins.                   |

The transaction invalidity rules for this output type are available [in our documentation](https://docs.fuel.network/docs/specs/tx-format/output/#outputvariable).

### OutputContractCreated

The `OutputContractCreated` output indicates that a new contract was created as part of the transaction. The parameters include the `contractID` and the initial state root for this contract.

|    name    |   type   |           description           |
|:----------:|:--------:|:-------------------------------:|
| contractID | byte[32] | Contract ID.                    |
| stateRoot  | byte[32] | Initial state root of contract. |

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputcontractcreated).

## Witness

The witness is a parameter attached to transactions. The block builders fill in witnesses and are not part of the transaction ID. A Witness is usually used to provide digital signatures for verification purposes, for example, the signature to prove the spending of a Coin or anything else.

Witnesses are not part of the transaction ID, which allows someone to sign over a transaction and provide it as part of the transaction.

**NOTE:** The protocol doesn't limit witnesses to providing signatures only; they serve to fill in any data and enable various interesting use cases, like [State Rehydration](../fuels-future/state-rehydration.md).

Each witness contains a byte array data along with the field dataLength helping know the length of this data.

|    name    |   type   |            description            |
|:----------:|:--------:|:---------------------------------:|
| dataLength | uint64   | Length of witness data, in bytes. |
| data       | byte[]   | Witness data.                     |
| asset_id   | byte[32] | Asset ID of coins.                |

Multiple witnesses can be provided as part of the transaction, and the inputs can indicate which witness block builders, contracts, scripts or predicates can look at to verify the validity of being able to spend the input by providing the index at which their witness lives.

## TransactionScript

Script transactions are transactions that, as the name suggests, have Inputs, Outputs, and a Script that dictates what happens as part of the transaction.

Note: Scripts are optional in transactions of type `TransactionScript`. For example, a simple token transfer can work only on inputs and outputs, with no requirement for a script. Scripts are mainly leveraged when you want to do other things as part of your transaction beyond simply transferring or burning assets.

The transaction's script can compute arbitrary amounts and call other contracts. A famous example of script transactions is using an AMM or transferring a token.

|       name       |    type    |               description               |
|:----------------:|:----------:|:---------------------------------------:|
| scriptGasLimit   | uint64     | Gas limits the script execution.        |
| receiptsRoot     | byte[32]   | Merkle root of receipts.                |
| scriptLength     | uint64     | Script length, in instructions.         |
| scriptDataLength | uint64     | Length of script input data, in bytes.  |
| policyTypes      | uint32     | Bitfield of used policy types.          |
| inputsCount      | uint16     | Number of inputs.                       |
| outputsCount     | uint16     | Number of outputs.                      |
| witnessesCount   | uint16     | Number of witnesses.                    |
| script           | byte[]     | Script to execute.                      |
| scriptData       | byte[]     | Script input data (parameters).         |
| policies         | Policy []  | List of policies, sorted by PolicyType. |
| inputs           | Input []   | List of inputs.                         |
| outputs          | Output []  | List of outputs.                        |
| witnesses        | Witness [] | List of witnesses.                      |

**NOTE:** Script transactions lack the ability to create contracts, therefore they cannot produce a ContractCreated output type. For additional transaction invalidity rules, refer to [our documentation](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionscript).

## TransactionCreate

TransactionCreate is used to create new contracts; the parameters allow for contracts with initialized storage slots.

The contract ID of smart contracts on Fuel is calculated deterministically, and the calculation mechanism is referred to [here](https://docs.fuel.network/docs/specs/identifiers/contract-id/).

![2.2 Transaction Create](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-create-light.png)

|         name         |          type          |                    description                    |
|:--------------------:|:----------------------:|:-------------------------------------------------:|
| bytecodeWitnessIndex | uint16                 | Witness index of contract bytecode to create.     |
| salt                 | byte[32]               | Salt.                                             |
| storageSlotsCount    | uint64                 | Number of storage slots to initialize.            |
| policyTypes          | uint32                 | Bitfield of used policy types.                    |
| inputsCount          | uint16                 | Number of inputs.                                 |
| outputsCount         | uint16                 | Number of outputs.                                |
| witnessesCount       | uint16                 | Number of witnesses.                              |
| storageSlots         | (byte[32], byte[32])[] | List of storage slots to initialize (key, value). |
| policies             | Policy []              | List of policies.                                 |
| inputs               | Input []               | List of inputs.                                   |
| outputs              | Output []              | List of outputs.                                  |
| witnesses            | Witness []             | List of witnesses.                                |

The transaction invalidity rules for this transaction type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionscript).

## TransactionMint

The block producer uses this transaction to mint new assets. It doesn’t require a signature. The transaction is currently used to create the block producer's fees. The last transaction in the blocks is a Coinbase transaction, allowing the block producer to collect fees for building the block.

![2.2 Transaction Mint](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-mint-light.png)

|      name      |      type      |                                 description                                |
|:--------------:|:--------------:|:--------------------------------------------------------------------------:|
| txPointer      | TXPointer      | The location of the Mint transaction in the block.                         |
| inputContract  | InputContract  | The contract UTXO that assets are minted to.                               |
| outputContract | OutputContract | The contract UTXO that assets are being minted to.                         |
| mintAmount     | uint64         | The amount of funds minted.                                                |
| mintAssetId    | byte[32]       | The asset IDs corresponding to the minted amount.                          |
| gasPrice       | uint64         | The gas price to be used in calculating all fees for transactions on block |

The transaction invalidity rules for this transaction type can be seen here.

## TransactionUpgrade

The Fuel network employs [consensus parameters](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/), subject to occasional upgrades. The network's state transition function resides on-chain, allowing privileged addresses to upgrade it when necessary.

Therefore, at any given moment, a TransactionUpgrade might attempt to perform one of the following actions:

- Trying to upgrade the consensus parameters

- Trying to upgrade the state transition function

![2.2 Transaction Upgrade](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-upgrade-light.png)

|      name      |      type      |           description          |
|:--------------:|:--------------:|:------------------------------:|
| upgradePurpose | UpgradePurpose | The purpose of the upgrade.    |
| policyTypes    | uint32         | Bitfield of used policy types. |
| inputsCount    | uint16         | Number of inputs.              |
| outputsCount   | uint16         | Number of outputs.             |
| witnessesCount | uint16         | Number of witnesses.           |
| policies       | Policy []      | List of policies.              |
| inputs         | Input []       | List of inputs.                |
| outputs        | Output []      | List of outputs.               |
| witnesses      | Witness []     | List of witnesses.             |

The transaction invalidity rules for this transaction type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionmint).

## TransactionUpload

Before performing an upgrade, operators must upload the Fuel state transition bytecode to the chain. This requires uploading the bytecode via multiple transactions. TransactionUpload allows us to split the bytecode into multiple subsections and upload each subsection sequentially over multiple transactions.

On successful upload of all subsections, the transaction reaches completion, and the system adopts the new bytecode.

![2.2 Transaction Upload](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-upload-light.png)

<!-- markdownlint-disable MD052 -->
|        name       |    type    |                                      description                                      |
|:-----------------:|:----------:|:-------------------------------------------------------------------------------------:|
| root              | byte[32]   | The root of the Merkle tree is created over the bytecode.                             |
| witnessIndex      | uint16     | The witness index of the subsection of the bytecode.                                  |
| subsectionIndex   | uint16     | The index of the subsection of the bytecode.                                          |
| subsectionsNumber | uint16     | The total number of subsections on which bytecode was divided.                        |
| proofSetCount     | uint16     | Number of Merkle nodes in the proof.                                                  |
| policyTypes       | uint32     | Bitfield of used policy types.                                                        |
| inputsCount       | uint16     | Number of inputs.                                                                     |
| outputsCount      | uint16     | Number of outputs.                                                                    |
| witnessesCount    | uint16     | Number of witnesses.                                                                  |
| proofSet          | byte[32][] | The proof set of Merkle nodes to verify the connection of the subsection to the root. |
| policies          | Policy []  | List of policies.                                                                     |
| inputs            | Input []   | List of inputs.                                                                       |
| outputs           | Output []  | List of outputs.                                                                      |
| witnesses         | Witness [] | List of witnesses.                                                                    |
<!-- markdownlint-enable MD052 -->

The transaction invalidity rules for this transaction type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionupload).

## Appendix

### Native Assets

In Fuel, apart from Eth (which is called the base asset), the functionality of minting and burning assets is enshrined in the protocol. The FuelVM provides op-codes for creating, minting, and burning assets, [MINT](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/#mint-mint-new-coins) and [BURN](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/#burn-burn-existing-coins), respectively.

All native assets can be spent using the same rules as the base asset, allowing Fuel developers and users to fully utilize the UTXO model and the resulting parallelization.

To explore Native assets further, it is recommended that you look at [Sway Standards](https://docs.fuel.network/docs/sway-standards/), which provide various standards ( like SRC-3, SRC-20, and many more ) related to native assets.


---

### File: docs/fuel-book/docs/src/why-fuel/beginnings.md

# Beginnings

A multitude of fragmented solutions—Layer 1s, rollups, DA layers, sequencers—clutter the blockchain landscape today, each striving to scale, decentralize, and power the internet's future. However, execution inefficiencies, unsustainable growth, and security compromises hamper the current array of solutions.

In the race to market, numerous solutions opted to copy and paste existing architectures. Few dared to build from the ground up. Why? Most projects focused on sustaining innovations, making incremental improvements to older frameworks. We took the opposite approach and aimed for disruptive innovation, challenging the status quo with a completely new architectural vision to overcome the limitations others had accepted.

Picture a group of early Ethereum developers, driven by a vision to enhance the performance, sustainability, interoperability, and developer experience of Ethereum. Recognizing the need for a fresh architectural approach to achieve ambitious goals, these devs envisioned a system incorporating years of blockchain evolution while adhering to cypherpunk ideals of decentralization and accessibility.

The blockchain ecosystem has undergone a remarkable transformation since the inception of Bitcoin in 2009. Bitcoin and Ethereum, as pioneering Layer 1 blockchains, established the foundation for decentralized systems, but quickly encountered scalability challenges. In response, alternative L1s offered differing approaches to decentralization, security, and performance. As demand for scalability grew, Ethereum explored modular approaches and various solutions like state channels, plasma, and eventually rollups—Layer 2 solutions that aggregate transactions to improve throughput while leveraging the security of L1s.

Sequencers, integral to rollups, emerged to manage transaction ordering and boost efficiency, forming a critical piece in the evolving blockchain landscape. This wave of innovation also sparked developments in Proposer-Builder Separation (PBS) and other modular solutions that allowed for specialization at various layers of the blockchain stack—execution, settlement, data availability, and consensus—pushing the boundaries of what these networks could achieve.

Despite such advancements, the blockchain landscape still lacks a crucial piece of the puzzle: scalability without compromise. Most solutions sacrifice decentralization for performance, or security for speed, resulting in trade-offs that undermine the core principles of blockchain technology.

Many L1 and L2 solutions boost transaction capacity by increasing node requirements, thus enhancing throughput and cutting latency. This approach, however, shrinks the pool of participants capable of validating and securing the chain.

Similarly, some rollups and sidechains achieve higher speeds by implementing trust assumptions that deviate from the foundational principles of security and decentralization. These solutions may rely on multi-signature schemes or other trust-based models to validate transactions, which introduce vulnerabilities. Users must place their trust in small groups of signers, which can be susceptible to hacking or coordination attacks.

This critical need for a scalable, trustless, and performant system—one that doesn’t trade off on the core principles of blockchain—remains unmet.

We built Fuel to address this critical gap.

In December 2020, Fuel emerged as the first optimistic rollup on Ethereum, with the launch of Fuel V1. We sought to create a trust-minimized sidechain that would inherit the security of Ethereum while introducing a radically redesigned execution model based on UTXOs, or Unspent Transaction Outputs.

Fuel V1 garnered significant attention within the blockchain community from day one. Many regarded Fuel V1 as the one “pure” rollup, primarily due to its approach to security and execution. Unlike other architectures, Fuel V1 demonstrated security inheritance without relying on third-party multi-signatures or sacrificing the integrity of optimistic fraud proofs.

[Vitalik's appreciation for Fuel.](https://x.com/vitalikbuterin/status/1838862177824051712?s=46&t=fyJoiPJn7gE_VIRS05WBaQ)

Fuel V1’s design philosophy set the bar for Ethereum rollups and ultimately, our vision, leading to a more refined architecture in Fuel V2.

Over the past three and a half years, Fuel has evolved significantly, morphing into a new blockchain architecture that thoughtfully addresses the common challenges faced by modern blockchains. Our vision culminated in what we now call Fuel V2, an operating system for rollups—the "Rollup OS." This framework empowers developers to build and customize their own rollups while leveraging the security and robustness of underlying L1s like Ethereum for settlement and access to Ethereum’s vast liquidity and assets.

Imagine Fuel as a robust framework designed to foster the development of sustainable and high-performance rollups, along with novel, advanced applications never before seen in blockchain. By providing this architecture, we empower developers to build innovative, decentralized solutions that push the boundaries of what's possible in the ecosystem.

We envision every application eventually evolving into its own app-chain, with Fuel providing the optimal architecture, tools, and developer experience for that future. Our commitment extends to creating pathways for the community to support millions of innovative app-chains, establishing Fuel as the foundation for the next generation of decentralized applications.

Fuel's narrative interweaves with Bitcoin and Ethereum's histories. Bitcoin's concise yet revolutionary whitepaper sparked a philosophical movement centered on self-sovereignty and cryptographic trust. Ethereum then expanded the horizon, introducing a programmable platform that unleashed developers' creativity and innovation.

Fuel acknowledges these contributions while seeking to fill the gaps left by conventional architectures. As we delve deeper into the intricacies of blockchain technology, we invite you to explore the problems we aim to solve and the vision we aspire to realize. Welcome to the beginnings of Fuel—a journey toward a sustainable, performant, and decentralized future.


---

### File: docs/fuel-book/docs/src/why-fuel/building-on-fuel-an-overview.md

# Building on Fuel: An Overview

Building on Fuel empowers developers to create high-performance, scalable decentralized applications with cutting-edge tools and infrastructure. Fuel’s architecture prioritizes speed, security, and developer productivity. This section outlines the core components of the Fuel ecosystem. We will explore each component in further detail in [Part 2](../the-architecture/index.md).

## The FuelVM (Fuel Virtual Machine)

The FuelVM incorporates years of blockchain design to bring the Ethereum community a reliable machine architecture built for longevity. It drives the Fuel Network and delivers exceptional performance by processing transactions in parallel. Unlike most blockchain virtual machines like the Ethereum Virtual Machine (EVM), which execute transactions serially, FuelVM handles concurrent processing, dramatically increasing throughput.

The FuelVM draws on a variety of architectures, including RISC-V, ARM ISAs, Bitcoin scripts, and the Ethereum Virtual Machine, to create a low-level execution environment optimized for blockchain use cases. By offering state-minimized facilities like native assets, ephemeral scripting, and spending conditions, it reduces the load on full nodes, improving network sustainability. Developers can avoid the inefficiencies of traditional state-heavy designs and build applications that deliver high performance while keeping the network decentralized and accessible.

As of May 2024, the FuelVM can achieve asset transfer benchmarks of 21,000 transactions per second (TPS) per core on high-end CPUs, offering unparalleled speed for modern blockchain applications.

## The Fuel Transaction Architecture

Fuel’s transaction architecture brings together lessons from Bitcoin, Ethereum, Cosmos, and Solana to create a highly parallel and efficient transaction model. By using a UTXO (Unspent Transaction Output) model, Fuel enables parallel execution both within and across blocks, allowing developers to process transactions quickly without overloading the network.

Fuel transactions are flexible enough to handle everything from simple asset transfers to complex multi-party, multi-asset interactions and batch smart-contract calls. Developers can build sophisticated applications using advanced conditional logic with predicates, reducing the need for state-heavy smart contracts. By minimizing reliance on state, developers can ensure that applications perform efficiently without overburdening network resources.

Fuel’s transaction model also solves concurrency issues seen in other UTXO-based blockchains. This maintains a familiar developer experience for those coming from Ethereum while benefiting from the performance advantages of UTXO-based execution.

## Fuel Ignition (Rollup)

Fuel Ignition will be the first Fuel V2 rollup to go live on Ethereum Mainnet. It aims to surpass traditional EVM rollups by delivering a vastly improved execution design. Initially starting as a more trustful Layer-2, Ignition’s ultimate goal is to evolve into a fully Ethereum-secured rollup with fraud proving, decentralized sequencing, and secure upgrades via a delayed multi-signature process.

Ignition’s focus on leveraging Ethereum’s security ensures that developers can build high-performance applications while benefiting from the strong security guarantees Ethereum offers. As Ignition develops, it will incorporate decentralized sequencing and Ethereum-based data availability (DA), further enhancing its trustless, scalable design.

## The Fuel Network

Fuel operates as a network of interconnected rollups, designed to offer seamless interaction between different blockchains and rollups. Fuel rollups diverge from the copy-paste approach common in many rollup networks. Fuel's customizable VM configurations enable tailoring each network blockchain to developers' specific needs, enhancing adaptability across diverse use cases. Combined with its decentralized block production model, enabled by a shared sequencing and builder network, Fuel provides a fair and efficient system for managing transaction inclusion and interoperation between rollups.

## Developer Tooling

The Fuel project realized early on the importance of thoughtful and considerate developer tooling. We consider developer time one of our community's most important assets and aim to optimize it for building high-value code. To maximize developer productivity and enable the creation of future-proof applications, we created our own suite of tools. These tools streamline building, testing, and deploying decentralized applications, freeing developers to focus on innovation.

**Sway:** Sway is a domain specific language (DSL) for modern blockchain programming which has familiar syntax, grammar and design ideology to Rust while incorporating blockchain specific functionality such as smart contract interface concepts. Sway is inherently designed to save developers time by providing a single programming language for constructing all critical blockchain application components such as: predicates, scripts, smart contracts, libraries, testing, deployment scripting, indexing and more.

Why not Rust or Solidity? Rust, primarily designed as a systems language, heavily bonds to the Low Level Virtual Machine (LLVM) toolchain and lacks focus on the special considerations of blockchain development. Solidity, a powerful language for developing on the Ethereum Virtual Machine, has many known shortcomings. Sway aims to combine the best aspects of both languages, offering developers a familiar yet powerful tool for blockchain development.

Other tools include:

- **Forc (Fuel Orchestrator):** This command-line toolchain serves as the backbone of Fuel development. It supports everything from compiling Sway smart contracts to managing dependencies and deploying applications. Forc simplifies the entire development process, ensuring that developers can build robust dApps with ease.

- **Fuel Rust SDK:** The Rust SDK allows developers to interact with Fuel’s blockchain using the Rust programming language. It offers a seamless experience for creating system-level applications and managing interactions with the Fuel Network.

- **Fuel Wallet SDK:** The Fuel Wallet SDK provides developers with the tools to create secure, user-friendly wallets that natively interact with the Fuel ecosystem. It ensures developers can easily build wallets that integrate into decentralized applications.

- **Fuel Typescript SDK:** The Typescript SDK allows developers to integrate Fuel into web applications, simplifying interaction with the Fuel blockchain and enabling frontend developers to build decentralized applications that connect with Fuel’s infrastructure.


---

### File: docs/fuel-book/docs/src/why-fuel/index.md

# Chapter 1 - Why Fuel?

- [1.1 - Beginnings](./beginnings.md)
- [1.2 - The Problem](./the-problem.md)
- [1.3 - The Fuel Way](./the-fuel-way.md)
- [1.4 - So, What is Fuel?](./what-is-fuel.md)
- [1.5 - Building on Fuel: An Overview](./building-on-fuel-an-overview.md)


---

### File: docs/fuel-book/docs/src/why-fuel/the-fuel-way.md

# The Fuel Way

Blockchains have largely followed Ethereum's evolutionary path since its launch.

Subsequent chains tout increased speed, scalability, power, and usability. They implement novel consensus mechanisms, databases, and ZK proving systems.

Despite these innovations, the core system remains largely unchanged: developers craft smart contracts for applications and assets (typically in Solidity or Rust). Users rely on centralized servers to read on-chain data and interact by signing messages with a standard private key, then routing these signed messages back through the same centralized servers.

Fuel charts a new course for the blockchain industry, prioritizing decentralization at its core. We're not just iterating; we're rebuilding blockchain architecture from the ground up.

## Decentralized… Sustainably Decentralized

Blockchains fundamentally consist of a network of distributed nodes, all validating new blocks and transactions. The ability for independent, distributed and unqualified actors to participate in this process is what gives blockchains their valuable properties of liveness, censorship resistance and verifiability.

Bitcoin continues to take the most principled stance on maintaining these properties. The low node requirements and low bandwidth usage mean that Bitcoin full nodes can be run on devices as light as Raspberry Pis, and in locations as remote as outer space.

However, subsequent blockchains have all made ongoing compromises. Most newer blockchains today (including most layer-2s) can only be run on high-powered servers with data-center connections. And some high throughput projects remove the key cryptographic primitives of verifiability, such as the merkelization of state elements.

Fuel aims to pull the blockchain space back from this creeping centralization, back towards the values of Bitcoin. The Fuel architecture allows for high performance, while still running on consumer hardware. Fuel always maintains the property of cryptographic verifiability, allowing users to check the state of the chain without trusting third parties.

## Blockchains are not Computers

Advancing blockchain technology demands more than incremental upgrades. True innovation often requires revolutionary action– including breaking changes. Fuel envisions revolutionizing both blockchain architecture and application development to unlock the technology's full potential.Traditional smart-contract platforms mimic computer systems, with blockchains serving as hardware and smart contracts as software. These contracts execute read and write operations, storing data to the chain's state—effectively treating it as a global Postgres database.

Fuel believes that blockchains are not simply scaled-up abstract mainframes but a different kind of computer—"trust machines." These machines are still programmable, but they operate under vastly different constraints than traditional execution environments. The role of a blockchain node is not to act as a cloud server but to verify the current state of the chain and all future state transitions with trustless integrity.

Moving computation off blockchain full nodes and shifting data outside of the blockchain’s state keep full node requirements low, allowing blockchains to scale without centralizing. Fuel enables developers to build smart applications without smart contracts, simplifying development while maintaining the decentralized ethos of blockchain technology.

## ZK Pragmatism

Zero-knowledge technology has captured the imagination of researchers and developers from across the blockchain industry. The promise of succinct verification for arbitrary computation has opened up a whole new range of possibilities for scaling blockchains, making them verifiable, interoperable, and more. The thesis of building the future of ZK-powered blockchain tech has driven some of the most anticipated and well-funded projects in this space.

Fuel adopts a pragmatic approach to zero-knowledge (ZK) technology while recognizing its groundbreaking potential within and beyond blockchains. We share the industry's excitement about these new primitives and are actively integrating ZK technology into the Fuel stack  (such as in Fuel’s hybrid-proving model and with the service chain’s ZK-powered bridge).

Fuel asserts that blockchain security, high performance, and interoperability should not hinge on ZK technology alone. Fuel pioneered the first optimistic rollup on Ethereum, diverging from the prevalent focus on ZK rollups among Ethereum scaling solutions. Fuel maintains that full ZK-verification cannot sustainably meet the market's stringent cost and performance demands.Proof generation costs and time constraints render fully ZK-proven chains incompatible with both cost-effectiveness and high-speed operations. Sustainable proofs and 'real-time proving' typically rely on ZK-specific hardware, which faces numerous production-readiness hurdles.

Fuel crafts cutting-edge blockchain technology, selectively integrating off-the-shelf ZK solutions to enhance its stack. The rise of generalized ZK-VMs like RISC Zero and Succinct’s SP-1 point to a future where ZK technology is commodified and easily available without the need for directly handling the necessary cryptography.


---

### File: docs/fuel-book/docs/src/why-fuel/the-problem.md

# The Problem

The blockchain landscape has advanced rapidly, but key issues still limit decentralized technology’s potential. Fuel is designed to address these fundamental challenges head-on. To understand its significance, we must first examine the core problems that blockchains face today.

## The Performance Bottleneck

Performance can be measured in various ways, such as speed to finality, total execution load capacity, transactions per second and cost-efficiency. However, traditional networks like Ethereum struggle to scale efficiently across these aspects.

One of the critical issues is load. Ethereum's computation overhead limits its processing capacity, restricting the number of transactions per second (TPS), compute units per gas unit, and overall execution capacity. Proving cryptographic evidence of transactions consumes much of this computation. The EVM, for instance, bears a significant cryptographic burden as it verifies and updates the state tree after every transaction. Ethereum's execution layer compounds this inefficiency by poorly optimizing for the underlying hardware, creating unnecessary computational overhead.

Sequential execution of these computations further constraints throughput.If you remove the state tree and focus solely on EVM computation, Ethereum could potentially achieve up to 10,000 TPS. However, the real bottleneck comes from the execution side and the cryptographic evidence required for state verification. Fuel addresses this by removing the need for a state tree and enabling computations to run in parallel, dramatically increasing efficiency. Fuel not only makes execution more efficient but also allows it to scale horizontally, making the system far more accessible to users without driving up costs or limiting throughput.

Cost-efficiency remains a problem. Ethereum's transaction costs fluctuate often, spiking to inaccessible heights during congestion. This unpredictability harms both developers and users, constraining the types of applications they can scale.

## The Scalability Dilemma

Many blockchain projects attempt to achieve scalability by increasing the hardware requirements for their nodes. This approach often makes it more expensive for users to participate, sidelining smaller users and compromising decentralization. Scalability demands more than incremental improvements. It requires fundamental changes to transaction and block processing that enhance efficiency without escalating the network's computational burden.

Early blockchains like Ethereum process transactions sequentially, executing one after another. This linear model severely limits performance on modern multi-core processors designed for parallel processing.

Parallelism, or the ability to process multiple transactions simultaneously, is one of the most promising solutions for blockchain scalability. However, enabling parallel transaction execution requires careful management of state access. If two transactions try to access the same state (for instance, attempting to spend the same funds), they can’t be processed in parallel. This leads to complex mechanisms in many blockchains that either attempt to predict state conflicts or reprocess conflicting transactions.

Fuel addresses these issues by adopting the UTXO model instead of Ethereum’s account-based model. In this model, every transaction defines its own state in the form of unspent transaction outputs, eliminating the risk of conflicting state access. As a result, Fuel can safely parallelize transaction execution, dramatically increasing throughput without compromising security. For developers, this complexity is abstracted away, allowing them to build seamlessly without needing to manage UTXOs directly.

Fuel's architecture introduces stateless primitives called predicates, enhancing efficiency and simplifying state management.This statelessness allows predicates to be trivially processed in parallel, enabling a high degree of concurrency in transaction execution. Predicates facilitate the execution of multiple operations within a single transaction while ensuring that conflicts with other transactions are avoided. Predicates don’t maintain state information between executions, enabling efficient parallel processing and significantly boosting throughput. Fuel's unique architecture enables critical performance gains, powering scalable real-world decentralized applications.

## State Growth and Sustainability

Blockchain growth inflates state size. State encompasses a blockchain's stored data: account balances, smart contract bytecode, and dApp interactions. Unchecked state growth explodes exponentially, threatening system stability. Every new transaction adds more data, and this accumulation increases the burden on node operators. As the state becomes larger, nodes must store and manage increasingly extensive amounts of data, leading to higher hardware requirements and potentially threatening decentralization.

Ethereum is currently grappling with state bloat, which many core developers consider the network’s most pressing scaling issues. As the state grows, nodes must store increasingly large amounts of data, which increases hardware requirements. The ecosystem continually explores possible solutions, such as statelessness and state expiry, but has yet to fully implement any. Ethereum's backwards compatibility limits radical innovation, while Fuel's flexibility enables more flexibility and scalable solutions.

Fuel directly addresses state growth by minimizing unnecessary data accumulation. It discourages excessive state use with op code pricing, pushing developers to optimize their applications. By streamlining data storage and management, Fuel reduces the state nodes must maintain, easing the load on operators. Its architecture efficiently handles data, ensuring the state remains manageable as transactions are processed. Our approach preserves decentralization and accessibility, allowing the network to scale without encountering the challenges of unchecked state growth.

## Interoperability and Fragmentation

Another major problem in today’s multi-chain world is interoperability. Ethereum's unified state machine succeeds largely by enabling application composition, universal asset access, and seamless dApp interactions. However, Ethereum's congestion has driven users to migrate to other L1s and L2s, fragmenting the ecosystem. Each new chain comes with its own set of challenges, including the need for separate wallets, token bridges, and onboarding processes.

Fuel is designed to reunite the fragmented ecosystem with a focus on interoperability at its core. Despite concerns about short-term fragmentation, Fuel's new VM and toolset aim to reduce ecosystem division long-term. Unlike most rollup projects, Fuel is not constrained by the EVM. Its flexible architecture enables innovative design choices for seamless interactions across multiple chains while maintaining full Ethereum compatibility. Fuel’s transaction model and block design simplify cross-chain integrations, making the movement of assets and data between chains easier to manage.

Fuel's proposed shared sequencer design prioritizes speed and efficiency, rapidly processing cross-chain transactions. Our fast sequencing empowers developers to build versatile, low-latency cross-chain applications, mitigating typical multi-chain fragmentation.

Fuel’s unique transaction and block architecture further enhances interoperability by providing execution evidence in the form of receipt roots and smart contract state roots. Verifiable proofs facilitate inter-chain interactions with Fuel, enhancing user experience and cross-chain fluidity.

## The Future: A Modular, Decentralized World

Performance limitations, poor scalability, unsustainable state growth, and minimal interoperability plague the current blockchain landscape. These issues threaten blockchain decentralization and constrain thriving applications. Fuel's innovations—UTXO-based parallelism, modular architecture, and cross-chain capabilities—overcome these limitations, setting a new blockchain infrastructure standard.


---

### File: docs/fuel-book/docs/src/why-fuel/what-is-fuel.md

# So What is Fuel?

Fuel is a next-generation execution layer for Ethereum, designed to offer unparalleled speed, flexibility, and scalability for both developers and users. But what exactly sets Fuel apart from other solutions? And why should you, as a developer, invest your time and energy into learning this architecture?

Fuel embodies a core philosophy of modularity and performance. For developers, Fuel’s appeal lies in both its design philosophy and the tools it offers. Here are a few key reasons why developers should pay attention to Fuel:

1. **Unmatched Parallelization:** Fuel’s unmatched parallelization enables simultaneous transaction processing, allowing significantly higher throughput than many other blockchains. By eliminating serial processing bottlenecks, developers can build scalable, efficient dApps without sacrificing performance. What truly sets Fuel apart is the introduction of predicates, stateless smart accounts that allow transactions to execute in parallel without conflict—something other blockchains struggle to achieve. Combined with the UTXO (Unspent Transaction Output) model, this ensures seamless, concurrent transaction execution, driving scalability to new heights.

2. **Native Assets:** Fuel natively supports a wide variety of assets, but its unique architecture handles them more efficiently. Unlike blockchains that handle only one native asset (like Ethereum's focus on ETH), Fuel enshrines all assets at the protocol level. This means developers don't need to create custom smart contracts for simple asset operations like transfers or balance checks. These operations are built into the system, significantly reducing complexity, time, and the risk of introducing vulnerabilities. Native assets also benefit from performance optimizations, avoiding the overhead of virtual machine processing.

3. **Security and Safety:** Fuel’s architecture eliminates many of the common vulnerabilities seen in smart contract platforms, such as reentrancy attacks. By integrating asset logic into the protocol itself, developers no longer have to rely on third-party contracts or code that could introduce risks. When you transfer tokens or execute other asset-related functions on Fuel, you do so with the assurance that the execution won’t be hijacked by malicious code, significantly enhancing security.

4. **Developer-Friendly Tooling:** Fuel offers an integrated, developer-friendly environment that makes building on its platform easier. Whether you're a seasoned blockchain developer or new to the space, Fuel provides a robust set of tools to support your development process. The Sway programming language, specifically designed for FuelVM, ensures that you’re writing optimized and secure smart contracts. In addition, Fuel’s native development kits (like Forc, the Fuel SDK, and Wallet SDK) make it easy to deploy, test, and manage decentralized applications.

5. **Future-Proof Design:** The blockchain space evolves rapidly, but Fuel is built to grow alongside it. Its modular design allows for the easy adoption of future innovations, whether in virtual machine improvements, consensus upgrades, data availability solutions or ZK. This flexibility ensures that Fuel can adapt to whatever comes next without developers having to constantly rework their applications.


---

### File: docs/fuel-graphql-docs/docs/how-to-use-graphql.md


# How To Use GraphQL

This section covers the fundamentals for how to use a GraphQL API.

For further documentation and resources about GraphQL, check out the official GraphQL Documentation at [graphql.org](https://graphql.org/).


---

### File: docs/fuel-graphql-docs/docs/how-to-use-graphql/apis-explained.md


# Schema & Type System

Unlike traditional REST APIs, GraphQL comes with a strong type system to describe your API. A GraphQL schema describes the data you can query using the API endpoint by defining a set of types and fields that are mapped to those types.

Read along to learn about various GraphQL types.

## Object Types

Object types in GraphQL describe an object with underlying fields that can be queried from your API endpoint.

As an example, an object type can be defined as shown below:

```graphql
type actors {
  name: String!
  appearsIn: [movie!]!
}
```

Here,`actors` is an object type and `name` and `appearsIn` are fields mapped to type `actors`.

## Scalar Types

> From The GraphQL Documentation:

In the example for object types above, field `name` is of type `String`. String in GraphQL is by default a scalar type. This means that it resolves to a definite value and cannot have further sub-fields while querying. Scalar types represent the leaves of a query.

GraphQL comes with a set of default scalar types out-of-the-box such as below:

- `Int`: A signed 32‐bit integer.
- `Float`: A signed double-precision floating-point value.
- `String`: A UTF‐8 character sequence.
- `Boolean`: true or false.
- `ID`: The ID scalar type represents a unique identifier, often used to re-fetch an object or as the key for a cache. The ID type is serialized in the same way as a String; however, defining it as an ID signifies that it is not intended to be human‐readable.

Fields can also be of types that are not scalar by default, but resolve to scalar values upon querying. For instance, in the following query, the `name` and `appearsIn` fields resolve to scalar types.

```graphql
{
  hero {
    name
    appearsIn
  }
}
```

This is because in the schema, `name` and `appearIn` do not have further queryable sub-fields as described below:

```graphql
{
 "data": {
   "hero": {
     "name": "R2-D2",
     "appearsIn": [
       "NEWHOPE",
       "EMPIRE",
       "JEDI"
     ]
   }
 }
}
```

## Lists and Non-nulls

> From the GraphQL documentation:

Object types, scalars, and enums are the only kinds of types you can define in GraphQL. But when you use the types in other parts of the schema, or in your query variable declarations, you can apply additional type modifiers that affect validation of those values.

Let's look at an example:

```graphql
type Character {
  name: String!
  appearsIn: [Episode]!
}
```

Here, we're using a String type and marking it as Non-Null by adding an exclamation mark `!` after the type name. This means that our server always expects to return a non-null value for this field, and if it ends up getting a null value that will actually trigger a GraphQL execution error, letting the client know that something has gone wrong.

The Non-Null type modifier can also be used when defining arguments for a field, causing the GraphQL server to return a validation error if a null value is passed either in the GraphQL string or the variables.

```graphql
query DroidById($id: ID!) {
 droid(id: $id) {
   name
 }
}
{
 "id": null
}
```

```graphql
{
 "errors": [
   {
     "message": "Variable \"$id\" of non-null type \"ID!\" must not be null.",
     "locations": [
       {
         "line": 1,
         "column": 17
       }
     ]
   }
 ]
}
```

```graphql
myField: [String!]
```

This means that the list itself can be null, but it can't have any null members. For example, in JSON:

```json
myField: null // valid
myField: [] // valid
myField: ['a', 'b'] // valid
myField: ['a', null, 'b'] // error

```

## Union types

When a query returns a union type, you can use `... on` to specify the query fields for a certain return type. These are also called inline fragments. For example, the `hero` query below returns a union type of either `Droid` or `Human`.

```graphql
query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}
```

## Connections

Connections are a type of response used whenever you are expecting multiple results that may require pagination. Each query return type that ends in "Connection" will include the following return fields:

```graphql
pageInfo: PageInfo!
edges: [SomethingEdge!]!
nodes: [Something!]!
```

### `PageInfo`

`pageInfo` returns an object that includes information about the returned page of results:

`hasPreviousPage: Boolean!`
Whether or not the result has a previous page.

`hasNextPage: Boolean!`
Whether or not the result has another page after it.

`startCursor: String`
The starting cursor that identifies the first page.

`endCursor: String`
The end cursor that identifies the last page.

### Edges

`edges` returns an array of edge objects, which includes the cursor and first node for that page. You can use this data to help with pagination.

### Nodes

`nodes` returns an array of whichever type you are expecting paginated results for.

### Arguments

Each of these queries also accepts the following arguments:
`first: Int`
`after: String`
`last: Int`
`before: String`

`first` and `last` both accept an integer, which sets the number of results returned for each page. `first` will paginate the results starting at the beginning, while `last` will start from the end. It is required to pass an argument for either `first` or `last`. If no argument is given, the query will not return any results.

`after` and `before` both accept a cursor, which you can use to request different pages. These are both optional arguments.

You can learn more about the connection model and pagination in the official GraphQL docs here: https://graphql.org/learn/pagination/


---

### File: docs/fuel-graphql-docs/docs/how-to-use-graphql/what-is-graphql.md


# What is GraphQL?

## HTTP and APIs Explained

HTTP is a protocol, or a definite set of rules, for accessing resources on the web. Resources could mean anything from HTML files to data from a database, photos, text, and so on.

These resources are made available to us via an Application Programming Interface (API) and we make requests to these APIs via the HTTP protocol. It is the mechanism that allows developers to request resources.

Read more about HTTP methods, client-server architecture, and why you need APIs [here](https://www.freecodecamp.org/news/http-request-methods-explained/).

## How does GraphQL work?

> Note: This section goes over how GraphQL works under the hood, but it is not necessary to know this as a developer building on Fuel. Schema definition, resolver logic, etc. are all written and maintained by the contributors at Fuel Labs.

GraphQL is a query language and specification that describes how you can communicate with your API. GraphQL is not constrained by programming languages, backend frameworks, and databases. GraphQL uses the HTTP protocol under the hood, so you can map GraphQL operations back to simple `GET`, `POST`, `PUT`, or `DELETE` operations. You can view the GraphQL documentation here: https://graphql.org/.

A GraphQL API works by defining types and the properties available on those types, also known as the schema, and defining functions that specify the logic for how to resolve those types. A resolver is a function that's responsible for populating the data for a single field in your schema. Whenever a client queries for a particular field, the resolver for that field fetches the requested data from the appropriate data source.

For example, as an API developer you could define a type, `Car` and define the properties that will be query-able on that type such as below:

```graphql
type Car {
  id: ID
  color: String
  year: Int
  isNew: Boolean
}
```

Fuel Labs created a GraphQL API endpoint for the Fuel Network, allowing developers to make complex queries for data on the blockchain. You can leverage these queries to populate a frontend application with details that your users might be interested in like the history of their transactions, their balance of a specific token, etc.

### GraphQL Queries

Queries in GraphQL allow you to read data. GraphQL lets you ask for specific data and returns exactly what you asked for. It also lets you request multiple resources in a single query instead of writing a separate 'GET' request for each resource as with REST APIs.

GraphQL also facilitates more complex queries and operations such as pagination, sort, filter, full-text search, and more.

Sample query:

```graphql
query Actor {
  actor {
    name {
      appearIn
    }
  }
}
```

The above query gives you a response with the name of the actor along with the name of the movie(s) they appear in.

### GraphQL Mutations

Mutations in GraphQL are write operations that update the chain's state. In addition to being able to traverse objects and their fields, GraphQL gives developers the ability to pass arguments to fields in order to filter out responses. Every field and nested object can have its own set of arguments.

Sample mutation:

```graphql
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}
```


---

### File: docs/fuel-graphql-docs/docs/overview.md


# Overview

## Introduction to the Fuel GraphQL API

The Fuel GraphQL API allows you to query the Fuel blockchain for a wide range of on-chain data. It can be used to query transactions, balances, block information, and more. You can also use it to simulate and submit transactions on the Fuel network.

## GraphQL Playground

The playground is an interactive and graphical IDE that includes a reference for queries, mutations, and types. It also provides query validation and context for the underlying GraphQL schema.

You can test out the Fuel GraphQL API playground here:

**Testnet**: https://testnet.fuel.network/v1/playground

**Mainnet**: https://mainnet.fuel.network/v1/playground

## RPC Endpoints

Here is a list of public RPC endpoints you can use to interact with Fuel, whether it's retrieving on-chain data or sending transactions.

| **Provider**                                            | **Testnet**                                                | **Mainnet**                                                |
|---------------------------------------------------------|------------------------------------------------------------|------------------------------------------------------------|
| [Ankr](https://www.ankr.com/web3-api/chains-list/fuel/) | `https://rpc.ankr.com/http/fuel_sepolia`                   | `https://rpc.ankr.com/http/fuel`                           |
| Fuel                                                    | `https://testnet.fuel.network/v1/graphql`                  | `https://mainnet.fuel.network/v1/graphql`                  |
| [QuickNode](https://www.quicknode.com/chains/fuel)      | `https://fuel-public.fuel-sepolia.quiknode.pro/v1/graphql` | `https://fuel-public.fuel-mainnet.quiknode.pro/v1/graphql` |

> Note: The above endpoints are provided on a best effort basis. If you are running a commercial project, we highly recommend creating an account with one of the providers above to get enhanced support and rate limits.

## Chain Id

A chain ID is a unique identifier assigned to a blockchain network, whether a testnet or a mainnet (Fuel Ignition), to ensure correct transaction signing and prevent replay attacks across chains.

**Testnet**: [`0`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition-test/chain_config.json#L41)

**Mainnet**: [`9889`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition/chain_config.json#L41)


---

### File: docs/fuel-graphql-docs/docs/querying-from-a-dapp.md


# Querying From A Dapp

There are several ways to interact with the Fuel GraphQL API from a frontend application.
This section covers just a few options available to get you started.

## JavaScript

```javascript
export async function getHealth() {
  let response = await fetch(TESTNET_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
    },
    body: JSON.stringify({ query: '{ health }' }),
  });
  let data = await response.json();
  console.log('DATA:', data);
}
```

## Apollo Client

Read the official Apollo Client docs [here](https://www.apollographql.com/apollo-client/).

```bash
npm install @apollo/client graphql
```

```javascript
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const apolloClient = new ApolloClient({
  uri: TESTNET_ENDPOINT,
  cache: new InMemoryCache(),
});

const HEALTH_QUERY = `
  query {
    health
  }
`;

export const checkHealth = async () => {
  const response = await apolloClient.query({
    query: gql(HEALTH_QUERY),
  });
  console.log('RESPONSE:', response);
};
```

## urql

Read the official urql docs [here](https://formidable.com/open-source/urql/).

```bash
npm install urql graphql
```

```javascript
import { Client, cacheExchange, fetchExchange } from 'urql';

const urqlClient = new Client({
  url: TESTNET_ENDPOINT,
  exchanges: [cacheExchange, fetchExchange],
});

const HEALTH_QUERY = `
  query {
    health
  }
`;

export const checkHealth = async () => {
  const response = await urqlClient.query(HEALTH_QUERY).toPromise();
  console.log('RESPONSE:', response);
};
```

You can see more examples in the next section.


---

### File: docs/fuel-graphql-docs/docs/recipes.md


# Recipes

You can see and test the example queries and mutations below.
Click the "Run" button to run the query above it and see the response.
Click the "TypeScript", "Apollo Client", or "urql" buttons to see code examples.

- [Get an asset balance of an address](#get-an-asset-balance-of-an-address)
- [List all asset balances of an address](#list-all-asset-balances-of-an-address)
- [List all transactions from an address](#list-all-transactions-from-an-address)
- [List the latest transactions](#list-the-latest-transactions)
- [Get an asset balance of a contract](#get-an-asset-balance-of-a-contract)
- [List all asset balances of a contract](#list-all-asset-balances-of-a-contract)
- [List the latest blocks](#list-the-latest-blocks)
- [Get block information by height](#get-block-information-by-height)
- [List all messages owned by address](#list-all-messages-owned-by-address)
- [Dry run a transaction](#dry-run-a-transaction)
- [Submit a transaction](#submit-a-transaction)
- [More Examples](#more-examples)

## Get an asset balance of an address

<GQLExamples.Balance />

<CodeExamples
  file="../examples/tests/balance.test.ts"
  ts_testCase="get balance with ts"
  apollo_testCase="get balance with apollo"
  urql_testCase="get balance with urql"
/>

## List all asset balances of an address

<GQLExamples.Balances />

<CodeExamples
  file="../examples/tests/balances.test.ts"
  ts_testCase="get balances with ts"
  apollo_testCase="get balances with apollo"
  urql_testCase="get balances with urql"
/>

## List all transactions from an address

<GQLExamples.Transactions />

<CodeExamples
  file="../examples/tests/transactions-by-owner.test.ts"
  ts_testCase="get transactions with ts"
  apollo_testCase="get transactions with apollo"
  urql_testCase="get transactions with urql"
/>

## List the latest transactions

<GQLExamples.LatestTransactions />

<CodeExamples
  file="../examples/tests/latest-transactions.test.ts"
  ts_testCase="get latest transactions with ts"
  apollo_testCase="get latest transactions with apollo"
  urql_testCase="get latest transactions with urql"
/>

## Get an asset balance of a contract

<GQLExamples.ContractBalance />

<CodeExamples
  file="../examples/tests/contract-balance.test.ts"
  ts_testCase="get contract balance with ts"
  apollo_testCase="get contract balance with apollo"
  urql_testCase="get contract balance with urql"
/>

## List all asset balances of a contract

<GQLExamples.ContractBalances />

<CodeExamples
  file="../examples/tests/contract-balances.test.ts"
  ts_testCase="get contract balances with ts"
  apollo_testCase="get contract balances with apollo"
  urql_testCase="get contract balances with urql"
/>

## List the latest blocks

<GQLExamples.LatestBlocks />

<CodeExamples
  file="../examples/tests/latest-blocks.test.ts"
  ts_testCase="get latest blocks with ts"
  apollo_testCase="get latest blocks with apollo"
  urql_testCase="get latest blocks with urql"
/>

## Get block information by height

<GQLExamples.BlockByHeight />

<CodeExamples
  file="../examples/tests/block.test.ts"
  ts_testCase="get block info with ts"
  apollo_testCase="get block info with apollo"
  urql_testCase="get block info with urql"
/>

## List all messages owned by address

<GQLExamples.MessageInfo />

<CodeExamples
  file="../examples/tests/messages.test.ts"
  ts_testCase="get messages with ts"
  apollo_testCase="get messages with apollo"
  urql_testCase="get messages with urql"
/>

## Dry run a transaction

```graphql
mutation DryRun($encodedTransaction: HexString!, $utxoValidation: Boolean) {
  dryRun(tx: $encodedTransaction, utxoValidation: $utxoValidation) {
    receiptType
    data
  }
}
```

## Submit a transaction

```graphql
mutation submit($encodedTransaction: HexString!) {
  submit(tx: $encodedTransaction) {
    id
  }
}
```

## More Examples

You can find more examples of how we use this API in our GitHub:

[Fuels Typescript SDK](https://github.com/FuelLabs/fuels-ts/)

[Fuels Rust SDK](https://github.com/FuelLabs/fuels-rs/)


---

### File: docs/fuel-graphql-docs/docs/reference.md


# Reference

The reference provides more information about the types, queries, and mutations used in the Fuel GraphQL API.

- [Scalars](/docs/reference/scalars/)

- [Enums](/docs/reference/enums/)

- [Unions](/docs/reference/unions/)

- [Objects](/docs/reference/objects/)

- [Queries](/docs/reference/queries/)

- [Mutations](/docs/reference/mutations/)

- [Subscriptions](/docs/reference/subscriptions/)


---

### File: docs/fuel-graphql-docs/docs/reference/enums.md


# Enums

## `BlockVersion`

The version of the block.

`V1`:
Version 1.

## `ConsensusParametersVersion`

The version of the consensus parameters.

`V1`:
Version 1.

## `ContractParametersVersion`

The version of the contract-specific consensus parameters.

`V1`:
Version 1.

## `FeeParametersVersion`

The version of the fee-specific consensus parameters.

`V1`:
Version 1.

## `GasCostsVersion`

The version of the gas-specific consensus parameters.

`V1`:
Version 1.

## `HeaderVersion`

The version of the header.

`V1`:
Version 1.

## `MessageState`

The state of a message, either `UNSPENT`, `SPENT`, or `NOT_FOUND`.

`UNSPENT`:
The message is unspent.

`SPENT`:
The message is spent.

`NOT_FOUND`:
The message was not found.

## `ReceiptType`

The receipt type indicating what kind of transaction generated the receipt.

`CALL`:
The receipt was generated from a contract call.

`RETURN`:
The receipt was generated from a transaction that returned without data.

`RETURN_DATA`:
The receipt was generated from a transaction that returned data.

`PANIC`:
The receipt was generated from a failed contract call that panicked.

`REVERT`:
The receipt was generated from a failed contract call that reverted.

`LOG`:
The receipt was generated from a log in the contract. The Log receipt is generated for non-reference types, namely `bool`, `u8`, `u16`, `u32`, and `u64`.

`LOG_DATA`:
The receipt was generated from a log in the contract. `LogData` is generated for reference types which include all types except for the non_reference types mentioned above.

`TRANSFER`:
The receipt was generated from a transaction that transferred coins to a contract.

`TRANSFER_OUT`:
The receipt was generated from a transaction that transferred coins to an address (rather than a contract).

`SCRIPT_RESULT`:
The receipt was generated from a script.

`MESSAGE_OUT`:
The receipt was generated from a message.

`MINT`:
The receipt was generated from a mint.

`BURN`:
The receipt was generated from a burn.

## `PredicateParametersVersion`

The version of the predicate-specific consensus parameters.

`V1`:
Version 1.

## `ReturnType`

The type of return response for a transaction

`RETURN`:
Indicates the transaction returned without any data.

`RETURN_DATA`:
Indicates the transaction returned some data.

`REVERT`:
Indicates the transaction reverted.

## `RunState`

The state of a [`RunResult`](/docs/reference/objects/#runresult).

`COMPLETED`:
All breakpoints have been processed, and the program has terminated.

`BREAKPOINT`:
The program stopped on a breakpoint.

## `ScriptParametersVersion`

The version of the script-specific consensus parameters.

`V1`:
Version 1.

## `TxParametersVersion`

The version of the transaction-specific consensus parameters.

`V1`:
Version 1.


---

### File: docs/fuel-graphql-docs/docs/reference/mutations.md


# Mutations

## `startSession`

Initialize a new debugger session, returning its `ID`.
A new VM instance is spawned for each session.
The session is run in a separate database transaction,
on top of the most recent node state.

## `endSession`

End a debugger session.
Returns a `Boolean!` indicating whether the session was successfully ended.

**args:**

`id`: `ID!`

The session ID.

## `reset`

Reset the VM instance to the initial state.
Returns a `Boolean!` indicating whether the VM instance was successfully reset.

**args:**

`id`: `ID!`

The session ID.

## `execute`

Execute a single `fuel-asm` instruction.
Returns a `Boolean!` indicating whether the instruction was successfully executed.

**args:**

`id`: `ID!`

The session ID.

`op`: `String!`

The `fuel-asm` instruction to execute.

## `setSingleStepping`

Set single-stepping mode for the VM instance.
Returns a `Boolean!` indicating whether the mutation successfully executed.

**args:**

`id`: `ID!`

The session ID.

`enable`: `boolean`

Whether to enable single-stepping mode.

## `setBreakpoint`

Set a breakpoint for a VM instance.
Returns a `Boolean!` indicating whether the breakpoint was successfully set.

**args:**

`id`: `ID!`

The session ID.

`breakpoint`: [`Breakpoint!`](/docs/reference/objects/#breakpoint)

The breakpoint to set.

## `startTx`

Run a single transaction in given session until it hits a breakpoint or completes.
Returns a `RunResult!`.

**args:**

`id`: `ID!`

The session ID.

`txJson`: `String!`

The transaction JSON string.

## `continueTx`

Resume execution of the VM instance after a breakpoint.
Runs until the next breakpoint or until the transaction completes.
Returns a `RunResult!`.

**args:**

`id`: `ID!`

The session ID.

## `dryRun`

Spin up a new temporary node from the current state and emulate a given transaction or set of transactions.
Returns a [`[Receipt!]!`](/docs/reference/objects/#receipt) for the emulated transaction.
You can optionally use UTXO validation.

**args:**

`txs`: [`[HexString!]!`](/docs/reference/scalars/#hexstring)

An array of transaction hex strings.

`utxoValidation`: `Boolean`

Whether or not to use UTXO validation.

`gasPrice`: [`U64!`](/docs/reference/scalars/#u64)

The gas price for the multiple transactions ran during the dry run.

## `produceBlocks`

Produce blocks that can be used for testing that requires block advancement.
Returns a [`U32!`](/docs/reference/scalars/#u32).

**args:**

`startTimestamp`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The start time of the produced block.

`blocksToProduce`: [`U64!`](/docs/reference/scalars/#u64)

The number of blocks to produce.

## `submit`

Submit a transaction to the transaction pool.
Returns a [`Transaction!`](/docs/reference/objects/#transaction).

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.


---

### File: docs/fuel-graphql-docs/docs/reference/objects.md


# Objects

## `Balance`

The balance of a particular asset for a wallet address.

**fields:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

An EOA account represented by 32 bytes.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of the selected asset id as an unsigned 64 bit number.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

A 32 byte representation of the asset.

## `BalanceFilterInput`

The filter input type used to filter the `balances` query.

**fields:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address of the balances.

## `Blob`

Information about a blob transaction in the network.

**fields:**

`id`: [`BlobId!`](/docs/reference/scalars/#blobid)

The transaction identifier for the blob.

`bytecode`: [`HexString!`](/docs/reference/scalars/#hexstring)

The blob bytecode.

## `Block`

Information about a block in the network.

**fields:**

`version`: [`BlockVersion!`](/docs/reference/enums/#blockversion)

The version of the block.

`id`: [`BlockId!`](/docs/reference/scalars/#blockid)

A unique identifier for the block.

`height`: [`U32!`](/docs/reference/scalars/#u32)

The height of the block.

`header`: [`Header!`](#header)

Metadata about a block.

`consensus`: [`Consensus!`](/docs/reference/unions/#consensus)

The type of consensus used.

`transactionIds`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

An array of transaction ids included in the block only.

`transactions`: [`[Transaction!]!`](#transaction)

An array of transactions included in the block.

## `Breakpoint`

A breakpoint during debugging.
Defined as a tuple of a contract ID and relative `pc` offset inside it.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`pc`: [`U64!`](/docs/reference/scalars/#u64)

The value of the program counter register `$pc`, which is the memory address of the current instruction.

## `ChainInfo`

Information about the base chain. At a very high level `chainInfo` helps you understand what Fuel chain you're connected to and the different parameters of this chain.

**fields:**

`name`: `String!`

The human-readable string name of the chain. i.e. `Upgradable Testnet`.

`latestBlock`: [`Block!`](#block)

The most recently created block.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The height of the base chain via relayer (i.e. Ethereum or DA)

`consensusParameters`: [`ConsensusParameters!`](#consensusparameters)

The consensus parameters used to validate blocks.

`gasCosts`: [`GasCosts!`](#gascosts)

The gas cost of each opcode.

## `ChangeOutput`

A transaction output that changes the unspent coins in a UTXO.

**fields:**

`to`: [`Address!`](/docs/reference/scalars/#address)

The recipient address of the coins.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the coins.

## `Coin`

Information about a coin.

**fields:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for a UTXO.

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address of the coins.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id of the coin.

`blockCreated`: [`U32!`](/docs/reference/scalars/#u32)

The block when the coins were created.

`txCreatedIdx`: [`U64!`](/docs/reference/scalars/#u64)

The index of the transaction that created this coin.

## `CoinFilterInput`

The filter input type for the `coins` query.

**fields:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner of the coins.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id of the coins.

## `CoinOutput`

A type representing a coin output.

**fields:**

`to`: [`Address!`](/docs/reference/scalars/#address)

The receiver address of the output coins.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins in the output.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the output coins.

## `ConsensusParameters`

The consensus parameters used for validating blocks.

**fields:**

`version`: [`ConsensusParametersVersion!`](/docs/reference/unions/#consensusparametersversion)

The version of the consensus parameters.

`txParams`: [`TxParameters!`](#txparameters)

The allowed parameters of transactions.

`predicateParams`: [`PredicateParameters!`](#predicateparameters)

The allowed parameters of predicates.

`scriptParams`: [`ScriptParameters!`](#scriptparameters)

The allowed parameters of scripts.

`contractParams`: [`ContractParameters!`](#contractparameters)

The allowed parameters of contracts.

`feeParams`: [`FeeParameters!`](#feeparameters)

The allowed parameters of fees.

`baseAssetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id of the "base" asset used for gas fees.

`blockGasLimit`: [`U64!`](/docs/reference/scalars/#u64)

The maximum amount of gas spend allowed in a block.

`blockTransactionSizeLimit`: [`U64!`](/docs/reference/scalars/#u64)

The maximum transaction slots in a block.

`chainId`: [`U64!`](/docs/reference/scalars/#u64)

A unique identifier for the chain.

`gasCosts`: [`GasCosts!`](#gascosts)

The gas cost of each opcode.

`privilegedAddress`: [`Address!`](/docs/reference/scalars/#address)

The address used to authorize network upgrades via the `Upgrade` transaction.

## `ConsensusParametersPurpose`

Details about the consensus parameters that are being upgraded.

**fields:**

`witnessIndex`: [`U16!`](/docs/reference/scalars/#u16)

The index of the witness in the `witnesses` field that contains the serialized consensus parameters. For an upgrade to consensus parameters, the upgraded parameters are stored as a witness in the transaction.

`checksum`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The hash of the serialized consensus parameters.
Since the serialized consensus parameters live inside the transaction witnesses (which is malleable data), any party can override them. The `checksum` is used to verify that the data was not modified or tampered with.

## `Contract`

An object representing a deployed contract.

**fields:**

`id`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`bytecode`: [`HexString!`](/docs/reference/scalars/#hexstring)

The contract bytecode.

`salt`: [`Salt!`](/docs/reference/scalars/#salt)

A unique identifier for the contract.

## `ContractBalance`

An object representing the balance of a deployed contract for a certain asset.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The contract balance for the given asset.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the coins.

## `ContractBalanceFilterInput`

The filter input type for the `contractBalances` query.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract id that the query will return balances for.

## `ContractCreated`

The output type from deploying a contract.

**fields:**

`contract`: [`Contract!`](#contract)

The contract that was created.

`stateRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The initial state root of contract.

## `ContractOutput`

The output type from a transaction that changed the state of a contract.

**fields:**

`inputIndex`: `Int!`

The index of the input.

`balanceRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The root of amount of coins owned by contract after transaction execution.

`stateRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The state root of contract after transaction execution.

## `ContractParameters`

Contract-specific consensus parameters.

**fields:**

`version`: [`ContractParametersVersion!`](/docs/reference/unions/#contractparametersversion)

The version of the contract-specific consensus parameters.

`contractMaxSize`: [`U64!`](/docs/reference/scalars/#u64)

Maximum size of a contract in bytes.

`maxStorageSlots`: [`U64!`](/docs/reference/scalars/#u64)

Maximum number of storage slots.

## `DryRunTransactionExecutionStatus`

Details about the status of a transaction dry run.

**fields:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The transaction ID.

`status`: [`DryRunTransactionStatus!`](/docs/reference/unions/#dryruntransactionstatus)

The status of the transaction dry run.

`receipts`: [`[Receipt!]!`](#receipt)

The receipts for the transaction dry run.

## `DryRunFailureStatus`

The status details of a failed transaction dry run.

**fields:**

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`reason`: `String!`

The reason why the transaction dry run failed.

`receipts`: [`[Receipt!]!`](#receipt)

The transaction dry run receipts.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `DryRunSuccessStatus`

The status details of a successful transaction dry run.

**fields:**

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`receipts`: [`[Receipt!]!`](#receipt)

The transaction dry run receipts.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `EstimateGasPrice`

The estimated gas price for a transaction.

**fields:**

`gasPrice`: [`U64!`](/docs/reference/scalars/#u64)

## `ExcludeInput`

The input type for the `resourcesToSpend` query that defines what UTXOs and messages to exclude.

**fields:**

`utxos`: [`[UtxoId!]!`](/docs/reference/scalars/#utxoid)

An array of UTXO IDs to exclude.

`messages`: [`[Nonce!]!`](/docs/reference/scalars/#nonce)

An array of message IDs to exclude.

## `FailureStatus`

The status type of a transaction that has failed.

**fields:**

`transactionId`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

A unique transaction id.

`blockHeight`: [`U32`](/docs/reference/scalars/#u32)

The block height for the failed transaction.

`block`: [`Block!`](#block)

The block number for the failed transaction.

`transaction`: [`Transaction!`](#transaction)

The transaction itself.

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The time the transaction failed.

`reason`: `String!`

The reason why the transaction failed.

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`receipts`: [`[Receipt!]!`](#receipt)

The receipts for the transaction.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `FeeParameters`

The consensus parameters for fees.

**fields:**

`version`: [`FeeParametersVersion!`](/docs/reference/unions/#feeparametersversion)

The version of the consensus parameters.

`gasPriceFactor`: [`U64!`](/docs/reference/scalars/#u64)

The dynamic adjustment of gas costs.

`gasPerByte`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost per byte.

## `GasCosts`

The breakdown of the gas costs of each opcode.

**fields:**

`version`: [`GasCostsVersion!`](/docs/reference/unions/#gascostsversion)

The version of the gas-specific consensus parameters.

`add`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$add` ALU opcode.

`addi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$addi` ALU opcode.

`aloc`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$aloc` memory opcode.

`and`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$and` ALU opcode.

`andi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$andi` ALU opcode.

`bal`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$bal` contract opcode.

`bhei`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$bhei` contract opcode.

`bhsh`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$bhsh` contract opcode.

`burn`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$burn` contract opcode.

`cb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$cb` contract opcode.

`cfei`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$cfei` memory opcode.

`cfsi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$cfsi` memory opcode.

`div`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$div` ALU opcode.

`divi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$divi` ALU opcode.

`ecr1`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ecr1` cryptographic opcode.

`eck1`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$eck1` cryptographic opcode.

`ed19`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ed19` cryptographic opcode.

`eq`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$eq` ALU opcode.

`exp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$exp` ALU opcode.

`expi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$expi` ALU opcode.

`flag`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$flag` opcode.

`gm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$gm` opcode.

`gt`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$gt` opcode.

`gtf`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$gtf` ALU opcode.

`ji`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ji` control flow opcode.

`jmp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jmp` control flow opcode.

`jne`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jne` control flow opcode.

`jnei`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnei` control flow opcode.

`jnzi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnzi` control flow opcode.

`jmpf`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jmpf` control flow opcode.

`jmpb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jmpb` control flow opcode.

`jnzf`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnzf` control flow opcode.

`jnzb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnzb` control flow opcode.

`jnef`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnef` control flow opcode.

`jneb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jneb` control flow opcode.

`lb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$lb` memory opcode.

`log`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$log` contract opcode.

`lt`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$lt` ALU opcode.

`lw`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$lw` memory opcode.

`mint`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mint` contract opcode.

`mlog`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mlog` ALU opcode.

`modOp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$modOp` opcode.

`modi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$modi` ALU opcode.

`moveOp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$moveOp` ALU opcode.

`movi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$movi` ALU opcode.

`mroo`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mroo` ALU opcode.

`mul`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mul` ALU opcode.

`muli`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$muli` ALU opcode.

`mldv`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mldv` ALU opcode.

`noop`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$noop` ALU opcode.

`not`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$not` ALU opcode.

`or`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$or` ALU opcode.

`ori`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ori` ALU opcode.

`poph`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$poph` opcode.

`popl`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$popl` opcode.

`pshh`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$pshh` opcode.

`pshl`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$pshl` opcode.

`ret`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ret` opcode.

`rvrt`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$rvrt` contract opcode.

`sb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sb` memory opcode.

`sll`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sll` ALU opcode.

`slli`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$slli` ALU opcode.

`srl`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$srl` ALU opcode.

`srli`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$srli` ALU opcode.

`srw`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$srw` contract opcode.

`sub`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sub` ALU opcode.

`subi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$subi` ALU opcode.

`sw`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sw` memory opcode.

`sww`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sww` contract opcode.

`time`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$time` contract opcode.

`tr`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$tr` contract opcode.

`tro`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$tro` contract opcode.

`wdcm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdcm` ALU opcode.

`wqcm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqcm` ALU opcode.

`wdop`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdop` ALU opcode.

`wqop`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqop` ALU opcode.

`wdml`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdml` ALU opcode.

`wqml`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqml` ALU opcode.

`wddv`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wddv` ALU opcode.

`wqdv`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqdv` ALU opcode.

`wdmd`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdmd` ALU opcode.

`wqmd`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqmd` ALU opcode.

`wdam`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdam` ALU opcode.

`wqam`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqam` ALU opcode.

`wdmm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdmm` ALU opcode.

`wqmm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqmm` ALU opcode.

`xor`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$xor` ALU opcode.

`xori`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$xori` ALU opcode.

`alocDependentCost`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$aloc` contract opcode.

`bldd`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$bldd` contract opcode.

`bsiz`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$bsiz` contract opcode.

`cfe`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$cfe` contract opcode.

`cfeiDependentCost`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$cfei` contract opcode.

`call`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$call` contract opcode.

`ccp`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$ccp` contract opcode.

`croo`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$croo` contract opcode.

`csiz`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$csiz` contract opcode.

`ed19DependentCost`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$ed19` contract opcode.

`k256`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$k256` cryptographic opcode.

`ldc`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$ldc` contract opcode.

`logd`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$logd` contract opcode.

`mcl`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcl` memory opcode.

`mcli`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcli` memory opcode.

`mcp`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcp` memory opcode.

`mcpi`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcpi` memory opcode.

`meq`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$meq` memory opcode.

`retd`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$retd` contract opcode.

`s256`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcpi` cryptographic opcode.

`scwq`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$scwq` cryptographic opcode.

`smo`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$smo` contract opcode.

`srwq`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$srwq` contract opcode.

`swwq`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$swwq` contract opcode.

`contractRoot`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost calculating the `contractRoot`.

`stateRoot`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost calculating the `stateRoot`.

`vmInitialization`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of the `vmInitialization`.

`newStoragePerByte`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of storage per byte.

## `Genesis`

The genesis consensus type.

**fields:**

`chainConfigHash`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The chain configuration hash. The chain configuration defines what consensus type to use, what settlement layer to use, and the rules of block validity.

`coinsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary Merkle tree root of all genesis coins.

`contractsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary Merkle tree root of state, balances, and the contracts code hash of each contract.

`messagesRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary merkle tree root of all genesis messages.

`transactionsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary Merkle tree root of all previous transactions.

## `HeavyOperation`

The operation dependent on the size of its inputs, and the time required per unit of input exceeding that of a single no-op operation

**fields:**

`base`: [`U64!`](/docs/reference/scalars/#u64)

The minimum gas that this operation can cost

`gasPerUnit`: [`U64!`](/docs/reference/scalars/#u64)

The gas is required to process a single unit

## `Header`

The header contains metadata about a certain block.

**fields:**

`version`: [`HeaderVersion!`](/docs/reference/enums/#headerversion)

The version of the header.

`id`: [`BlockId!`](/docs/reference/scalars/#blockid)

The current block id.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The block height for the data availability layer up to which (inclusive) input messages are processed.

`consensusParametersVersion`: [`U32!`](/docs/reference/scalars/#u32)

The version of the consensus parameters.

`stateTransitionBytecodeVersion`: [`U32!`](/docs/reference/scalars/#u32)

The version of the state transition bytecode.

`transactionsCount`: [`U64!`](/docs/reference/scalars/#u64)

The number of transactions in the block.

`messageReceiptCount`: [`U64!`](/docs/reference/scalars/#u64)

The number of receipt messages in the block.

`transactionsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The merkle root of the transactions in the block.

`messageOutboxRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The Merkle root of the outgoing messages back to the data availability (DA) layer from Fuel, where the inputs are the IDs (`MessageId`) of the messages. The IDs are produced by executing transactions and collecting IDs from the receipts of the `Message` outputs.

`eventInboxRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The Merkle root of the incoming events from the data availability (DA) layer to Fuel, where the tree inputs are the hashes of these events.

`height`: [`U32!`](/docs/reference/scalars/#u32)

The block height.

`prevRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The merkle root of all previous consensus header hashes (not including this block).

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The timestamp for the block.

`applicationHash`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The hash of the serialized application header for this block.

## `InputCoin`

Information about a coin input.

**fields:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for the UTXO.

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owning address or predicate root.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset ID of the coins.

`txPointer`: [`TxPointer!`](/docs/reference/scalars/#txpointer)

A pointer to the transaction whose output is being spent.

`witnessIndex`: `Int!`

The index of the witness that authorizes spending the coin.

`predicateGasUsed`: [`U64!`](/docs/reference/scalars/#u64)

The amount of gas used in the predicate transaction.

`predicate`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate bytecode.

`predicateData`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate input parameters.

## `InputContract`

Information about a contract input.

**fields:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for the UTXO.

`balanceRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The root of amount of coins owned by contract before transaction execution.

`stateRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The state root of contract before transaction execution.

`txPointer`: [`TxPointer!`](/docs/reference/scalars/#txpointer)

A pointer to the TX whose output is being spent.

`contractId`: [`ContractId!`](/docs/reference/scalars/#contractid)

The input contract's ID.

## `InputMessage`

Information about a message input.

**fields:**

`sender`: [`Address!`](/docs/reference/scalars/#address)

The sender address of the message.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The recipient address of the message.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount sent in the message.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

A nonce value for the message input, which is determined by the sending system and is published at the time the message is sent.

`witnessIndex`: `Int!`

The index of witness that authorizes spending the coin.

`predicateGasUsed`: [`U64!`](/docs/reference/scalars/#u64)

The amount of gas used in the predicate transaction.

`data`: [`HexString!`](/docs/reference/scalars/#hexstring)

The message data.

`predicate`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate bytecode.

`predicateData`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate input parameters.

## `LatestGasPrice`

Information about the latest price of gas.

**fields:**

`gasPrice`: [`U64!`](/docs/reference/scalars/#u64)

The gas price for the latest block produced.

`blockHeight`: [`U32!`](/docs/reference/scalars/#u32)

The block height for the latest block produced.

## `LightOperation`

The operation dependent on the size of its inputs, and the time required per unit of input less that of a single no-op operation

**fields:**

`base`: [`U64!`](/docs/reference/scalars/#u64)

The minimum gas that this operation can cost

`unitsPerGas`: [`U64!`](/docs/reference/scalars/#u64)

The units that can be processed with a single gas

## `MerkleProof`

Information about a merkle proof.

**fields:**

`proofSet`: [`[Bytes32!]!`](/docs/reference/scalars/#bytes32)

The proof set of the message proof.

`proofIndex`: [`U64!`](/docs/reference/scalars/#u64)

The index used to generate this proof.

## `Message`

Contains information about a message.

**fields:**

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of base asset coins sent with the message.

`sender`: [`Address!`](/docs/reference/scalars/#address)

The address of the message sender.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The recipient of the message.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The nonce value for the message.

`data`: `[Int!]!`

The vector with the message data.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The block height of the data availability layer up to which (inclusive) input messages are processed.

## `MessageCoin`

Information about message coin

**fields:**

`sender`: [`Address!`](/docs/reference/scalars/#address)

The address of the message sender.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The recipient of the message.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The nonce value for the message.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of base asset coins sent with the message.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id of the coins transferred.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The block height of the data availability layer up to which (inclusive) input messages are processed.

## `MessageProof`

Information about the message proof.

**fields:**

`messageProof`: [`MerkleProof!`](#merkleproof)

The merkle proof of the message.

`blockProof`: [`MerkleProof!`](#merkleproof)

The merkle proof of the block.

`messageBlockHeader`: [`Header!`](#header)

The merkle proof of the message.

`commitBlockHeader`: [`Header!`](#header)

The merkle proof of the block.

`sender`: [`Address!`](/docs/reference/scalars/#address)

The message sender.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The message recipient.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The message nonce.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount sent in the message.

`data`: [`HexString!`](/docs/reference/scalars/#hexstring)

The data from the message.

## `MessageStatus`

The status type of a message.

**fields:**

`state`: [`MessageState`](/docs/reference/enums/#messagestate)

The state of the message.

## `NodeInfo`

Information about a node.

**fields:**

`utxoValidation`: `Boolean!`

Whether or not the node is using UTXO validation.

`vmBacktrace`: `Boolean!`

Whether or not logging of backtraces from VM errors is enabled.

`maxTx`: [`U64!`](/docs/reference/scalars/#u64)

The maximum number of transactions.

`maxDepth`: [`U64!`](/docs/reference/scalars/#u64)

The maximum number of connected UTXOs allowed, excluding contracts.

`nodeVersion`: `String!`

The node version.

`peers`: [`PeerInfo!`](#peerinfo)!`

The information about the node's peers.

## `OutputBreakpoint`

A breakpoint during debugging.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`pc`: [`U64!`](/docs/reference/scalars/#u64)

The value of the program counter register `$pc`, which is the memory address of the current instruction.

## `PeerInfo`

Information about a peer node.

**fields:**

`id`: `String!`

The `libp2p` ID of the peer node.

`addresses`: `[String!]!`

The advertised addresses that can be used to connect to this peer node.

`clientVersion`: `String`

The self-reported version of the client the peer node is using.

`blockHeight`: [`U32`](/docs/reference/scalars/#u32)

The last reported height of the peer node.

`lastHeartbeatMs`: [`U64!`](/docs/reference/scalars/#u64)

The time of the last heartbeat from this peer node in Unix epoch time milliseconds.

`appScore`: `Float!`

The internal Fuel peer-to-peer reputation of this peer node.

## `PoAConsensus`

The proof-of-authority (PoA) consensus type.

**fields:**

`signature`: [`Signature!`](/docs/reference/scalars/#signature)

The signature of the block produced by PoA consensus.

## `ProgramState`

An object representing the state of execution of a transaction.

**fields:**

`returnType`: [`ReturnType!`](/docs/reference/enums/#returntype)

The type of return response for the transaction.

`data`: [`HexString!`](/docs/reference/scalars/#hexstring)

The data returned from the transaction.

## `Policies`

Information about the policies of a transaction.

**fields:**

`tip`: [`U64`](/docs/reference/scalars/#u64)

The user-defined `tip` is a new transaction policy that replaced the `GasPrice` transaction policy. `Tip` allows the user to specify how much they want to pay to the block producer to incentivize them to include the user's transaction in the block.

`witnessLimit`: [`U64`](/docs/reference/scalars/#u64)

The limit of witnesses that can be included in the transaction.

`maturity`: [`U32`](/docs/reference/scalars/#u32)

The minimum block height that the transaction can be included at.

`maxFee`: [`U64`](/docs/reference/scalars/#u64)

The maximum fee allowed for the transaction to consume.

## `PredicateParameters`

The consensus parameters for predicates.

**fields:**

`version`: [`PredicateParametersVersion!`](/docs/reference/unions/#predicateparametersversion)

The version of the consensus parameters.

`maxPredicateLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of a predicate.

`maxPredicateDataLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of predicate data.

`maxGasPerPredicate`: [`U64!`](/docs/reference/scalars/#u64)

The maximum amount of gas allowed for a predicate.

`maxMessageDataLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of message data for a predicate.

## `Receipt`

An object representing all possible types of receipts.

**fields:**

`id`: [`ContractId!`](/docs/reference/scalars/#contractid)

The ID of the contract that produced the receipt.

`pc`: [`U64`](/docs/reference/scalars/#u64)

The value of the program counter register `$pc`, which is the memory address of the current instruction.

`is`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$is`, which is the pointer to the start of the currently-executing code.

`to`: [`Contract`](#contract)

The recipient contract.

`toAddress`: [`Address`](/docs/reference/scalars/#address)

The recipient address.

`amount`: [`U64`](/docs/reference/scalars/#u64)

The amount of coins transferred.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id of the coins transferred.

`gas`: [`U64`](/docs/reference/scalars/#u64)

The gas used for the transaction.

`param1`: [`U64`](/docs/reference/scalars/#u64)

The first parameter for a `CALL` receipt type, holds the function selector.

`param2`: [`U64`](/docs/reference/scalars/#u64)

The second parameter for a `CALL` receipt type, typically used for the user-specified input to the ABI function being selected.

`val`: [`U64`](/docs/reference/scalars/#u64)

The value of registers at the end of execution, used for debugging.

`ptr`: [`U64`](/docs/reference/scalars/#u64)

The value of the pointer register, used for debugging.

`digest`: [`Bytes32`](/docs/reference/scalars/#bytes32)

A 32-byte hash of `MEM[$rC, $rD]`. The syntax `MEM[x, y]` means the memory range starting at byte `x`, of length `y` bytes.

`reason`: [`U64`](/docs/reference/scalars/#u64)

The decimal string representation of an 8-bit unsigned integer for the panic reason. Only returned if the receipt type is `PANIC`.

`ra`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rA`.

`rb`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rB`.

`rc`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rC`.

`rd`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rD`.

`len`: [`U64`](/docs/reference/scalars/#u64)

The length of the receipt.

`receiptType`: [`ReceiptType!`](/docs/reference/enums/#receipttype)

The type of receipt.

`result`: [`U64`](/docs/reference/scalars/#u64)

`0` if script exited successfully, `any` otherwise.

`gasUsed`: [`U64`](/docs/reference/scalars/#u64)

The amount of gas consumed by the script.

`data`: [`HexString`](/docs/reference/scalars/#hexstring)

The receipt data.

`sender`: [`Address`](/docs/reference/scalars/#address)

The address of the message sender.

`recipient`: [`Address`](/docs/reference/scalars/#address)

The address of the message recipient.

`nonce`: [`Nonce`](/docs/reference/scalars/#nonce)

The nonce value for a message.

`contractId`: [`ContractId`](/docs/reference/scalars/#contractid)

The contract id.

`subId`: [`Bytes32`](/docs/reference/scalars/#bytes32)

The sub id.

## `RelayedTransactionFailed`

Details about why a relayed transaction from an L1 failed.

**fields:**

`blockHeight`: `U32!`

The block height at the time the relayed transaction failed.

`failure`: `String!`

The reason why the transaction failed.

## `RunResult`

The result of a transaction execution.

**fields:**

`state`: `RunState!`

The state of the transaction execution.

`breakpoint`: `OutputBreakpoint`

A breakpoint during debugging.

`jsonReceipts`: `[String!]!`

The receipts of the transaction in JSON format.

## `ScriptParameters`

The consensus parameters for a script.

**fields:**

`version`: [`ScriptParametersVersion!`](/docs/reference/unions/#scriptparametersversion)

The version of the consensus parameters.

`maxScriptLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of a script.

`maxScriptDataLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of script data.

## `SpendQueryElementInput`

A type used in the `queryPerAsset` argument for the `resourcesToSpend` query.

**fields:**

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the asset.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins to send.

`max`: [`U64`](/docs/reference/scalars/#u64)

The max number of resources in the selection.

## `SqueezedOutStatus`

The status for a transaction that was squeezed out of the transaction pool.

**fields:**

`reason`: `String!`

The reason why the transaction was squeezed out.

## `StateTransitionBytecode`

The bytecode of a state transition upgrade.

**fields:**

`root`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

The merkle root of the state transition bytecode.

`bytecode`: [`[UploadedBytecode!]`](#uploadedbytecode)

The bytecode of the state transition.

## `StateTransitionPurpose`

Details about a state transition upgrade.

**fields:**

`root`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The merkle root of the new state.

## `SuccessStatus`

The status of a successful transaction.

**fields:**

`transactionId`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The ID of the transaction.

`blockHeight`: [`U32`](/docs/reference/scalars/#u32)

The block height for the successful transaction.

`block`: [`Block!`](#block)

The block for the successful transaction.

`transaction`: [`Transaction!`](#transaction)

The transaction itself.

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The time of the transaction.

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`receipts`: [`[Receipt!]!`](#receipt)

The transaction receipts.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `SubmittedStatus`

The status for a submitted transaction.

**fields:**

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The time a transaction was submitted

## `Transaction`

An object containing information about a transaction.

**fields:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

A unique transaction id.

`inputAssetIds`: [`[AssetId!]`](/docs/reference/scalars/#assetid)

An array of asset ids used for the transaction inputs.

`inputContracts`: [`[Contract!]`](#contract)

An array of contracts used for the transaction inputs.

`inputContract`: [`InputContract`](#inputcontract)

A contract used for the transaction input.

`policies`: [`Policies`](#policies)

The policies for the transaction.

`scriptGasLimit`: [`U64`](/docs/reference/scalars/#u64)

The gas limit for the transaction.

`maturity`: [`U32`](/docs/reference/scalars/#u32)

The minimum block height that the transaction can be included at.

`mintAmount`: [`U64`](/docs/reference/scalars/#u64)

The amount minted in the transaction.

`mintAssetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset ID for coins minted in the transaction.

`mintGasPrice`: [`U64!`](/docs/reference/scalars/#u64)

The gas price at the time of minting the block.

`txPointer`: [`TxPointer`](/docs/reference/scalars/#txpointer)

The location of the transaction in the block.

`isScript`: `Boolean!`

Whether or not the transaction is a script.

`isCreate`: `Boolean!`

Whether or not the transaction is creating a new contract.

`isMint`: `Boolean!`

Whether or not the transaction is minting new coins.

`isUpgrade`: `Boolean!`

Whether or not the transaction is upgrading the network.

`isUpload`: `Boolean!`

Whether or not the transaction is uploading state transition data to prepare for upgrading the network.

`isBlob`: `Boolean!`

Whether or not the transaction is a blob.

`inputs`: [`[Input!]`](/docs/reference/unions/#input)

An array of inputs for the transaction.

`outputs`: [`[Output!]!`](/docs/reference/unions/#output)

An array of outputs for the transaction.

`outputContract`: [`ContractOutput`](#contractoutput)

The contract output for the transaction.

`witnesses`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

An array of witnesses.

`receiptsRoot`: [`Bytes32`](/docs/reference/scalars/#bytes32)

The root of the receipts.

`status`: [`TransactionStatus`](/docs/reference/unions/#transactionstatus)

The status of the transaction.

`script`: [`HexString`](/docs/reference/scalars/#hexstring)

The script to execute.

`scriptData`: [`HexString`](/docs/reference/scalars/#hexstring)

The script input parameters.

`bytecodeWitnessIndex`: `Int`

The witness index of contract bytecode.

`blobId`: [`BlobId`](/docs/reference/scalars/#blobid)

A unique hash identifier for a blob transaction.

`salt`: [`Salt`](/docs/reference/scalars/#salt)

The salt value for the transaction.

`storageSlots`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

An array of storage slot.

`bytecodeRoot`: [`Bytes32`](/docs/reference/scalars/#bytes32)

The Merkle tree root of the bytecode that is being uploaded.

`subsectionIndex`: [`U16`](/docs/reference/scalars/#u16)

The index of the subsection of the bytecode.

`subsectionsNumber`: [`U16`](/docs/reference/scalars/#u16)

The total number of subsections that the bytecode was divided into.

`proofSet`: [`[Bytes32!]`](/docs/reference/scalars/#bytes32)

The proof set helps to verify the connection of the subsection to the `root`.

`upgradePurpose`: [`UpgradePurpose`](/docs/reference/unions/#upgradepurpose)

The purpose of a network upgrade.

`rawPayload`: [`HexString!`](/docs/reference/scalars/#hexstring)

A hex string of the raw transaction payload.

## `TxParameters`

The consensus parameters for a transaction.

**fields:**

`version`: [`TxParametersVersion!`](/docs/reference/unions/#txparametersversion)

The version of the consensus parameters.

`maxInputs`: [`U8!`](/docs/reference/scalars/#u8)

The maximum number of inputs allowed for a transaction.

`maxOutputs`: [`U8!`](/docs/reference/scalars/#u8)

The maximum number of outputs allowed for a transaction.

`maxWitnesses`: [`U32!`](/docs/reference/scalars/#u32)

The maximum number of witnesses allowed for a transaction.

`maxGasPerTx`: [`U64!`](/docs/reference/scalars/#u64)

The maximum amount of gas allowed for a transaction.

`maxSize`: [`U64!`](/docs/reference/scalars/#u64)

The maximum size allowed for a transaction.

`maxBytecodeSubsections`: [`U16!`](/docs/reference/scalars/#u16)

The maximum number of subsections the new executor bytecode can be broken into.

## `UploadedBytecode`

**fields:**

`bytecode`: [`[HexString!]!`](/docs/reference/scalars/#hexstring)

The bytecode that is uploaded.

`uploadedSubsectionsNumber`: `Int`

The number of uploaded subsections.

`completed`: `Boolean!`

Whether or not the bytecode upload has completed.

## `VariableOutput`

The output type for a transaction that outputs an amount that may vary based on transaction execution.

**fields:**

`to`: [`Address`](/docs/reference/scalars/#address)

The address the coins were sent to.

`amount`: [`U64`](/docs/reference/scalars/#u64)

The amount of coins in the output.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id for the coins sent.


---

### File: docs/fuel-graphql-docs/docs/reference/queries.md


# Queries

## `balance`

Returns the [`Balance!`](/docs/reference/objects/#balance) of a specific address for a given asset id.

**args:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id.

## `balances`

Returns a [`BalanceConnection!`](/docs/reference/objects/#balance) for an array of balances for each asset owned by a given address.

**args:**

`filter`: [`BalanceFilterInput!`](/docs/reference/objects/#balancefilterinput)

A filter to specify the wallet owner address.

## `blob`

Returns information about a certain [`Blob`](/docs/reference/objects/#blob).

**args:**

`id`: [`BlobId`](/docs/reference/scalars/#blobid)

The transaction identifier for the blob.

## `block`

Returns information about a certain [`Block`](/docs/reference/objects/#block). Accepts either the block id or block height as an argument.

**args:**

`id`: [`BlockId`](/docs/reference/scalars/#blockid)

The block id.

`height`: [`U64`](/docs/reference/scalars/#u64)

The block height.

## `blocks`

Returns a [`BlockConnection!`](/docs/reference/objects/#block) for an array of all blocks produced.

## `chain`

Returns [`ChainInfo!`](/docs/reference/objects/#chaininfo) about the target Fuel network used for the API.

## `coin`

Returns details about a specific [`Coin`](/docs/reference/objects/#coin).

**args:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for the UTXO.

## `coins`

Returns a [`CoinConnection!`](/docs/reference/objects/#coin) for an array of coins based on a given owner and/or asset id

**args:**

`filter`: [`CoinFilterInput!`](/docs/reference/objects/#coinfilterinput)

A filter with the owner address and optionally the asset id.

## `coinsToSpend`

Returns an array of spendable [`[[CoinType!]!]!`](/docs/reference/unions/#cointype) per asset.

**args:**

`owner`: [`Address`](/docs/reference/scalars/#address)

The owner address of the coins.

`queryPerAsset`: [`[SpendQueryElementInput!]!`](/docs/reference/objects/#spendqueryelementinput)

The list of requested asset resources. Several entries with the same asset id are not allowed.

`excludedIds`: [`ExcludeInput`](/docs/reference/objects/#excludeinput)

The resources to exclude.

## `consensusParameters`

Returns the [`ConsensusParameters`](/docs/reference/objects/#consensusparameters) for a given version.

**args:**

`version`: `Int!`

The version of the consensus parameters.

## `contract`

Returns the [`Contract`](/docs/reference/objects/#contract) information for a given contract id.

**args:**

`id`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract id of the requested contract.

## `contractBalance`

Returns the [`ContractBalance!`](/docs/reference/objects/#contractbalance) for a given contract and asset id.

**args:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract that owns the balance.

`asset`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the balance.

## `contractBalances`

Returns a [`ContractBalanceConnection!`](/docs/reference/objects/#contractbalance) for an array of balances for all assets owned by a given contract

**args:**

`filter`: [`ContractBalanceFilterInput!`](/docs/reference/objects/#contractbalancefilterinput)

A filter for the contract balances.

## `estimateGasPrice`

Estimates the most expensive the gas price over a given block horizon, and returns [`EstimateGasPrice!`](/docs/reference/objects/#estimategasprice).

**args:**

`blockHorizon`: [`U32!`](/docs/reference/scalars/#u32)

The block horizon defines how many blocks in the future you are doing an estimate for.

## `estimatePredicates`

Estimate the predicate gas and returns a [`Transaction!`](/docs/reference/objects/#transaction).

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.

## `health`

Returns `true` if the API is running or `false` if the API is down.

## `latestGasPrice`

Returns the [`LatestGasPrice!`](/docs/reference/objects/#latestgasprice) of the latest block.

## `message`

Returns the [`Message`](/docs/reference/objects/#message) for a given message nonce.

**args:**

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The message nonce.

## `messageProof`

Returns the [`MessageProof`](/docs/reference/objects/#messageproof) for a given message id or transaction.

**args:**

`transactionId`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The transaction id for the message.

`nonce`: [`Nonce`](/docs/reference/scalars/#nonce)

The message nonce.

`commitBlockId`: [`BlockId`](/docs/reference/scalars/#blockid)

The block id.

`commitBlockHeight`: [`U32`](/docs/reference/scalars/#u32)

The block height.

## `messages`

Returns a [`MessageConnection!`](/docs/reference/objects/#message) for an array of messages for a given owner.

**args:**

`owner`: [`Address`](/docs/reference/scalars/#address)

The owner address of the messages.

## `messageStatus`

Returns the [`MessageStatus`](/docs/reference/objects/#messagestatus) for a given message [`Nonce`](/docs/reference/scalars/#nonce).

**args:**

`nonce`: [`Nonce`](/docs/reference/scalars/#nonce)

The nonce of the message.

## `nodeInfo`

Returns [`NodeInfo!`](/docs/reference/objects/#nodeinfo) about the current node.

## `relayedTransactionStatus`

Returns [`RelayedTransactionStatus`](/docs/reference/unions/#relayedtransactionstatus) details for a given relayed transaction id.

**args:**

`id`: [`RelayedTransactionId!`](/docs/reference/scalars/#relayedtransactionid)

The ID for the relayed transaction.

## `stateTransitionBytecodeByVersion`

Returns [`StateTransitionBytecode`](/docs/reference/objects/#statetransitionbytecode) details for a given version.

**args:**

`version`: `Int!`

The version of the state transition function..

## `stateTransitionBytecodeByRoot`

Returns [`StateTransitionBytecode`](/docs/reference/objects/#statetransitionbytecode) details for a given root.

**args:**

`root`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

The merkle root of the state transition bytecode.

## `transaction`

Returns [`Transaction`](/docs/reference/objects/#transaction) details for a given transaction id.

**args:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The ID for the transaction.

## `transactions`

Returns a [`TransactionConnection!`](/docs/reference/objects/#transaction) for an array of all transactions.

## `transactionsByOwner`

Returns a [`TransactionConnection!`](/docs/reference/objects/#transaction) for an array of all transactions from a given address.

**args:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address of the transactions.


---

### File: docs/fuel-graphql-docs/docs/reference/scalars.md


# Scalars

## `Address`

An address of an externally owned account identified by a 32 byte string prefixed by `0x`.

## `AssetId`

A 32 byte unique ID used to identify a coin. On the testnet, the `assetId` is `0x0000000000000000000000000000000000000000000000000000000000000000`.

## `BlobId`

A unique hash identifier for a blob transaction.

## `BlockId`

A unique hash identifier for a block.

## `Bytes32`

32 bytes to hold arbitrary data, usually as a hex string. `Bytes32` is the base type for cryptographic primitives like `Address` or `Message`.

## `ContractId`

A wrapped 32byte hash that is used to uniquely identify a contract.

## `HexString`

A way to pass in bytes as hex data. This is used for variable byte length types. Predicates and predicate data are always a hex string.

## `Nonce`

A random or pseudo-random number generated for a single use to ensure data freshness and prevent replay attacks.

## `RelayedTransactionId`

The ID for a relayed transaction.

## `Salt`

Sometimes referred to as a nonce. A unique, random value used to distinguish two things that are otherwise identical. This is used in contract deployments so you can deploy contracts that are otherwise exactly the same.

## `Signature`

A cryptographic signature used to authorize messages and transactions.

## `Tai64Timestamp`

A TAI 64 timestamp.

## `TransactionId`

A unique 32 byte hash identifier for a transaction.

## `TxPointer`

The location of the transaction in the block. It can be used by UTXOs as a reference to the transaction or by the transaction itself to make it unique.

## `U16`

Unsigned 16 bit integer.

## `U32`

Unsigned 32 bit integer.

## `U64`

Unsigned 64 bit integer. The default GraphQL `int` scalar does not cover the range of values needed because the FuelVM word size is 64bit.

## `UtxoId`

A unique 32 byte identifier for a UTXO.


---

### File: docs/fuel-graphql-docs/docs/reference/subscriptions.md


# Subscriptions

## `statusChange`

Returns a stream of [`TransactionStatus!`](/docs/reference/unions/#transactionstatus) updates for the given transaction id if the current status is `[TransactionStatus::Submitted]`.

This stream will wait forever so it's advised to use within a timeout. It is possible for the stream to miss an update if it is polled slower then the updates arrive. In such a case the stream will close without a status. If this occurs the stream can simply be restarted to return the latest status.

**args:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The id of the transaction to stream status updates for.

## `submitAndAwait`

Submits a transaction to the `TxPool` and await returns the [`TransactionStatus!`](/docs/reference/unions/#transactionstatus).

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.

## `submitAndAwaitStatus`

Submits the transaction to the `TxPool` and returns a stream of events. Compared to the [`submitAndAwait`](/docs/reference/subscriptions/#submitandawait), the stream also contains [`SubmittedStatus`](/docs/reference/objects/#submittedstatus) as an intermediate state.

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.


---

### File: docs/fuel-graphql-docs/docs/reference/unions.md


# Union Types

## `CoinType`

The type of coin being used.

**Types:**

[`Coin`](/docs/reference/objects/#coin): A standard coin.

[`MessageCoin`](/docs/reference/objects/#messagecoin): A message coin.

## `Consensus`

The type of consensus mechanism used to validate a block.

**Types:**

[`Genesis`](/docs/reference/objects/#genesis): Genesis consensus

[`PoAConsensus`](/docs/reference/objects/#poaconsensus): PoA
consensus

## `DependentCost`

Contains the dependent cost of opcodes.

**Types:**

[`LightOperation`](/docs/reference/objects/#lightoperation): Operations that can process many units with 1 gas

[`HeavyOperation`](/docs/reference/objects/#heavyoperation): Operations that require more than 1 gas to process a single unit

## `DryRunTransactionStatus`

The status of a transaction dry run.

**Types:**

[`DryRunSuccessStatus`](/docs/reference/objects/#dryrunsuccessstatus): The transaction dry run was successful.

[`DryRunFailureStatus`](/docs/reference/objects/#dryrunfailurestatus): The transaction dry run failed.

## `Input`

An input type for a transaction.

**Types:**

[`InputCoin`](/docs/reference/objects/#inputcoin): An input type for
a coin.

[`InputContract`](/docs/reference/objects/#inputcontract): An input
type for a contract.

[`InputMessage`](/docs/reference/objects/#inputmessage): An input
type for a message.

## `Output`

An output type for a transaction.

**Types:**

[`CoinOutput`](/docs/reference/objects/#coinoutput): Indicates coins
were forwarded from one address to another.
Can be used during transaction creation when the recipient, asset, and amount is known.

[`ContractOutput`](/docs/reference/objects/#contractoutput):
Indicates the transaction updated the state of a contract.

[`ChangeOutput`](/docs/reference/objects/#changeoutput): Indicates
that the output's amount may vary based on transaction execution, but is
otherwise identical to a Coin output. Output changes are always guaranteed to
have an amount of zero since they're only set after execution terminates.

[`VariableOutput`](/docs/reference/objects/#variableoutput): Similar
to `ChangeOutput`, this output type indicates that the output's amount may vary
based on transaction execution, but is otherwise identical to a Coin output. On
initialization, the amount on variable outputs is zero, but during execution
they could be set to a non-zero value.

[`ContractCreated`](/docs/reference/objects/#contractcreated):
Indicates a contract was deployed.

## `RelayedTransactionStatus`

The status of a relayed transaction from a L1. If the transaction is valid, it will be included in part of a block. If the transaction is invalid, it will be skipped.

**Types:**

[`RelayedTransactionFailed`](/docs/reference/objects/#relayedtransactionfailed): Details about why the relayed transaction failed.

## `TransactionStatus`

The status type of a transaction.

**Types:**

[`SubmittedStatus`](/docs/reference/objects/#submittedstatus): The transaction has been submitted.

[`SuccessStatus`](/docs/reference/objects/#successstatus): The transaction has succeeded.

[`SqueezedOutStatus`](/docs/reference/objects/#squeezedoutstatus): The transaction was kicked out of the mempool.

[`FailureStatus`](/docs/reference/objects/#failurestatus): The transaction has failed.

## `UpgradePurpose`

The purpose of a network upgrade.

**Types:**

[`ConsensusParametersPurpose`](/docs/reference/objects/#consensusparameterspurpose): The consensus parameters are being upgraded.

[`StateTransitionPurpose`](/docs/reference/objects/#statetransitionpurpose): The state transition is being upgraded.


---

### File: docs/fuel-specs/src/abi/argument-encoding.md

# Argument Encoding

## Version 0

> :warning: This version is being deprecated for Version 1 (see below).

When crafting transaction script data, you must encode the arguments you wish to pass to the script.

### Types

These are the available types that can be encoded in the ABI:

- Unsigned integers:
  - `u8`, 8 bits.
  - `u16`, 16 bits.
  - `u32`, 32 bits.
  - `u64`, 64 bits.
  - `u128`, 128 bits.
  - `u256`, 256 bits.
- Boolean: `bool`, either `0` or `1` encoded identically to `u8`.
- B256: `b256`, arbitrary 256-bits value.
- Address : `address`, a 256-bit (32-byte) address.
- Fixed size string
- Array
- Enums (sum types)
- Structs
- Vectors
- Tuples

These types are encoded in-place. Here's how to encode them. We define `enc(X)` the encoding of the type `X`.

### Unsigned Integers

`u<M>` where `M` is either 8, 16, 32, 64, 128 or 256 bits.

`enc(X)` is the big-endian (i.e. right-aligned) representation of `X` left-padded with zero-bytes.

- In the case of `M` being 8, 16, 32 or 64, total length must be 8 bytes.
- If `M` is 128, total length must be 16 bytes.
- If `M` is 256, total length must be 32 bytes.

> **Note:** since all integer values are unsigned, there is no need to preserve the sign when extending/padding; padding with only zeroes is sufficient._

**Example:**

Encoding `42` yields: `0x000000000000002a`, which is the hexadecimal representation of the decimal number `42`, right-aligned to 8 bytes.
Encoding `u128::MAX - 1` yields: `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE`, it's right-aligned to 16 bytes

### `Boolean`

`enc(X)` is `0` if `X` is false or `1` if `X` is true, left-padded with zero-bytes. Total length must be 8 bytes. Similar to the `u8` encoding.

**Example:**

Encoding `true` yields:

```text
0x0000000000000001
```

### `B256`

`b256` is a fixed size bit array of length 256. Used for 256-bit hash digests and other 256-bit types. It is encoded as-is.

**Example:**

Encoding `0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745` yields:

```text
0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745
```

### `Address`

A 256-bit (32-byte) address, encoded in the same way as a `b256` argument: encoded as-is.

**Example:**

Encoding `0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745` yields:

```text
0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745
```

### Array

An array of a certain type `T`, `[T; n]`, where `n` is the length of the array.

Arrays in Sway have a fixed-length which is known at compile time. This means the ABI encoding for arrays also happens in-place, with no need to account for dynamic sizing.

The encoding for the array contains, in order, the encoding of each element in `[T; n]`, recursively following the encoding for the type `T`.

For instance, consider the function signature `my_func(bool, [u64; 2])` with the values `(true, [1, 2])`.

The encoding will be:

1. `0x0000000000000001`, the `true` bool encoded in-place.
2. `0x0000000000000001`, First element of the parameter `[u64; 2]`, `1`, encoded as a `u64`.
3. `0x0000000000000002`, Second element of the parameter `[u64; 2]`, `2`, encoded as a `u64`.

The resulting encoded ABI will be:

```text
0x000000000000000100000000000000010000000000000002
```

### Fixed-length Strings

Strings have fixed length and are encoded in-place. `str[n]`, where `n` is the fixed-size of the string. Rather than padding the string, the encoding of the elements of the string is tightly packed. And unlike the other type encodings, the string encoding is left-aligned.

Note that all strings are encoded in UTF-8.

**Example:**

Encoding `"Hello, World"` as a `str[12]` **yields**:

```text
0x48656c6c6f2c20576f726c6400000000
```

Note that we're padding with zeroes in order to keep it right-aligned to 8 bytes (FuelVM's word size).

### Structs

Encoding ABIs that contain custom types, such as structs, is similar to encoding a set of primitive types. The encoding will proceed in the order that the inner types of a custom type are declared and _recursively_ just like encoding any other type. This way you can encode structs with primitive types or structs with more complex types in them such as other structs, arrays, strings, and enums.

Here's an example:

```rust
struct InputStruct {
    field_1: bool,
    field_2: u8,
}


abi MyContract {
    fn foo(a: u64);
    fn bar(a: InputStruct);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `InputStruct { field_1: true, field_2: 5 }` yields:

```plaintext
0x
0000000000000001 // `true` encoded as a bool
0000000000000005 // `5` encoded as u8
```

A more complex scenario:

```rust
struct InputStruct {
    field_1: bool,
    field_2: [u8; 2], // An array of u8, with length 2.
}


abi MyContract {
    fn foo(a: u64);
    fn bar(a: InputStruct);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `InputStruct { field_1: true, field_2: [1, 2] }` yields:

```plaintext
0x
0000000000000001 // `true` encoded as a bool
0000000000000001 // `1` encoded as u8
0000000000000002 // `2` encoded as u8
```

### Enums (sum types)

ABI calls containing enums (sum types) are encoded similarly to structs: encode the discriminant first, then recursively encode the type of the enum variant being passed to the function being called.

```rust
enum MySumType
{
    X: u32,
    Y: bool,
}

abi MyContract {
    fn foo(a: u64);
    fn bar(a: MySumType);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `MySumType::X(42)` yields:

```plaintext
0x
0000000000000000 // The discriminant of the chosen enum, in this case `0`.
000000000000002a // `42` encoded as u64
```

If the sum type has variants of different sizes, then left padding is required.

```rust
enum MySumType
{
    X: b256,
    Y: u32,
}

abi MyContract {
    fn foo(a: u64);
    fn bar(a: MySumType);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `MySumType::Y(42)` yields:

```plaintext
0x
0000000000000001 // The discriminant of the chosen enum, in this case `1`.
0000000000000000 // Left padding
0000000000000000 // Left padding
0000000000000000 // Left padding
000000000000002a // `42` encoded as u64
```

Note that three words of padding are required because the largest variant of `MySumType` is 4 words wide.

If all the variants of a sum type are of type `()`, or unit, then only the discriminant needs to be encoded.

```rust
enum MySumType
{
    X: (),
    Y: (),
    Z: (),
}

abi MyContract {
    fn foo(a: u64);
    fn bar(a: MySumType);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `MySumType::Z` yields:

```plaintext
0x
0000000000000002 // The discriminant of the chosen enum, in this case `2`.
```

### Vectors

ABI calls containing vectors are encoded in the following way:

- First, figure out the the length `l` of the vector. Its length will also be its capacity.
- Encode the content of the vector according to the spec of its type, e.g. for a `Vec<bool>`,
  encode each `bool` element according to the `bool` specs. This gives out data that is stored
  on the heap, and we encode only the pointer to this data

```rust
abi MyContract {
  fn foo(a: Vec<u32>);
} {
  fn foo(a: Vec<u32>) {};
}
```

Calling `foo` with `vec![1u32, 2u32, 3u32, 4u32]`:

- `length` is 4, `capacity` is 4
- `data`: [0x0000000000000001, 0x0000000000000002, 0x0000000000000003, 0x0000000000000004], stored at pointer address `0x000000000000beef`

> Note: to understand how the `u32` are encoded, see the section about encoding integers.

```plaintext
0x
000000000000beef // pointer address
0000000000000004 // length = 4
0000000000000004 // capacity = 4
```

At the pointer address, then the vector's content are encoded as such:

```plaintext
0x
0000000000000001 // 1u32
0000000000000002 // 2u32
0000000000000003 // 3u32
0000000000000004 // 4u32
```

### Tuples

ABI calls containing tuples are encoded as such:
If `X` is a tuple with the type signature `(T_1, T_2, ..., T_n)`, with `T_1,...,T_n` being any type except for vector, then `enc(X)` is encoded as the concatenation of `enc(T_1)`, `enc(T_2)`,`enc (T_3)`, ..., `enc(T_n)`.

```rust
abi MyContract {
  fn foo(a: (u64, str[3], bool));
} {
  fn foo(a: (u64, str[4], bool)) {};
}
```

Calling `foo` with `(1u64, "fuel", true)` :

```plaintext
0x
0000000000000001 // 1u64
6675656c00000000 // "fuel" encoded as per the specs
0000000000000001 // true
```

## Version 1

This version was created to replace the older version 0 described above, and follows three philosophical tenets:

- being self-sufficient: it must be possible to completely decode the original data only using the encoded bytes and the original type (there are no references to data outside the encoded bytes);
- no overhead: only the bare minimum bytes are necessary to do the encoding. No metadata, headers, etc...;
- no relation with runtime memory layout: no padding, no alignment, etc...

### Primitive Types

Primitive types will be encoded using the exact number of bits they need:

- `u8`: 1 byte;
- `u16`: 2 bytes;
- `u32`: 4 bytes;
- `u64`: 8 bytes;
- `u256`: 32 bytes;
- `b256`: 32 bytes;

### Arrays

Arrays are encoded without any padding or alignment, with one item after the other.

- [T; 1] is encoded [encode(T)];
- [T; 2] is encoded [encode(T), encode(T)]

### Strings

String arrays are encoded just like arrays, without any overhead.

- `str[1]` = 1 byte
- `str[2]` = 2 bytes
- `str[n]` = `n` bytes

String slices do contain their length as u64, and the string itself is encoded packed without alignment or padding.

- `"abc"` = `[0, 0, 0, 0, 0, 0, 0, 3, "a", "b", "c"]`

### Slices

`raw_slice`, also being dynamic, contains their length as u64 and is treated as a "slice of bytes". Each byte is encoded as `u8` (1 byte) and is packed without alignment and padding.

For example, a slice of three bytes like `[0u8, 1u8, 2u8]` will be encoded as bytes `[0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2]`

### Tuple

Tuples are encoded just like arrays, without any overhead like padding and alignment:

- `(A, B, C)` = `[encode(A), encode(B), encode(C)]`

### Structs (v1)

Structs can be encoded in two ways:

- first, with the automatic implementation;
- second, with the custom implementation.

Auto implementation follows the same rules as tuples. So we can imagine that

```sway
struct S {
    a: A,
    b: B,
    c: C
}
```

is encoded the same way as the tuple `(A, B, C)`.

Custom implementation allows the developer to choose how a struct is encoded.

A struct has auto-implemented encoding if no custom was found.

### Enums

`Enums` can also be encoded with the automatic or the custom implementation.

The auto implementation first encoded the variant with a `u64` number starting from zero as the first variant and increments this value for each variant, following declaration order.

```sway
enum E {
    VARIANT_A: A, // <- variant 0
    VARIANT_B: B, // <- variant 1
    VARIANT_C: C  // <- variant 2 
}
```

will be encoded as `[encode(variant), encode(value)]`.

The variant data will be encoded right after the variant tag, without any alignment or padding.

An enum has auto-implemented encoding if no custom was found.

### Data Structures

Some common data structures also have well-defined encoding:

- `Vec` will be encoded as `[encode(length), <encode each item>]`
- `Bytes` will be encoded as `[encode(length), <bytes>]`
- `String` will be encoded as `[encode (length), <data>]`

All of them first contain the length and then their data right after, without any padding or alignment.


---

### File: docs/fuel-specs/src/abi/fn-selector-encoding.md

# Function Selector Encoding

To select which function you want to call, first, this function must be in an ABI struct of a Sway program. For instance:

```rust
abi MyContract {
    fn foo(a: u64);
    fn bar(a: InputStruct );
} {
    fn baz(a: ()) { }
}
```

The function selector is the first 4 bytes of the SHA-256 hash function of the signature of the Sway function being called. Then, these 4 bytes are right-aligned to 8 bytes, left-padded with zeroes.

> **Note**: The word size for the FuelVM is 8 bytes.

## Function Signature

The signature is composed of the function name with the parenthesized list of comma-separated parameter types without spaces. All strings encoded with UTF-8. For custom types such as `enum` and `struct`, there is a prefix added to the parenthesized list (see below). Generic `struct` and `enum` types also accept a list of comma-separated type arguments in between angle brackets right after the prefix.

For instance, to compute the selector for the following function:

```rust
    fn entry_one(arg: u64);
```

we should pass `"entry_one(u64)"` to the `sha256()` hashing algorithm. The full digest would be:

```text
0x0c36cb9cb766ff60422db243c4fff06d342949da3c64a3c6ac564941f84b6f06
```

Then we would get only the first 4 bytes of this digest and left-pad it to 8 bytes:

```text
0x000000000c36cb9c
```

The table below summarizes how each function argument type is encoded

| Type       | Encoding                                                                                                                                                                    |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bool`     | `bool`                                                                                                                                                                      |
| `u8`       | `u8`                                                                                                                                                                        |
| `u16`      | `u16`                                                                                                                                                                       |
| `u32`      | `u32`                                                                                                                                                                       |
| `u64`      | `u64`                                                                                                                                                                       |
| `b256`     | `b256`                                                                                                                                                                      |
| `struct`   | `s<<arg1>,<arg2>,...>(<ty1>,<ty2>,...)` where `<ty1>`, `<ty2>`, ... are the encoded types of the struct fields and `<arg1>`, `<arg2>`, ... are the encoded type arguments   |
| `enum`     | `e<<arg1>>,<arg_2>,...>(<ty1>,<ty2>,...)` where `<ty1>`, `<ty2>`, ... are the encoded types of the enum variants and `<arg1>`, `<arg2>`, ... are the encoded type arguments |
| `str[<n>]` | `str[<n>]`                                                                                                                                                                  |
| `array`    | `a[<ty>;<n>]` where `<ty>` is the encoded element type of the array and `<n>` is its length                                                                                 |
| `tuple`    | `(<ty1>,<ty2>,...)` where `<ty1>`, `<ty2>`, ... are the encoded types of the tuple fields                                                                                   |

> **Note:** Non-generic structs and enums do not require angle brackets.

## A Complex Example

```rust
enum MyEnum<V> {
    Foo: u64,
    Bar: bool,
}
struct MyStruct<T, U> {
    bim: T,
    bam: MyEnum<u64>,
}

struct MyOtherStruct {
    bom: u64,
}

fn complex_function(
    arg1: MyStruct<[b256; 3], u8>,
    arg2: [MyStruct<u64, bool>; 4],
    arg3: (str[5], bool),
    arg4: MyOtherStruct,
);
```

is encoded as:

```text
abi MyContract {
    complex_function(s<a[b256;3],u8>(a[b256;3],e<u64>(u64,bool)),a[s<u64,bool>(u64,e<u64>(u64,bool));4],(str[5],bool),s(u64))
}
```

which is then hashed into:

```text
51fdfdadc37ff569e281a622281af7ec055f8098c40bc566118cbb48ca5fd28b
```

and then the encoded function selector is:

```text
0x0000000051fdfdad
```


---

### File: docs/fuel-specs/src/abi/hash-based-ids.md

# Hash based IDs

Hash based ids are deterministically generated from associated types and are used in the JSON ABI for `type` IDs and for `logId`.
This document specifies how the hash based IDS are generated for `type` IDs and for `logId`.

## Generation

Hash based ids for `type` IDs are generated from the `sha256` of a string that represents the type.

For `logIds` we use the first 8 bytes of the `sha256` of a string that represents the type, this is because the `LOG` and `LOGD` opcodes use a 64bit value as log id.

## String representation of types

For describing the string representation of type we will use the notation `{abi_str(T)}` that should be replaced by the respective ABI string representation of the respective type `T`.

### Intrinsics

 `u8`   => `"u8"`
 `u16`  => `"u16"`
 `u32`  => `"u32"`
 `u64`  => `"u64"`
 `u256` => `"u256"`
 `b256` => `"b256"`
 `bool` => `"bool"`

### String arrays

  String array of size `1` => `"str[1]"`
  String array of size `2` => `"str[2]"`
  etc.

### String slices

  String slice => `"str"`

### Arrays

 `[T; 1]` => `"[{abi_str(T)}; 1]"`
 `[T; 2]` => `"[{abi_str(T)}; 2]"`
etc.

### Tuples

 `()`      => `"()"`
 `(T1)`    => `"({abi_str(T1)})"`
 `(T1,T2)` => `"({abi_str(T1)}, {abi_str(T2)})"`
etc.

### Enums

  `Option` enum with type parameter `T` => `"enum std::option::Option<{abi_str(T)}>"`
  Enum without type parameters named `MyEnum` => `"enum MyEnum"`
  Enum with type parameter `T1` named `MyEnum` => `"enum MyEnum<{abi_str(T1)}>"`
  Enum with type parameters `T1`, `T2` named `MyEnum` in `my_module` => `"enum my_module::MyEnum<{abi_str(T1)},{abi_str(T2)}>"`

### Structs

  `Vec` struct with type parameter `T` => `"struct std::vec::Vec<{abi_str(T)}>"`
  Struct without type parameters named `MyStruct` => `"struct MyStruct"`
  Struct with type parameter `T1` named `MyStruct` => `"struct MyStruct<{abi_str(T1)}>"`
  Struct with type parameters `T1`, `T2` named `MyStruct` in `my_module` => `"struct my_module::MyStruct<{abi_str(T1)},{abi_str(T2)}>"`

### Generic Type Parameter

 Generic type parameter `T` if root type => `"generic T"`
 Generic type parameter `T` if not root type => `"T"` as in `"struct MyStruct<T>"`

### Complex examples composition

 Tuple of array and `u64` => `"([u64,1]; u64)"`
 Array of `Option<u64>`=> `"[enum std::option::Option<u64>; 3]"`
 Struct with tuple type parameter => `"struct my_module::MyStruct<(u64, u64)>"`


---

### File: docs/fuel-specs/src/abi/index.md

# Application Binary Interface (ABI)

This document describes and specifies the ABI (Application Binary Interface) of the FuelVM, the Sway programming language, and contracts written in Sway.

- [JSON ABI Format](./json-abi-format.md)
- [Receipts](./receipts.md)
- [Function Selector Encoding](./fn-selector-encoding.md)
- [Argument Encoding](./argument-encoding.md)
- [Hash Based Ids](./hash-based-ids.md)


---

### File: docs/fuel-specs/src/abi/json-abi-format.md

# JSON ABI Format

The JSON of an ABI is the human-readable representation of the interface of a Sway contract.

## Spec Version

Current `specVersion` is `1.0`

The version above should be updated each time this spec changes and the JSON ABI generator should be updated with the new changes along with an increment in the spec version.

## Notation

Before describing the format of the JSON ABI, we provide some definitions that will make the JSON ABI spec easier to read.

Given the example below:

```rust
struct Foo { x: bool }
struct Bar<T> { y: T }

fn baz(input1: Foo, input2: Bar<u64>); // an ABI function
```

we define the following expressions:

- _type concrete declaration_: the declaration or definition of a type which can be generic. `struct Foo { .. }` and `struct Bar<T> { .. }` in the example above are both type declarations. Note that generic types may have multiple _type concrete declaration_.
- _type metadata declaration_: the declaration or definition of a type which can be generic. `struct Foo { .. }` and `struct Bar<T> { .. }` in the example above are both type declarations. The metadata declaration contains component details about the type. And a single _type metadata declaration_ is generated per type, even for generic types.
- _type application_: the application or use of a type. `Foo` and `Bar<u64>` in `fn baz(input1: Foo, input2: Bar<u64>);` in the example above are both applications of the type declarations `struct Foo { .. }` and `struct Bar<T> { .. }` respectively.
- _type parameter_: a generic parameter used in a type declaration. `T` in `struct Bar<T>` in the example above is a type parameter.
- _type argument_: an application of a type parameter used in a type application. `u64` in `input2: Bar<u64>` in the example above is a type argument.

## JSON ABI Spec

The ABI of a contract is represented as a JSON object containing the following properties:

- `"specVersion"`: a string representing the version pointing to this document versioning. `specVersion` enables the reader of the JSON ABI to find the correct specification for that file, this can be done by comparing it to value in [spec version](#spec-version).
- `"encodingVersion"`: a string representing the version of the `ABIEncode` and `ABIDecode` used in this program.
- `"programType"`: a string that can be `"script"`, `"contract"`, `"predicate"`, `"library"`. This is used by the SDK to generate types without having to manually specify the program type.
- `"concreteTypes"`: an array describing all the _type concrete declarations_ used (or transitively used) in the ABI. Each _type concrete declaration_ is a JSON object that contains the following properties:
  - `"type"`: a string representing the type, the `sha256` of this string generates the `concreteTypeId`.
  - `"concreteTypeId"`: a unique string hash based ID. Generated as specified in [Hash Based Ids](./hash-based-ids.md).
  - `"metadataTypeId"`: the _type metadata declaration_ ID of this type, if the type metadata has components or is generic, otherwise nonexistent.
  - `"typeArguments"`: an array of _type concrete declarations_ hash based IDs of the type parameters of the type, if the type is generic, otherwise nonexistent.
- `"metadataTypes"`: an array describing all the _type metadata declarations_ used (or transitively used) in the ABI. Each _type metadata declaration_ is a JSON object that contains the following properties:
  - `"type"`: a string representation of the _type metadata declaration_. The section [JSON ABI Format for Each Possible Metadata Type Declaration](#json-abi-format-for-each-possible-metadata-type-declaration) specifies the format for each possible type.
  - `"metadataTypeId"`: a unique integer ID.
  - `"components"`: an array of the components of a given type, if any, otherwise nonexistent. Each component is a _type application_ represented as a JSON object that contains the following properties:
    - `"name"`: the name of the component.
    - `"typeId"`: the _type metadata declaration_ ID (number) or _type concrete declaration_ hash based ID (string) of the type of the component.
    - `"typeArguments"`: an array of the _type arguments_ used when applying the type of the component, if the type is generic, otherwise nonexistent. Each _type argument_ is a _type application_ represented as a JSON object that contains the following properties:
      - `"name"`: the name of the _type argument_.
      - `"typeId"`: the _type metadata declaration_ ID (number) or _type concrete declaration_ hash based ID (string) of the type of the component.
      - `"typeArguments"`: an array of the _type arguments_ used when applying the type of the _type argument_, if the type is generic, otherwise nonexistent. The format of the elements of this array recursively follows the rules described in this section.
  - `"typeParameters"`: an array of _type metadata declaration_ ID of the _type parameters_ of the type, if the type is generic, otherwise nonexistent. Each _type parameter_ is a type declaration and is represented as described in [Generic Type Parameter](#generic-type-parameter).
- `"functions`": an array describing all the functions in the ABI. Each function is a JSON object that contains the following properties:
  - `"name"`: the name of the function
  - `"inputs"`: an array of objects that represents the inputs to the function (i.e. its parameters). Each input is a _type application_ represented as a JSON object that contains the following properties:
    - `"name"`: the name of the input.
    - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the type of the input.
  - `"output"`: the _type concrete declaration_ hash based ID of the type being returned by the function.
  - `"attributes"`: an optional array of _attributes_. Each _attribute_ is explained in the [dedicated section](#attributes-semantics) and is represented as a JSON object that contains the following properties:
    - `"name"`: the name of the attribute.
    - `"arguments"`: an array of attribute arguments.
- `"loggedTypes"`: an array describing all instances of [`log`](../fuel-vm/instruction-set.md#log-log-event) or [`logd`](../fuel-vm/instruction-set.md#logd-log-data-event) in the contract's bytecode. Each instance is a JSON object that contains the following properties:
  - `"logId"`: a string containing the 64bit hash based decimal ID calculated from the first 8 bytes of the `sha256` of a string that represents the type logged as defined in [Hash Based Ids](./hash-based-ids.md). The [`log`](../fuel-vm/instruction-set.md#log-log-event) and [`logd`](../fuel-vm/instruction-set.md#logd-log-data-event) instructions must set their `$rB` register to that ID.
  - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the value being logged.
- `"messagesTypes"`: an array describing all instances of [`smo`](../fuel-vm/instruction-set.md#smo-send-message-to-output) in the contract's bytecode. Each instance is a JSON object that contains the following properties:
  - `"messageId"`: a unique string ID.
  - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the message data being sent.
- `"configurables"`: an array describing all `configurable` variables used in the contract. Each `configurable` variable is represented as a JSON object that contains the following properties:
  - `"name"`: the name of the `configurable` variable.
  - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the type of the `configurable` variable.
  - `"offset"`: the specific offset within the contract's bytecode, in bytes, to the data section entry for the `configurable` variable.

> **Note**: This JSON should be both human-readable and parsable by the tooling around the FuelVM and the Sway programming language. There is a detailed specification for the binary encoding backing this readable descriptor. The [Function Selector Encoding](./fn-selector-encoding.md) section specifies the encoding for the function being selected to be executed and each of the argument types.

### Attributes Semantics

| Attribute name | Attribute arguments               | Semantics                                                                                              |
|----------------|-----------------------------------|--------------------------------------------------------------------------------------------------------|
| `storage`      | `read` and/or `write`             | Specifies if a function reads or writes to/from storage                                                |
| `payable`      | None                              | Specifies if a function can accept coins: a function without `payable` attribute must not accept coins |
| `test`         | None                              | Specifies if a function is a unit test                                                                 |
| `inline`       | `never` or `always`, but not both | Specifies if a function should be inlined during code generation                                       |
| `doc-comment`  | String                            | Documentation comment                                                                                  |
| `doc`          | Not defined yet                   | Not defined yet                                                                                        |

## A Simple Example

Below is a simple example showing how the JSON ABI for an example that does not use generic or complex types. We will later go over more complex examples.

```rust
abi MyContract {
    fn first_function(arg: u64) -> bool;
    fn second_function(arg: b256);
}
```

the JSON representation of this ABI looks like:

```json
{
  "concreteTypes": [
    {
      "type": "u64",
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    },
    {
      "type": "b256",
      "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
    },
    {
      "type": "bool",
      "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "metadataTypes": [],
  "functions": [
    {
      "inputs": [
        {
          "name": "arg",
          "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
        }
      ],
      "name": "first_function",
      "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
    },
    {
      "inputs": [
        {
          "name": "arg",
          "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
        }
      ],
      "name": "second_function",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "loggedTypes": []
}
```

## JSON ABI Format for Each Possible Metadata Type Declaration

Below is a list of the JSON ABI formats for each possible metadata type declaration:

### `struct`

```json
{
  "metadataTypeId": <id>,
  "type": "struct <struct_name>",
  "components": [
    {
      "name": "<field1_name>",
      "typeId": "<field1_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    {
      "name": "<field2_name>",
      "typeId": "<field2_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    ...
  ],
  "typeParameters": [
    <type_param1_type_id>,
    <type_param2_type_id>,
    ...
  ]
}
```

### `enum`

```json
{
  "metadataTypeId": <id>,
  "type": "enum <enum_name>",
  "components": [
    {
      "name": "<variant1_name>",
      "typeId": "<variant1_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    {
      "name": "<variant2_name>",
      "typeId": "<variant2_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    ...
  ],
  "typeParameters": [
    <type_param1_type_id>,
    <type_param2_type_id>,
    ...
  ]
}
```

### `array`

```json
{
  "metadataTypeId": <id>,
  "type": "[_; <n>]",
  "components": [
    {
      "name": "__array_element",
      "typeId": "<element_type>",
      "typeArguments": ...
    }
    {
      "name": "__array_element",
      "typeId": "<element_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
  ]
}
```

- `<n>` is the size of the array.

### `tuple`

```json
{
  "metadataTypeId": <id>,
  "type": "(_, _, ...)",
  "components": [
    {
      "name": "__tuple_element",
      "typeId": "<field1_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    {
      "name": "__tuple_element",
      "typeId": "<field2_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    ...
  ]
}
```

### Generic Type Parameter

```json
{
  "metadataTypeId": <id>,
  "type": "generic <name>"
}
```

`<name>` is the name of the generic parameter as specified in the struct or enum declaration that uses it.

## Some Complex Examples

### An Example with Non-Generic Custom Types

Given the following ABI declaration:

```rust
enum MyEnum {
    Foo: u64,
    Bar: bool,
}

struct MyStruct {
    bim: u64,
    bam: MyEnum,
}

abi MyContract {
    /// this is a doc comment
    #[payable, storage(read, write)]
    fn complex_function(
        arg1: ([str[5]; 3], bool, b256),
        arg2: MyStruct,
    );
}
```

its JSON representation would look like:

```json
{
  "concreteTypes": [
    {
      "type": "([str[5]; 3], bool, b256)",
      "concreteTypeId": "625531542be70834dd127e771101ac1014111718451bfae996d97abe700c66a5",
      "metadataTypeId": 1,
    },
    {
      "type": "str[5]",
      "concreteTypeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7",
    },
    {
      "type": "struct MyStruct",
      "concreteTypeId": "392d58c694d2d91f3025f2bccfadacf2a105936f5da881b0899185d49f264522",
      "metadataTypeId": 4,
    },
    {
      "type": "u64",
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    },
    {
      "type": "b256",
      "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
    },
    {
      "type": "bool",
      "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "metadataTypes": [
    {
      "metadataTypeId": 1,
      "type": "(_, _, _)",
      "components": [
        {
          "name": "__tuple_element",
          "typeId": 2,
        },
        {
          "name": "__tuple_element",
          "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
        },
        {
          "name": "__tuple_element",
          "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b",
        }
      ]
    },
    {
      "metadataTypeId": 2,
      "type": "[_; 3]",
      "components": [
        {
          "name": "__array_element",
          "typeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7",
        }
      ]
    },
    {
      "metadataTypeId": 3,
      "type": "enum MyEnum",
      "components": [
        {
          "name": "Foo",
          "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
        },
        {
          "name": "Bar",
          "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
        }
      ]
    },
    {
      "metadataTypeId": 4,
      "type": "struct MyStruct",
      "components": [
        {
          "name": "bim",
          "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
        },
        {
          "name": "bam",
          "typeId": 3,
        }
      ]
    },
  ],
  "functions": [
    {
      "inputs": [
        {
          "name": "arg1",
          "concreteTypeId": "625531542be70834dd127e771101ac1014111718451bfae996d97abe700c66a5",
        },
        {
          "name": "arg2",
          "concreteTypeId": "392d58c694d2d91f3025f2bccfadacf2a105936f5da881b0899185d49f264522"
        }
      ],
      "name": "complex_function",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d",
      "attributes": [
        {
          "name": "doc-comment",
          "arguments": [" this is a doc comment"]
        },
        {
          "name": "payable",
        },
        {
          "name": "storage",
          "arguments": ["read", "write"]
        }
      ]
    }
  ],
  "loggedTypes": []
}
```

### An Example with Generic Types

Given the following ABI declaration:

```rust
enum MyEnum<T, U> {
    Foo: T,
    Bar: U,
}
struct MyStruct<W> {
    bam: MyEnum<W, W>,
}

abi MyContract {
    fn complex_function(
        arg1: MyStruct<b256>,
    );
}
```

its JSON representation would look like:

```json
{
  "concreteTypes": [
    {
      "type": "struct MyStruct<b256>",
      "concreteTypeId": "3ddd5c1768dd7869663dc2f868ea8a8ce68bd6064244dbc4286e2c921c8ce962",
      "metadataTypeId": 5,
      "typeArguments": [
        "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
      ]
    },
    {
      "type": "b256",
      "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b",
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d",
    }
  ],
  "metadataTypes": [
    {
      "metadataTypeId": 1,
      "type": "enum MyEnum",
      "components": [
        {
          "name": "Foo",
          "typeId": 2,
        },
        {
          "name": "Bar",
          "typeId": 3,
        }
      ],
      "typeParameters": [2, 3]
    },
    {
      "metadataTypeId": 2,
      "type": "generic T",
    },
    {
      "metadataTypeId": 3,
      "type": "generic U",
    },
    {
      "metadataTypeId": 4,
      "type": "generic W",
    },
    {
      "metadataTypeId": 5,
      "type": "struct MyStruct",
      "components": [
        {
          "name": "bam",
          "typeId": 1,
          "typeArguments": [
            {
              "typeId": 4,
            },
            {
              "typeId": 4,
            }
          ]
        }
      ],
      "typeParameters": [4]
    }
  ],
  "functions": [
    {
      "inputs": [
        {
          "name": "arg1",
          "concreteTypeId": "3ddd5c1768dd7869663dc2f868ea8a8ce68bd6064244dbc4286e2c921c8ce962"
        }
      ],
      "name": "complex_function",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "loggedTypes": []
}
```

### An Example with Logs

Given the following contract:

```rust
struct MyStruct<W> {
    x: W,
}

abi MyContract {
    fn logging();
}

...

fn logging() {
    log(MyStruct { x: 42 });
    log(MyStruct { x: true });
}
```

its JSON representation would look like:

```json
{
  "concreteTypes": [
    {      
      "type": "struct MyStruct<bool>",
      "concreteTypeId": "eca2a040ce95fc19b7cd5f75bac530d052484d0b1a49267a2eb07a7a1b00c389",
      "metadataTypeId": 1,
      "typeArguments": [
        "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
      ]
    },
    {      
      "type": "struct MyStruct<u64>",
      "concreteTypeId": "b2fa346d9ca66ceca61951a27dba2977b2a82b8aa8600670604f286a1393dffe",
      "metadataTypeId": 1,
      "typeArguments": [
        "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
      ]
    },
    {      
      "type": "bool",
      "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
    },
    {      
      "type": "u64",
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d",
    }
  ],
  "metadataTypes": [
    {
      "metadataTypeId": 1,
      "type": "struct MyStruct",
      "components": [
        {
          "name": "x",
          "typeId": 2,
          "typeArguments": null
        }
      ],
      "typeParameters": [2]
    },
    {
      "metadataTypeId": 2,
      "type": "generic W",
    },
  ],
  "functions": [
    {
      "inputs": [],
      "name": "logging",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "loggedTypes": [
    {
      "logId": "12896678128313068780",
      "concreteTypeId": "b2fa346d9ca66ceca61951a27dba2977b2a82b8aa8600670604f286a1393dffe"
    },
    {
      "logId": "16383228984366451899",
      "concreteTypeId": "eca2a040ce95fc19b7cd5f75bac530d052484d0b1a49267a2eb07a7a1b00c389"
    }
  ]
}
```

The `logIds` are calculated from:

- First 8 bytes of `sha256("struct MyStruct<u64>")` => "12896678128313068780"
- First 8 bytes of `sha256("struct MyStruct<bool>")` => "16383228984366451899"


---

### File: docs/fuel-specs/src/abi/receipts.md

# Receipts

Upon execution of ABI calls, i.e scripts being executed, a JSON object representing a list of receipts will be returned to the caller. Below is the JSON specification of the possible receipt types. The root will be `receipts_root` which will include an array of `receipts`.

```json
{
  "receipts_list":[
    {
      "type":"<receipt_type>",
      ...
    },
    ...
  ]
}
```

All receipts will have a `type` property:

- `type`: String; the type of the receipt. Can be one of:
  - [`Call`](#call-receipt)
  - [`Return`](#return-receipt)
  - [`ReturnData`](#returndata-receipt)
  - [`Panic`](#panic-receipt)
  - [`Revert`](#revert-receipt)
  - [`Log`](#log-receipt)
  - [`Mint`](#mint-receipt)
  - [`Burn`](#burn-receipt)
  - [`LogData`](#logdata-receipt)
  - [`Transfer`](#transfer-receipt)
  - [`TransferOut`](#transferout-receipt)
  - [`ScriptResult`](#scriptresult-receipt)
  - [`MessageOut`](#messageout-receipt)

Then, each receipt type will have its own properties. Some of these properties are related to the FuelVM's registers, as specified in more detail [here](../fuel-vm/instruction-set.md).

_Important note:_ For the JSON representation of receipts, we represent 64-bit unsigned integers as a JSON `String` due to limitations around the type `Number` in the JSON specification, which only supports numbers up to `2^{53-1}`, while the FuelVM's registers hold values up to `2^64`.

## Panic Receipt

- `type`: `Panic`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `reason`: Optional decimal string representation of an 8-bit unsigned integer; panic reason.
  Not included in canonical receipt form.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.
- `contractId`: Optional hexadecimal string representation of the 256-bit (32-byte) contract ID if applicable. `null` otherwise.
  Not included in canonical receipt form. Primary use is for access-list estimation by SDK.

```json
{
  "type": "Panic",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "reason": "1",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe",
  "contractId": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
```

## `Return` Receipt

- `type`: `Return`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context; `null` otherwise.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Return",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "18446744073709551613",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Call` Receipt

- `type`: `Call`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context; `null` otherwise.
- `to`: Hexadecimal representation of the 256-bit (32-byte) contract ID of the callee.
- `amount`: Decimal string representation of a 64-bit unsigned integer; amount of coins to forward.
- `asset_id`: Hexadecimal string representation of the 256-bit (32-byte) asset ID of coins to forward.
- `gas`: Decimal string representation of a 64-bit unsigned integer; amount gas to forward; value in register `$rD`.
- `param1`: Hexadecimal string representation of a 64-bit unsigned integer; first parameter, holds the function selector.
- `param2`: Hexadecimal string representation of a 64-bit unsigned integer; second parameter, typically used for the user-specified input to the ABI function being selected.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Call",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "to": "0x1c98ff5d121a6d5afc8135821acb3983e460ef0590919266d620bfc7b9b6f24d",
  "amount": "10000",
  "asset_id": "0xa5149ac6064222922eaa226526b0d853e7871e28c368f6afbcfd60a6ef8d6e61",
  "gas": "500",
  "param1": "0x28f5c28f5c28f5c",
  "param2": "0x68db8bac710cb",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Log` Receipt

- `type`: `Log`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `ra`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `rb`: Decimal string representation of a 64-bit unsigned integer; value of register `$rB`.
- `rc`: Decimal string representation of a 64-bit unsigned integer; value of register `$rC`.
- `rd`: Decimal string representation of a 64-bit unsigned integer; value of register `$rD`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Log",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "ra": "1844674407370",
  "rb": "1844674407371",
  "rc": "1844674407372",
  "rd": "1844674407373",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Mint` Receipt

- `type`: `Mint`.
- `sub_id`: Hexadecimal string representation of the 256-bit (32-byte) asset sub identifier ID; derived from register `$rB`.
- `contract_id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Mint",
  "sub_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "contract_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "18446744073709551613",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Burn` Receipt

- `type`: `Burn`.
- `sub_id`: Hexadecimal string representation of the 256-bit (32-byte) asset sub identifier ID; derived from register `$rB`.
- `contract_id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Burn",
  "sub_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "contract_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "18446744073709551613",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `LogData` Receipt

- `type`: `LogData`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `ra`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`
- `rb`: Decimal string representation of a 64-bit unsigned integer; value of register `$rB`
- `ptr`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$rC`.
- `len`: Decimal string representation of a 64-bit unsigned integer; value of register `$rD`.
- `digest`: Hexadecimal string representation of the 256-bit (32-byte) hash of `MEM[$rC, $rD]`.
- `data`: Hexadecimal string representation of the value of the memory range `MEM[$rC, $rD]`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "LogData",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "ra": "1844674407370",
  "rb": "1844674407371",
  "ptr": "0x1ad7f29abcc",
  "len": "66544",
  "digest": "0xd28b78894e493c98a196aa51b432b674e4813253257ed9331054ee8d6813b3aa",
  "pc": "0xffffffffffffffff",
  "data": "0xa7c5ac471b47",
  "is": "0xfffffffffffffffe"
}
```

## `ReturnData` Receipt

- `type`: `ReturnData`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `ptr`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `len`: Decimal string representation of a 64-bit unsigned integer; value of register `$rB`.
- `digest`: Hexadecimal string representation of 256-bit (32-byte), hash of `MEM[$rA, $rB]`.
- `data`: Hexadecimal string representation of the value of the memory range `MEM[$rA, $rB]`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "ReturnData",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "ptr": "0x1ad7f29abcc",
  "len": "1844",
  "digest": "0xd28b78894e493c98a196aa51b432b674e4813253257ed9331054ee8d6813b3aa",
  "pc": "0xffffffffffffffff",
  "data": "0xa7c5ac471b47",
  "is": "0xfffffffffffffffe"
}
```

## `Revert` Receipt

- `type`: `Revert`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Revert",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "1844674407372",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Transfer` Receipt

- `type`: `Transfer`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `to`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the recipient contract.
- `amount`: Decimal string representation of a 64-bit unsigned integer; amount of coins to forward.
- `asset_id`: Hexadecimal string representation of the 256-bit (32-byte) asset ID of coins to forward.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Transfer",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "to": "0x1c98ff5d121a6d5afc8135821acb3983e460ef0590919266d620bfc7b9b6f24d",
  "amount": "10000",
  "asset_id": "0xa5149ac6064222922eaa226526b0d853e7871e28c368f6afbcfd60a6ef8d6e61",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `TransferOut` Receipt

- `type`: `TransferOut`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `to`: Hexadecimal string representation of the 256-bit (32-byte) _address_ to transfer coins to.
- `amount`: Decimal string representation of a 64-bit unsigned integer; amount of coins to forward.
- `asset_id`: Hexadecimal string representation of the 256-bit (32-byte) asset ID of coins to forward.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "TransferOut",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "to": "0x1c98ff5d121a6d5afc8135821acb3983e460ef0590919266d620bfc7b9b6f24d",
  "amount": "10000",
  "asset_id": "0xa5149ac6064222922eaa226526b0d853e7871e28c368f6afbcfd60a6ef8d6e61",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `ScriptResult` Receipt

- `type`: `ScriptResult`.
- `result`: Hexadecimal string representation of a 64-bit unsigned integer; `0` if script exited successfully, `any` otherwise.
- `gas_used`: Decimal string representation of a 64-bit unsigned integer; amount of gas consumed by the script.

```json
{
  "type": "ScriptResult",
  "result": "0x00",
  "gas_used": "400"
}
```

## `MessageOut` Receipt

- `type`: `MessageOut`.
- `sender`: Hexadecimal string representation of the 256-bit (32-byte) address of the message sender: `MEM[$fp, 32]`.
- `recipient`: Hexadecimal string representation of the 256-bit (32-byte) address of the message recipient: `MEM[$rA, 32]`.
- `amount`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$rD`.
- `nonce`: Hexadecimal string representation of the 256-bit (32-byte) message nonce as described [here](../identifiers/utxo-id.md#message-nonce).
- `len`: Decimal string representation of a 16-bit unsigned integer; value of register `$rC`.
- `digest`: Hexadecimal string representation of 256-bit (32-byte), hash of `MEM[$rB, $rC]`.
- `data`: Hexadecimal string representation of the value of the memory range `MEM[$rB, $rC]`.

```json
{
  "type": "MessageOut",
  "sender": "0x38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff05139150017c9e",
  "recipient": "0x4710162c2e3a95a6faff05139150017c9e38e5e280432d546fae345d6ce6d8fe",
  "amount": "0xe6d8fe4710162c2e",
  "nonce": "0x47101017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "len": "65535",
  "digest": "0xd28b78894e493c98a196aa51b432b674e4813253257ed9331054ee8d6813b3aa",
  "data": "0xa7c5ac471b47"
}
```


---

### File: docs/fuel-specs/src/fuel-vm/index.md

# Fuel VM Specification

- [Introduction](#introduction)
- [Parameters](#parameters)
- [Semantics](#semantics)
- [Flags](#flags)
- [Instruction Set](#instruction-set)
- [VM Initialization](#vm-initialization)
- [Contexts](#contexts)
  - [Predicate Estimation and Verification](#predicate-estimation-and-verification)
  - [Script Execution](#script-execution)
  - [Call](#call)
- [Call Frames](#call-frames)
- [Ownership](#ownership)

## Introduction

This document provides the specification for the Fuel Virtual Machine (FuelVM). The specification covers the types, instruction set, and execution semantics.

## Parameters

| name                    | type     | value   | note                                    |
|-------------------------|----------|---------|-----------------------------------------|
| `CONTRACT_MAX_SIZE`     | `uint64` |         | Maximum contract size, in bytes.        |
| `VM_MAX_RAM`            | `uint64` | `2**26` | 64 MiB.                                 |
| `MESSAGE_MAX_DATA_SIZE` | `uint64` |         | Maximum size of message data, in bytes. |

## Semantics

FuelVM instructions are exactly 32 bits (4 bytes) wide and comprise of a combination of:

- Opcode: 8 bits
- Register/special register (see below) identifier: 6 bits
- Immediate value: 12, 18, or 24 bits, depending on operation

Of the 64 registers (6-bit register address space), the first `16` are reserved:

| value  | register | name                | description                                                                      |
|--------|----------|---------------------|----------------------------------------------------------------------------------|
| `0x00` | `$zero`  | zero                | Contains zero (`0`), for convenience.                                            |
| `0x01` | `$one`   | one                 | Contains one (`1`), for convenience.                                             |
| `0x02` | `$of`    | overflow            | Contains overflow/underflow of addition, subtraction, and multiplication.        |
| `0x03` | `$pc`    | program counter     | The program counter. Memory address of the current instruction.                  |
| `0x04` | `$ssp`   | stack start pointer | Memory address of bottom of current writable stack area.                         |
| `0x05` | `$sp`    | stack pointer       | Memory address on top of current writable stack area (points to free memory).    |
| `0x06` | `$fp`    | frame pointer       | Memory address of beginning of current call frame.                               |
| `0x07` | `$hp`    | heap pointer        | Memory address below the current bottom of the heap (points to used/OOB memory). |
| `0x08` | `$err`   | error               | Error codes for particular operations.                                           |
| `0x09` | `$ggas`  | global gas          | Remaining gas globally.                                                          |
| `0x0A` | `$cgas`  | context gas         | Remaining gas in the context.                                                    |
| `0x0B` | `$bal`   | balance             | Received balance for this context.                                               |
| `0x0C` | `$is`    | instructions start        | Pointer to the start of the currently-executing code.                            |
| `0x0D` | `$ret`   | return value        | Return value or pointer.                                                         |
| `0x0E` | `$retl`  | return length       | Return value length in bytes.                                                    |
| `0x0F` | `$flag`  | flags               | Flags register.                                                                  |

Integers are represented in [big-endian](https://en.wikipedia.org/wiki/Endianness) format, and all operations are unsigned. Boolean `false` is `0` and Boolean `true` is `1`.

Registers are 64 bits (8 bytes) wide. Words are the same width as registers.

Persistent state (i.e. storage) is a key-value store with 32-byte keys and 32-byte values. Each contract has its own persistent state that is independent of other contracts. This is committed to in a Sparse Binary Merkle Tree.

## Flags

| value  | name           | description                                                               |
|--------|----------------|---------------------------------------------------------------------------|
| `0x01` | `F_UNSAFEMATH` | If set, undefined arithmetic zeroes target and sets `$err` without panic. |
| `0x02` | `F_WRAPPING`   | If set, overflowing arithmetic wraps around and sets `$of` without panic. |

All other flags are reserved, any must be set to zero.

## Instruction Set

A complete instruction set of the Fuel VM is documented in [the following page](./instruction-set.md).

## VM Initialization

Every time the VM runs, a single monolithic memory of size `VM_MAX_RAM` bytes is allocated, indexed by individual byte. A stack and heap memory model is used, allowing for dynamic memory allocation in higher-level languages. The stack begins at `0` and grows upward. The heap begins at `VM_MAX_RAM` and grows downward.

To initialize the VM, the following is pushed on the stack sequentially:

1. Transaction hash (`byte[32]`, word-aligned), computed as defined [here](../identifiers/transaction-id.md).
1. Base asset ID (`byte[32]`, word-aligned)
1. [`MAX_INPUTS`](../tx-format/consensus_parameters.md) pairs of `(asset_id: byte[32], balance: uint64)`, of:
    1. For [predicate estimation and verification](#predicate-estimation-and-verification), zeroes.
    1. For [script execution](#script-execution), the free balance for each asset ID seen in the transaction's inputs, ordered in ascending order. If there are fewer than `MAX_INPUTS` asset IDs, the pair has a value of zero.
1. Transaction length, in bytes (`uint64`, word-aligned).
1. The [transaction, serialized](../tx-format/index.md).

Then the following registers are initialized (without explicit initialization, all registers are initialized to zero):

1. `$ssp = 32 + 32 + MAX_INPUTS*(32+8) + size(tx))`: the writable stack area starts immediately after the serialized transaction in memory (see above).
1. `$sp = $ssp`: writable stack area is empty to start.
1. `$hp = VM_MAX_RAM`: the heap area begins at the top and is empty to start.

## Contexts

There are 4 _contexts_ in the FuelVM: [predicate estimation and verification](#predicate-estimation-and-verification), [scripts](#script-execution), and [calls](#call). A context is an isolated execution environment with defined [memory ownership](#ownership) and can be _external_ or _internal_:

- External: predicate and script. `$fp` will be zero.
- Internal: call. `$fp` will be non-zero.

[Returning](./instruction-set.md#return-return-from-call) from a context behaves differently depending on whether the context is external or internal.

### Predicate Estimation and Verification

There are two ways to run predicates on the VM:

1. Estimation: runs the predicate and updates the amount of gas used
1. Verification: runs the predicate and verifies the amount of gas used matches the input

For any input of type [`InputType.Coin`](../tx-format/input.md#inputcoin) or [`InputType.Message`](../tx-format/input.md#inputmessage), a non-zero `predicateLength` field means the UTXO being spent is a [`P2SH`](https://en.bitcoin.it/P2SH) rather than a [`P2PKH`](https://en.bitcoin.it/P2PKH) output.

For each such input in the transaction, the VM is [initialized](#vm-initialization), then:

1. `$pc` and `$is` are set to the start of the input's `predicate` field.
1. `$ggas` and `$cgas` are set to `MAX_GAS_PER_PREDICATE` for estimation, and `predicateGasUsed` for verification.

Predicate execution will fail if gas is exhausted during execution.

During predicate mode, hitting any [contract instruction](./instruction-set.md#contract-instructions) (except `ldc` with non-contract target) causes predicate verification to halt, returning Boolean `false`.

A predicate that halts without returning Boolean `true` would not pass verification, making the entire transaction invalid. Note that predicate return value is monotonic with respect to time (i.e. if a predicate evaluates to `true` then it will always evaluate to `true` in the future).

After successful execution, the run mode is determines the final step:

1. Estimation: `predicateGasUsed` is set to `MAX_GAS_PER_PREDICATE - $ggas`.
1. Verification: if `$ggas` is non-zero, predicate verification fails.

### Script Execution

If script bytecode is present, transaction validation requires execution.

The VM is [initialized](#vm-initialization), then:

1. `$pc` and `$is` are set to the start of the transaction's script bytecode.
1. `$ggas` and `$cgas` are set to `tx.scriptGasLimit`.

Following initialization, execution begins.

For each instruction, its gas cost `gc` is first computed. If `gc > $cgas`, deduct `$cgas` from `$ggas` and `$cgas` (i.e. spend all of `$cgas` and no more), then [revert](./instruction-set.md#rvrt-revert) immediately without actually executing the instruction. Otherwise, deduct `gc` from `$ggas` and `$cgas`.

After the script has been executed, `tx.receiptsRoot` is updated to contain the Merkle root of the receipts, [as described in the `TransactionScript` spec](../tx-format/transaction.md#`TransactionScript`).

### Call

Call context is entered via [`CALL` instruction](./instruction-set.md#call-call-contract). It's also called _internal context_, or _contract context_. Call context is used to access state of a contract.

## Call Frames

Cross-contract calls push a _call frame_ onto the stack, similar to a stack frame used in regular languages for function calls (which may be used by a high-level language that targets the FuelVM). The distinction is as follows:

1. Stack frames: store metadata across trusted internal (i.e. intra-contract) function calls. Not supported natively by the FuelVM, but may be used as an abstraction at a higher layer.
1. Call frames: store metadata across untrusted external (i.e. inter-contract) calls. Supported natively by the FuelVM.

Call frames are needed to ensure that the called contract cannot mutate the running state of the current executing contract. They segment access rights for memory: the currently-executing contracts may only write to their own call frame and their own heap.

A call frame consists of the following, word-aligned:

| bytes | type          | value      | description                                                                   |
|-------|---------------|------------|-------------------------------------------------------------------------------|
|       |               |            | **Unwritable area begins.**                                                   |
| 32    | `byte[32]`    | `to`       | Contract ID for this call.                                                    |
| 32    | `byte[32]`    | `asset_id` | asset ID of forwarded coins.                                                  |
| 8*64  | `byte[8][64]` | `regs`     | Saved registers from previous context.                                        |
| 8     | `uint64`      | `codesize` | Code size in bytes, padded to the next word boundary.                         |
| 8     | `byte[8]`     | `param1`   | First parameter.                                                              |
| 8     | `byte[8]`     | `param2`   | Second parameter.                                                             |
| 1*    | `byte[]`      | `code`     | Zero-padded to 8-byte alignment, but individual instructions are not aligned. |
|       |               |            | **Unwritable area ends.**                                                     |
| *     |               |            | Call frame's stack.                                                           |

## Access rights

Only memory that has been allocated is accessible.
In other words, memory between highest-ever `$sp` value and current `$hp`
is inaccessible. Attempting to read or write
memory that has not been allocated will result in VM panic.
Similarly reads or writes that cross from the stack to the heap
will panic. Note that stack remains readable even after stack
frame has been shrunk. However, if the heap is afterwards expanded
to cover that area, the crossing read prohibition still remains,
while all memory is accessible.

### Ownership

Whenever memory is written to (i.e. with [`SB`](./instruction-set.md#sb-store-byte) or [`SW`](./instruction-set.md#sw-store-word)), or write access is granted (i.e. with [`CALL`](./instruction-set.md#call-call-contract)), ownership must be checked.

If the context is external, the owned memory range is:

1. `[$ssp, $sp)`: the writable stack area.
1. `[$hp, VM_MAX_RAM)`: the heap area allocated by this script or predicate.

If the context is internal, the owned memory range for a call frame is:

1. `[$ssp, $sp)`: the writable stack area of the call frame.
1. `[$hp, $fp->$hp)`: the heap area allocated by this call frame.

### Executability

Memory is only executable in range `[$is, $ssp)`. Attempting to execute instructions outside these boundaries will cause a panic. This area never overlaps with writable memory, essentially providing [W^X](https://en.wikipedia.org/wiki/W%5EX) protection.


---

### File: docs/fuel-specs/src/fuel-vm/instruction-set.md

# FuelVM Instruction Set

- [Reading Guide](#reading-guide)
- [Arithmetic/Logic (ALU) Instructions](#arithmeticlogic-alu-instructions)
  - [`ADD`: Add](#add-add)
  - [`ADDI`: Add immediate](#addi-add-immediate)
  - [`AND`: AND](#and-and)
  - [`ANDI`: AND immediate](#andi-and-immediate)
  - [`DIV`: Divide](#div-divide)
  - [`DIVI`: Divide immediate](#divi-divide-immediate)
  - [`EQ`: Equals](#eq-equals)
  - [`EXP`: Exponentiate](#exp-exponentiate)
  - [`EXPI`: Exponentiate immediate](#expi-exponentiate-immediate)
  - [`GT`: Greater than](#gt-greater-than)
  - [`LT`: Less than](#lt-less-than)
  - [`MLOG`: Math logarithm](#mlog-math-logarithm)
  - [`MOD`: Modulus](#mod-modulus)
  - [`MODI`: Modulus immediate](#modi-modulus-immediate)
  - [`MOVE`: Move](#move-move)
  - [`MOVI`: Move immediate](#movi-move-immediate)
  - [`MROO`: Math root](#mroo-math-root)
  - [`MUL`: Multiply](#mul-multiply)
  - [`MULI`: Multiply immediate](#muli-multiply-immediate)
  - [`MLDV`: Fused multiply-divide](#mldv-fused-multiply-divide)
  - [`NIOP`: Narrow integer operation](#niop-narrow-integer-operation)
  - [`NOOP`: No operation](#noop-no-operation)
  - [`NOT`: Invert](#not-invert)
  - [`OR`: OR](#or-or)
  - [`ORI`: OR immediate](#ori-or-immediate)
  - [`SLL`: Shift left logical](#sll-shift-left-logical)
  - [`SLLI`: Shift left logical immediate](#slli-shift-left-logical-immediate)
  - [`SRL`: Shift right logical](#srl-shift-right-logical)
  - [`SRLI`: Shift right logical immediate](#srli-shift-right-logical-immediate)
  - [`SUB`: Subtract](#sub-subtract)
  - [`SUBI`: Subtract immediate](#subi-subtract-immediate)
  - [`WDCM`: 128-bit integer comparison](#wdcm-128-bit-integer-comparison)
  - [`WQCM`: 256-bit integer comparison](#wqcm-256-bit-integer-comparison)
  - [`WDOP`: Misc 128-bit integer operations](#wdop-misc-128-bit-integer-operations)
  - [`WQOP`: Misc 256-bit integer operations](#wqop-misc-256-bit-integer-operations)
  - [`WDML`: Multiply 128-bit integers](#wdml-multiply-128-bit-integers)
  - [`WQML`: Multiply 256-bit integers](#wqml-multiply-256-bit-integers)
  - [`WDDV`: 128-bit integer division](#wddv-128-bit-integer-division)
  - [`WQDV`: 256-bit integer division](#wqdv-256-bit-integer-division)
  - [`WDMD`: 128-bit integer fused multiply-divide](#wdmd-128-bit-integer-fused-multiply-divide)
  - [`WQMD`: 256-bit integer fused multiply-divide](#wqmd-256-bit-integer-fused-multiply-divide)
  - [`WDAM`: Modular 128-bit integer addition](#wdam-modular-128-bit-integer-addition)
  - [`WQAM`: Modular 256-bit integer addition](#wqam-modular-256-bit-integer-addition)
  - [`WDMM`: Modular 128-bit integer multiplication](#wdmm-modular-128-bit-integer-multiplication)
  - [`WQMM`: Modular 256-bit integer multiplication](#wqmm-modular-256-bit-integer-multiplication)
  - [`XOR`: XOR](#xor-xor)
  - [`XORI`: XOR immediate](#xori-xor-immediate)
- [Control Flow Instructions](#control-flow-instructions)
  - [`JMP`: Jump](#jmp-jump)
  - [`JI`: Jump immediate](#ji-jump-immediate)
  - [`JNE`: Jump if not equal](#jne-jump-if-not-equal)
  - [`JNEI`: Jump if not equal immediate](#jnei-jump-if-not-equal-immediate)
  - [`JNZI`: Jump if not zero immediate](#jnzi-jump-if-not-zero-immediate)
  - [`JMPB`: Jump relative backwards](#jmpb-jump-relative-backwards)
  - [`JMPF`: Jump relative forwards](#jmpf-jump-relative-forwards)
  - [`JNZB`: Jump if not zero relative backwards](#jnzb-jump-if-not-zero-relative-backwards)
  - [`JNZF`: Jump if not zero relative forwards](#jnzf-jump-if-not-zero-relative-forwards)
  - [`JNEB`: Jump if not equal relative backwards](#jneb-jump-if-not-equal-relative-backwards)
  - [`JNEF`: Jump if not equal relative forwards](#jnef-jump-if-not-equal-relative-forwards)
  - [`RET`: Return from context](#ret-return-from-context)
- [Memory Instructions](#memory-instructions)
  - [`ALOC`: Allocate memory](#aloc-allocate-memory)
  - [`CFE`: Extend call frame](#cfe-extend-call-frame)
  - [`CFEI`: Extend call frame immediate](#cfei-extend-call-frame-immediate)
  - [`CFS`: Shrink call frame](#cfs-shrink-call-frame)
  - [`CFSI`: Shrink call frame immediate](#cfsi-shrink-call-frame-immediate)
  - [`LB`: Load byte](#lb-load-byte)
  - [`LQW`: Load quarter word](#lqw-load-quarter-word)
  - [`LHW`: Load half word](#lhw-load-half-word)
  - [`LW`: Load word](#lw-load-word)
  - [`MCL`: Memory clear](#mcl-memory-clear)
  - [`MCLI`: Memory clear immediate](#mcli-memory-clear-immediate)
  - [`MCP`: Memory copy](#mcp-memory-copy)
  - [`MCPI`: Memory copy immediate](#mcpi-memory-copy-immediate)
  - [`MEQ`: Memory equality](#meq-memory-equality)
  - [`POPH`: Pop a set of high registers from stack](#poph-pop-a-set-of-high-registers-from-stack)
  - [`POPL`: Pop a set of low registers from stack](#popl-pop-a-set-of-low-registers-from-stack)
  - [`PSHH`: Push a set of high registers to stack](#pshh-push-a-set-of-high-registers-to-stack)
  - [`PSHL`: Push a set of low registers to stack](#pshl-push-a-set-of-low-registers-to-stack)
  - [`SB`: Store byte](#sb-store-byte)
  - [`SQW`: Store quarter word](#sqw-store-quarter-word)
  - [`SHW`: Store half word](#shw-store-half-word)
  - [`SW`: Store word](#sw-store-word)
- [Contract Instructions](#contract-instructions)
  - [`BAL`: Balance of contract ID](#bal-balance-of-contract-id)
  - [`BHEI`: Block height](#bhei-block-height)
  - [`BHSH`: Block hash](#bhsh-block-hash)
  - [`BURN`: Burn existing coins](#burn-burn-existing-coins)
  - [`CALL`: Call contract](#call-call-contract)
  - [`CB`: Coinbase contract id](#cb-coinbase-contract-id)
  - [`CCP`: Code copy](#ccp-code-copy)
  - [`CROO`: Code Merkle root](#croo-code-merkle-root)
  - [`CSIZ`: Code size](#csiz-code-size)
  - [`LDC`: Load code from an external contract, blob or memory](#ldc-load-code-from-an-external-contract-blob-or-memory)
  - [`LOG`: Log event](#log-log-event)
  - [`LOGD`: Log data event](#logd-log-data-event)
  - [`MINT`: Mint new coins](#mint-mint-new-coins)
  - [`RETD`: Return from context with data](#retd-return-from-context-with-data)
  - [`RVRT`: Revert](#rvrt-revert)
  - [`SMO`: Send message to output](#smo-send-message-out)
  - [`SCWQ`: State clear sequential 32 byte slots](#scwq-state-clear-sequential-32-byte-slots)
  - [`SRW`: State read word](#srw-state-read-word)
  - [`SRWQ`: State read sequential 32 byte slots](#srwq-state-read-sequential-32-byte-slots)
  - [`SWW`: State write word](#sww-state-write-word)
  - [`SWWQ`: State write sequential 32 byte slots](#swwq-state-write-sequential-32-byte-slots)
  - [`TIME`: Timestamp at height](#time-timestamp-at-height)
  - [`TR`: Transfer coins to contract](#tr-transfer-coins-to-contract)
  - [`TRO`: Transfer coins to output](#tro-transfer-coins-to-output)
- [Blob Instructions](#blob-instructions)
  - [`BSIZ`: Blob size](#bsiz-blob-size)
  - [`BLDD`: Load data from a blob](#bldd-load-data-from-a-blob)
- [Cryptographic Instructions](#cryptographic-instructions)
  - [`ECK1`: Secp251k1 signature recovery](#eck1-secp256k1-signature-recovery)
  - [`ECR1`: Secp256r1 signature recovery](#ecr1-secp256r1-signature-recovery)
  - [`ED19`: EdDSA curve25519 verification](#ed19-eddsa-curve25519-verification)
  - [`K256`: keccak-256](#k256-keccak-256)
  - [`S256`: SHA-2-256](#s256-sha-2-256)
  - [`ECOP`: Elliptic curve operation](#ecop-elliptic-curve-point-operation)
  - [`EPAR`: Elliptic curve point pairing check](#epar-elliptic-curve-point-pairing-check)
- [Other Instructions](#other-instructions)
  - [`ECAL`: Call external function](#ecal-call-external-function)
  - [`FLAG`: Set flags](#flag-set-flags)
  - [`GM`: Get metadata](#gm-get-metadata)
  - [`GTF`: Get transaction fields](#gtf-get-transaction-fields)

## Reading Guide

This page provides a description of all instructions for the FuelVM. Encoding is read as a sequence of one 8-bit value (the opcode identifier) followed by four 6-bit values (the register identifiers or immediate value). A single `i` indicates a 6-bit immediate value, `i i` indicates a 12-bit immediate value, `i i i` indicates an 18-bit immediate value, and `i i i i` indicates a 24-bit immediate value. All immediate values are interpreted as big-endian unsigned integers. If the instruction would be shorter than the full 32 bits, the remaining part is reserved and must be zero.

- The syntax `MEM[x, y]` used in this page means the memory range starting at byte `x`, of length `y` bytes.
- The syntax `STATE[x, y]` used in this page means the sequence of storage slots starting at key `x` and spanning `y` bytes.

### Panics

Some instructions may _panic_, i.e. enter an unrecoverable state. Additionally, attempting to execute an instruction not in this list causes a panic and consumes no gas. Instructions with reserved part having a non-zero value will likewise panic.  How a panic is handled depends on [context](./index.md#contexts):

- In a predicate context, cease VM execution and return `false`.
- In other contexts, revert (described below).

On a non-predicate panic, append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Panic`                                                       |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

then append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `1`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

### Receipts

The number of receipts is limited to 2<sup>16</sup>, with the last two reserved to panic and script result receipts. Trying to add any other receipts after 2<sup>16</sup>-2 will panic.

### Effects

A few instructions are annotated with the _effects_ they produce, the table below explains each effect:

| effect name        | description                                        |
|--------------------|----------------------------------------------------|
| Storage read       | Instruction reads from storage slots               |
| Storage write      | Instruction writes to storage slots                |
| External call      | External contract call instruction                 |
| Balance tree read  | Instruction reads from the balance tree            |
| Balance tree write | Instruction writes to the balance tree             |
| Output message     | Instruction sends a message to a recipient address |

If an instruction is not annotated with an effect, it means it does not produce any of the aforementioned affects.

## Arithmetic/Logic (ALU) Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

Normally, if the result of an ALU operation is mathematically undefined (e.g. dividing by zero),
the VM panics. However, if the [`F_UNSAFEMATH`](./index.md#flags) flag is set, `$err` is set to `true`
and execution continues.

If an operation would overflow, so that the result doesn't fit into the target field, the VM will panic.
Results below zero are also considered overflows. If the [`F_WRAPPING`](./index.md#flags) flag is set,
instead `$of` is set to `true` or the overflowing part of the result, depending on the operation.

### `ADD`: Add

|             |                        |
|-------------|------------------------|
| Description | Adds two registers.    |
| Operation   | ```$rA = $rB + $rC;``` |
| Syntax      | `add $rA, $rB, $rC`    |
| Encoding    | `0x00 rA rB rC -`      |
| Notes       |                        |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `ADDI`: Add immediate

|             |                                         |
|-------------|-----------------------------------------|
| Description | Adds a register and an immediate value. |
| Operation   | ```$rA = $rB + imm;```                  |
| Syntax      | `addi $rA, $rB, immediate`              |
| Encoding    | `0x00 rA rB i i`                        |
| Notes       |                                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `AND`: AND

|             |                             |
|-------------|-----------------------------|
| Description | Bitwise ANDs two registers. |
| Operation   | ```$rA = $rB & $rC;```      |
| Syntax      | `and $rA, $rB, $rC`         |
| Encoding    | `0x00 rA rB rC -`           |
| Notes       |                             |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `ANDI`: AND immediate

|             |                                                 |
|-------------|-------------------------------------------------|
| Description | Bitwise ANDs a register and an immediate value. |
| Operation   | ```$rA = $rB & imm;```                          |
| Syntax      | `andi $rA, $rB, imm`                            |
| Encoding    | `0x00 rA rB i i`                                |
| Notes       |                                                 |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`imm` is extended to 64 bits, with the high 52 bits set to `0`.

`$of` and `$err` are cleared.

### `DIV`: Divide

|             |                         |
|-------------|-------------------------|
| Description | Divides two registers.  |
| Operation   | ```$rA = $rB // $rC;``` |
| Syntax      | `div $rA, $rB, $rC`     |
| Encoding    | `0x00 rA rB rC -`       |
| Notes       |                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rC == 0`, `$rA` is cleared and `$err` is set to `true`.

Otherwise, `$err` is cleared.

`$of` is cleared.

### `DIVI`: Divide immediate

|             |                                            |
|-------------|--------------------------------------------|
| Description | Divides a register and an immediate value. |
| Operation   | ```$rA = $rB // imm;```                    |
| Syntax      | `divi $rA, $rB, imm`                       |
| Encoding    | `0x00 rA rB i i`                           |
| Notes       |                                            |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `imm == 0`, `$rA` is cleared and `$err` is set to `true`.

Otherwise, `$err` is cleared.

`$of` is cleared.

### `EQ`: Equals

|             |                                      |
|-------------|--------------------------------------|
| Description | Compares two registers for equality. |
| Operation   | ```$rA = $rB == $rC;```              |
| Syntax      | `eq $rA, $rB, $rC`                   |
| Encoding    | `0x00 rA rB rC -`                    |
| Notes       |                                      |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `EXP`: Exponentiate

|             |                                              |
|-------------|----------------------------------------------|
| Description | Raises one register to the power of another. |
| Operation   | ```$rA = $rB ** $rC;```                      |
| Syntax      | `exp $rA, $rB, $rC`                          |
| Encoding    | `0x00 rA rB rC -`                            |
| Notes       |                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If the result cannot fit in 8 bytes, `$of` is set to `1` and `$rA` is instead set to `0`, otherwise `$of` is cleared.

`$err` is cleared.

### `EXPI`: Exponentiate immediate

|             |                                                         |
|-------------|---------------------------------------------------------|
| Description | Raises one register to the power of an immediate value. |
| Operation   | ```$rA = $rB ** imm;```                                 |
| Syntax      | `expi $rA, $rB, imm`                                    |
| Encoding    | `0x00 rA rB i i`                                        |
| Notes       |                                                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If the result cannot fit in 8 bytes, `$of` is set to `1` and `$rA` is instead set to `0`, otherwise `$of` is cleared.

`$err` is cleared.

### `GT`: Greater than

|             |                                          |
|-------------|------------------------------------------|
| Description | Compares two registers for greater-than. |
| Operation   | ```$rA = $rB > $rC;```                   |
| Syntax      | `gt $rA, $rB, $rC`                       |
| Encoding    | `0x00 rA rB rC -`                        |
| Notes       |                                          |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `LT`: Less than

|             |                                       |
|-------------|---------------------------------------|
| Description | Compares two registers for less-than. |
| Operation   | ```$rA = $rB < $rC;```                |
| Syntax      | `lt $rA, $rB, $rC`                    |
| Encoding    | `0x00 rA rB rC -`                     |
| Notes       |                                       |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `MLOG`: Math logarithm

|             |                                              |
|-------------|----------------------------------------------|
| Description | The (integer) logarithm base `$rC` of `$rB`. |
| Operation   | ```$rA = math.floor(math.log($rB, $rC));```  |
| Syntax      | `mlog $rA, $rB, $rC`                         |
| Encoding    | `0x00 rA rB rC -`                            |
| Notes       |                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rB == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

If `$rC <= 1`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MOD`: Modulus

|             |                                    |
|-------------|------------------------------------|
| Description | Modulo remainder of two registers. |
| Operation   | ```$rA = $rB % $rC;```             |
| Syntax      | `mod $rA, $rB, $rC`                |
| Encoding    | `0x00 rA rB rC -`                  |
| Notes       |                                    |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rC == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MODI`: Modulus immediate

|             |                                                        |
|-------------|--------------------------------------------------------|
| Description | Modulo remainder of a register and an immediate value. |
| Operation   | ```$rA = $rB % imm;```                                 |
| Syntax      | `modi $rA, $rB, imm`                                   |
| Encoding    | `0x00 rA rB i i`                                       |
| Notes       |                                                        |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `imm == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MOVE`: Move

|             |                                    |
|-------------|------------------------------------|
| Description | Copy from one register to another. |
| Operation   | ```$rA = $rB;```                   |
| Syntax      | `move $rA, $rB`                    |
| Encoding    | `0x00 rA rB - -`                   |
| Notes       |                                    |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `MOVI`: Move immediate

|             |                                          |
|-------------|------------------------------------------|
| Description | Copy an immediate value into a register. |
| Operation   | ```$rA = imm;```                         |
| Syntax      | `movi $rA, imm`                          |
| Encoding    | `0x00 rA i i i`                          |
| Notes       |                                          |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `MROO`: Math root

|             |                                              |
|-------------|----------------------------------------------|
| Description | The (integer) `$rCth` root of `$rB`.         |
| Operation   | ```$rA = math.floor(math.root($rB, $rC));``` |
| Syntax      | `mroo $rA, $rB, $rC`                         |
| Encoding    | `0x00 rA rB rC -`                            |
| Notes       |                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rC == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MUL`: Multiply

|             |                           |
|-------------|---------------------------|
| Description | Multiplies two registers. |
| Operation   | ```$rA = $rB * $rC;```    |
| Syntax      | `mul $rA, $rB, $rC`       |
| Encoding    | `0x00 rA rB rC -`         |
| Notes       |                           |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `MULI`: Multiply immediate

|             |                                               |
|-------------|-----------------------------------------------|
| Description | Multiplies a register and an immediate value. |
| Operation   | ```$rA = $rB * imm;```                        |
| Syntax      | `mul $rA, $rB, imm`                           |
| Encoding    | `0x00 rA rB i i`                              |
| Notes       |                                               |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `MLDV`: Fused multiply-divide

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Multiplies two registers with arbitrary precision, then divides by a third register. |
| Operation   | `a = (b * c) / d;`                                                                   |
| Syntax      | `mldv $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       | Division by zero is treated as division by `1 << 64` instead.                        |

If the divisor (`$rD`) is zero, then instead the value is divided by `1 << 64`. This returns the higher half of the 128-bit multiplication result. This operation never overflows.

If the result of after the division doesn't fit into a register, `$of` is assigned the overflow of the operation. Otherwise, `$of` is cleared.

`$err` is cleared.

### `NIOP`: Narrow integer operation

|             |                                                                                     |
|-------------|-------------------------------------------------------------------------------------|
| Description | Perform an ALU operation with overflow handing for 8, 16 or 32 bit integers         |
| Operation   | `$rA = op($rB,$rC);`                                                                |
| Syntax      | `niop $rA, $rB, $rC, imm`                                                           |
| Encoding    | `0x00 rA rB rC i`                                                                   |
| Notes       | Operations that would be identical with their 64-bit counterparts are not available |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`..XXXX` | `op`       | Operation selection, see below
`XX....` | `width`    | Operation width, see below

Then the actual operation that's performed:

`op` | Name | Description
-----|-------|---------------------------
0    | `add` | Add (`a = b + c`)
1    | `mul` | Multiply (`a = b * c`)
2    | `exp` | Exponentiate (`a = b ** c`)
3    | `sll` | Bit shift left (logical) (`a = b << c`)
4    | `xnor`| Bitwise xnor (`a = b ^ (!c)`).
other| -     | Reserved and must not be used

And operation width:

`width`| Bits
-------|------
0      | 8
1      | 16
2      | 32
3      | Reserved and must not be used

All operations first truncate their operands to the given bit width,
then perform the operation with overflow checking on that size. The
result always fits within the bit width of the operation.

Operations set `$of` and `$err` similarly to their 64-bit counterparts.
`XNOR` has no counterpart, and it always clears both `$of` and `$err`.

Panic if:

- Reserved bits of the immediate are set
- `$rA` is a [reserved register](./index.md#semantics)

### `NOOP`: No operation

|             |                        |
|-------------|------------------------|
| Description | Performs no operation. |
| Operation   |                        |
| Syntax      | `noop`                 |
| Encoding    | `0x00 - - - -`         |
| Notes       |                        |

`$of` and `$err` are cleared.

### `NOT`: Invert

|             |                         |
|-------------|-------------------------|
| Description | Bitwise NOT a register. |
| Operation   | ```$rA = ~$rB;```       |
| Syntax      | `not $rA, $rB`          |
| Encoding    | `0x00 rA rB - -`        |
| Notes       |                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `OR`: OR

|             |                            |
|-------------|----------------------------|
| Description | Bitwise ORs two registers. |
| Operation   | ```$rA = $rB \| $rC;```    |
| Syntax      | `or $rA, $rB, $rC`         |
| Encoding    | `0x00 rA rB rC -`          |
| Notes       |                            |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `ORI`: OR immediate

|             |                                                |
|-------------|------------------------------------------------|
| Description | Bitwise ORs a register and an immediate value. |
| Operation   | ```$rA = $rB \| imm;```                        |
| Syntax      | `ori $rA, $rB, imm`                            |
| Encoding    | `0x00 rA rB i i`                               |
| Notes       |                                                |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`imm` is extended to 64 bits, with the high 52 bits set to `0`.

`$of` and `$err` are cleared.

### `SLL`: Shift left logical

|             |                                       |
|-------------|---------------------------------------|
| Description | Left shifts a register by a register. |
| Operation   | ```$rA = $rB << $rC;```               |
| Syntax      | `sll $rA, $rB, $rC`                   |
| Encoding    | `0x00 rA rB rC -`                     |
| Notes       | Zeroes are shifted in.                |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SLLI`: Shift left logical immediate

|             |                                               |
|-------------|-----------------------------------------------|
| Description | Left shifts a register by an immediate value. |
| Operation   | ```$rA = $rB << imm;```                       |
| Syntax      | `slli $rA, $rB, imm`                          |
| Encoding    | `0x00 rA rB i i`                              |
| Notes       | Zeroes are shifted in.                        |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SRL`: Shift right logical

|             |                                        |
|-------------|----------------------------------------|
| Description | Right shifts a register by a register. |
| Operation   | ```$rA = $rB >> $rC;```                |
| Syntax      | `srl $rA, $rB, $rC`                    |
| Encoding    | `0x00 rA rB rC -`                      |
| Notes       | Zeroes are shifted in.                 |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SRLI`: Shift right logical immediate

|             |                                                |
|-------------|------------------------------------------------|
| Description | Right shifts a register by an immediate value. |
| Operation   | ```$rA = $rB >> imm;```                        |
| Syntax      | `srli $rA, $rB, imm`                           |
| Encoding    | `0x00 rA rB i i`                               |
| Notes       | Zeroes are shifted in.                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SUB`: Subtract

|             |                                                  |
|-------------|--------------------------------------------------|
| Description | Subtracts two registers.                         |
| Operation   | ```$rA = $rB - $rC;```                           |
| Syntax      | `sub $rA, $rB, $rC`                              |
| Encoding    | `0x00 rA rB rC -`                                |
| Notes       |                                                  |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the underflow of the operation, as though `$of` is the high byte of a 128-bit register.

`$err` is cleared.

### `SUBI`: Subtract immediate

|             |                                                  |
|-------------|--------------------------------------------------|
| Description | Subtracts a register and an immediate value.     |
| Operation   | ```$rA = $rB - imm;```                           |
| Syntax      | `subi $rA, $rB, imm`                             |
| Encoding    | `0x00 rA rB i i`                                 |
| Notes       |                                                  |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the underflow of the operation, as though `$of` is the high byte of a 128-bit register.

`$err` is cleared.

### `WDCM`: 128-bit integer comparison

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Compare or examine two 128-bit integers using selected mode                   |
| Operation   | `b = mem[$rB,16];`<br>`c = indirect?mem[$rC,16]:$rC;`<br>`$rA = cmp_op(b,c);` |
| Syntax      | `wdcm $rA, $rB, $rC, imm`                                                     |
| Encoding    | `0x00 rA rB rC i`                                                             |
| Notes       |                                                                               |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`...XXX` | `mode`     | Compare mode selection
`.XX...` | `reserved` | Reserved and must be zero
`X.....` | `indirect` | Is rhs operand (`$rC`) indirect or not

Then the actual operation that's performed:

`mode` | Name | Description
-------|------|-------------------------------------------------------------
0      | `eq`   | Equality (`==`)
1      | `ne`   | Inequality (`!=`)
2      | `lt`   | Less than (`<`)
3      | `gt`   | Greater than (`>`)
4      | `lte`  | Less than or equals (`<=`)
5      | `gte`  | Greater than or equals (`>=`)
6      | `lzc`  | Leading zero count the lhs argument (`lzcnt`). Discards rhs.
7      | -    | Reserved and must not be used

The leading zero count can be used to compute rounded-down log2 of a number using the following formula `TOTAL_BITS - 1 - lzc(n)`. Note that `log2(0)` is undefined, and will lead to integer overflow with this method.

Clears `$of` and `$err`.

Panic if:

- A reserved compare mode is given
- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQCM`: 256-bit integer comparison

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Compare or examine two 256-bit integers using selected mode                   |
| Operation   | `b = mem[$rB,32];`<br>`c = indirect?mem[$rC,32]:$rC;`<br>`$rA = cmp_op(b,c);` |
| Syntax      | `wqcm $rA, $rB, $rC, imm`                                                     |
| Encoding    | `0x00 rA rB rC i`                                                             |
| Notes       |                                                                               |

The immediate value is interpreted identically to `WDCM`.

Clears `$of` and `$err`.

Panic if:

- A reserved compare mode is given
- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDOP`: Misc 128-bit integer operations

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Perform an ALU operation on two 128-bit integers                                  |
| Operation   | `b = mem[$rB,16];`<br>`c = indirect?mem[$rC,16]:$rC;`<br>`mem[$rA,16] = op(b,c);` |
| Syntax      | `wdop $rA, $rB, $rC, imm`                                                         |
| Encoding    | `0x00 rA rB rC i`                                                                 |
| Notes       |                                                                                   |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`...XXX` | `op`       | Operation selection, see below
`.XX...` | `reserved` | Reserved and must be zero
`X.....` | `indirect` | Is rhs operand (`$rC`) indirect or not

Then the actual operation that's performed:

`op` | Name | Description
-----|------|---------------------------
0    | `add`  | Add
1    | `sub`  | Subtract
2    | `not`  | Invert bits (discards rhs)
3    | `or`   | Bitwise or
4    | `xor`  | Bitwise exclusive or
5    | `and`  | Bitwise and
6    | `shl`  | Shift left (logical)
7    | `shr`  | Shift right (logical)

Operations behave `$of` and `$err` similarly to their 64-bit counterparts, except that `$of` is set to `1` instead of the overflowing part.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQOP`: Misc 256-bit integer operations

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Perform an ALU operation on two 256-bit integers                                  |
| Operation   | `b = mem[$rB,32];`<br>`c = indirect?mem[$rC,32]:$rC;`<br>`mem[$rA,32] = op(b,c);` |
| Syntax      | `wqop $rA, $rB, $rC, imm`                                                         |
| Encoding    | `0x00 rA rB rC i`                                                                 |
| Notes       |                                                                                   |

The immediate value is interpreted identically to `WDOP`.

Operations behave `$of` and `$err` similarly to their 64-bit counterparts.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDML`: Multiply 128-bit integers

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Perform integer multiplication operation on two 128-bit integers.                      |
| Operation   | `b=indirect0?mem[$rB,16]:$rB;`<br>`c=indirect1?mem[$rC,16]:$rC;`<br>`mem[$rA,16]=b*c;` |
| Syntax      | `wdml $rA, $rB, $rC, imm`                                                              |
| Encoding    | `0x00 rA rB rC i`                                                                      |
| Notes       |                                                                                        |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name  | Description
---------|-------------|-------------------------------------
`..XXXX` | `reserved`  | Reserved and must be zero
`.X....` | `indirect0` | Is lhs operand (`$rB`) indirect or not
`X.....` | `indirect1` | Is rhs operand (`$rC`) indirect or not

`$of` is set to `1` in case of overflow, and cleared otherwise.

`$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `indirect0 == 1` and `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect1 == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQML`: Multiply 256-bit integers

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Perform integer multiplication operation on two 256-bit integers.                      |
| Operation   | `b=indirect0?mem[$rB,32]:$rB;`<br>`c=indirect1?mem[$rC,32]:$rC;`<br>`mem[$rA,32]=b*c;` |
| Syntax      | `wqml $rA, $rB, $rC, imm`                                                              |
| Encoding    | `0x00 rA rB rC i`                                                                      |
| Notes       |                                                                                        |

The immediate value is interpreted identically to `WDML`.

`$of` is set to `1` in case of overflow, and cleared otherwise.

`$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `indirect0 == 1` and `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect1 == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDDV`: 128-bit integer division

|             |                                                                                 |
|-------------|---------------------------------------------------------------------------------|
| Description | Divide a 128-bit integer by another.                                            |
| Operation   | `b = mem[$rB,16];`<br>`c = indirect?mem[$rC,16]:$rC;`<br>`mem[$rA,16] = b / c;` |
| Syntax      | `wddv $rA, $rB, $rC, imm`                                                       |
| Encoding    | `0x00 rA rB rC i`                                                               |
| Notes       |                                                                                 |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`.XXXXX` | `reserved` | Reserved and must be zero
`X.....` | `indirect` | Is rhs operand (`$rC`) indirect or not

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 16]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQDV`: 256-bit integer division

|             |                                                                                 |
|-------------|---------------------------------------------------------------------------------|
| Description | Divide a 256-bit integer by another.                                            |
| Operation   | `b = mem[$rB,32];`<br>`c = indirect?mem[$rC,32]:$rC;`<br>`mem[$rA,32] = b / c;` |
| Syntax      | `wqdv $rA, $rB, $rC, imm`                                                       |
| Encoding    | `0x00 rA rB rC i`                                                               |
| Notes       |                                                                                 |

The immediate value is interpreted identically to `WDDV`.

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 32]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDMD`: 128-bit integer fused multiply-divide

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Combined multiply-divide of 128-bit integers with arbitrary precision.                 |
| Operation   | `b=mem[$rB,16];`<br>`c=mem[$rC,16];`<br>`d=mem[$rD,16];`<br>`mem[$rA,16]=(b * c) / d;` |
| Syntax      | `wdmd $rA, $rB, $rC, $rD`                                                              |
| Encoding    | `0x00 rA rB rC rD`                                                                     |
| Notes       | Division by zero is treated as division by `1 << 128` instead.                         |

If the divisor `MEM[$rA, 16]` is zero, then instead the value is divided by `1 << 128`. This returns the higher half of the 256-bit multiplication result.

If the result of after the division is larger than operand size, `$of` is set to one. Otherwise, `$of` is cleared.

`$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `$rC + 16` overflows or `> VM_MAX_RAM`
- `$rD + 16` overflows or `> VM_MAX_RAM`

### `WQMD`: 256-bit integer fused multiply-divide

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Combined multiply-divide of 256-bit integers with arbitrary precision.                 |
| Operation   | `b=mem[$rB,32];`<br>`c=mem[$rC,32];`<br>`d=mem[$rD,32];`<br>`mem[$rA,32]=(b * c) / d;` |
| Syntax      | `wqmd $rA, $rB, $rC, $rD`                                                              |
| Encoding    | `0x00 rA rB rC rD`                                                                     |
| Notes       | Division by zero is treated as division by `1 << 256` instead.                         |

If the divisor `MEM[$rA, 32]` is zero, then instead the value is divided by `1 << 256`. This returns the higher half of the 512-bit multiplication result.

If the result of after the division is larger than operand size, `$of` is set to one. Otherwise, `$of` is cleared.

`$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`

### `WDAM`: Modular 128-bit integer addition

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Add two 128-bit integers and compute modulo remainder with arbitrary precision.      |
| Operation   | `b=mem[$rB,16];`<br>`c=mem[$rC,16];`<br>`d=mem[$rD,16];`<br>`mem[$rA,16] = (b+c)%d;` |
| Syntax      | `wdam $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 16]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `$rC + 16` overflows or `> VM_MAX_RAM`
- `$rD + 16` overflows or `> VM_MAX_RAM`

### `WQAM`: Modular 256-bit integer addition

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Add two 256-bit integers and compute modulo remainder with arbitrary precision.      |
| Operation   | `b=mem[$rB,32];`<br>`c=mem[$rC,32];`<br>`d=mem[$rD,32];`<br>`mem[$rA,32] = (b+c)%d;` |
| Syntax      | `wqam $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 32]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`

### `WDMM`: Modular 128-bit integer multiplication

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Multiply two 128-bit integers and compute modulo remainder with arbitrary precision. |
| Operation   | `b=mem[$rB,16];`<br>`c=mem[$rC,16];`<br>`d=mem[$rD,16];`<br>`mem[$rA,16] = (b*c)%d;` |
| Syntax      | `wdmm $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 16]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `$rC + 16` overflows or `> VM_MAX_RAM`
- `$rD + 16` overflows or `> VM_MAX_RAM`

### `WQMM`: Modular 256-bit integer multiplication

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Multiply two 256-bit integers and compute modulo remainder with arbitrary precision. |
| Operation   | `b=mem[$rB,32];`<br>`c=mem[$rC,32];`<br>`d=mem[$rD,32];`<br>`mem[$rA,32] = (b*c)%d;` |
| Syntax      | `wqmm $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 32]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`

### `XOR`: XOR

|             |                             |
|-------------|-----------------------------|
| Description | Bitwise XORs two registers. |
| Operation   | ```$rA = $rB ^ $rC;```      |
| Syntax      | `xor $rA, $rB, $rC`         |
| Encoding    | `0x00 rA rB rC -`           |
| Notes       |                             |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `XORI`: XOR immediate

|             |                                                 |
|-------------|-------------------------------------------------|
| Description | Bitwise XORs a register and an immediate value. |
| Operation   | ```$rA = $rB ^ imm;```                          |
| Syntax      | `xori $rA, $rB, imm`                            |
| Encoding    | `0x00 rA rB i i`                                |
| Notes       |                                                 |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

## Control Flow Instructions

### `JMP`: Jump

|             |                                                     |
|-------------|-----------------------------------------------------|
| Description | Jumps to the code instruction offset by a register. |
| Operation   | ```$pc = $is + $rA * 4;```                          |
| Syntax      | `jmp $rA`                                           |
| Encoding    | `0x00 rA - - -`                                     |
| Notes       |                                                     |

Panic if:

- `$is + $rA * 4 > VM_MAX_RAM - 1`

### `JI`: Jump immediate

|             |                                                |
|-------------|------------------------------------------------|
| Description | Jumps to the code instruction offset by `imm`. |
| Operation   | ```$pc = $is + imm * 4;```                     |
| Syntax      | `ji imm`                                       |
| Encoding    | `0x00 i i i i`                                 |
| Notes       |                                                |

Panic if:

- `$is + imm * 4 > VM_MAX_RAM - 1`

### `JNE`: Jump if not equal

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Jump to the code instruction offset by a register if `$rA` is not equal to `$rB`.    |
| Operation   | ```if $rA != $rB:```<br>```$pc = $is + $rC * 4;```<br>```else:```<br>```$pc += 4;``` |
| Syntax      | `jne $rA $rB $rC`                                                                    |
| Encoding    | `0x00 rA rB rC -`                                                                    |
| Notes       |                                                                                      |

Panic if:

- `$is + $rC * 4 > VM_MAX_RAM - 1` and the jump would be performed (i.e. `$rA != $rB`)

### `JNEI`: Jump if not equal immediate

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Jump to the code instruction offset by `imm` if `$rA` is not equal to `$rB`.         |
| Operation   | ```if $rA != $rB:```<br>```$pc = $is + imm * 4;```<br>```else:```<br>```$pc += 4;``` |
| Syntax      | `jnei $rA $rB imm`                                                                   |
| Encoding    | `0x00 rA rB i i`                                                                     |
| Notes       |                                                                                      |

Panic if:

- `$is + imm * 4 > VM_MAX_RAM - 1` and the jump would be performed (i.e. `$rA != $rB`)

### `JNZI`: Jump if not zero immediate

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Jump to the code instruction offset by `imm` if `$rA` is not equal to `$zero`.         |
| Operation   | ```if $rA != $zero:```<br>```$pc = $is + imm * 4;```<br>```else:```<br>```$pc += 4;``` |
| Syntax      | `jnzi $rA imm`                                                                         |
| Encoding    | `0x00 rA i i i`                                                                        |
| Notes       |                                                                                        |

Panic if:

- `$is + imm * 4 > VM_MAX_RAM - 1`and the jump would be performed (i.e. `$rA != $zero`)

### `JMPB`: Jump relative backwards

|             |                                          |
|-------------|------------------------------------------|
| Description | Jump `$rA + imm` instructions backwards. |
| Operation   | ```$pc -= ($rA + imm + 1) * 4;```        |
| Syntax      | `jmpb $rA imm`                           |
| Encoding    | `0x00 rA i i i`                          |
| Notes       |                                          |

Panic if:

- `$pc - ($rA + imm + 1) * 4 < 0`

### `JMPF`: Jump relative forwards

|             |                                        |
|-------------|----------------------------------------|
| Description | Jump `$rA + imm` instructions forwards |
| Operation   | ```$pc += ($rA + imm + 1) * 4;```      |
| Syntax      | `jmpf $rA imm`                         |
| Encoding    | `0x00 rA i i i`                        |
| Notes       |                                        |

Panic if:

- `$pc + ($rA + imm + 1) * 4 > VM_MAX_RAM - 1`

### `JNZB`: Jump if not zero relative backwards

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Jump `$rB + imm` instructions backwards if `$rA != $zero`.                    |
| Operation   | `if $rA != $zero:`<br>`$pc -= ($rB + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jnzb $rA $rB imm`                                                            |
| Encoding    | `0x00 rA rB i i`                                                              |
| Notes       |                                                                               |

Panic if:

- `$pc - ($rB + imm + 1) * 4 < 0`

### `JNZF`: Jump if not zero relative forwards

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Jump `$rB + imm` instructions forwards if `$rA != $zero`.                     |
| Operation   | `if $rA != $zero:`<br>`$pc += ($rB + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jnzf $rA $rB imm`                                                            |
| Encoding    | `0x00 rA rB i i`                                                              |
| Notes       |                                                                               |

Panic if:

- `$pc + ($rB + imm + 1) * 4 > VM_MAX_RAM - 1`

### `JNEB`: Jump if not equal relative backwards

|             |                                                                             |
|-------------|-----------------------------------------------------------------------------|
| Description | Jump `$rC + imm` instructions backwards if `$rA != $rB`.                    |
| Operation   | `if $rA != $rB:`<br>`$pc -= ($rC + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jneb $rA $rB $rC imm`                                                      |
| Encoding    | `0x00 rA rB rC i`                                                           |
| Notes       |                                                                             |

Panic if:

- `$pc - ($rC + imm + 1) * 4 < 0`

### `JNEF`: Jump if not equal relative forwards

|             |                                                                             |
|-------------|-----------------------------------------------------------------------------|
| Description | Jump `$rC + imm` instructions forwards if `$rA != $rB`.                     |
| Operation   | `if $rA != $rB:`<br>`$pc += ($rC + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jnef $rA $rB $rC imm`                                                      |
| Encoding    | `0x00 rA rB rC i`                                                           |
| Notes       |                                                                             |

Panic if:

- `$pc + ($rC + imm + 1) * 4 > VM_MAX_RAM - 1`

### `RET`: Return from context

|             |                                                               |
|-------------|---------------------------------------------------------------|
| Description | Returns from [context](./index.md#contexts) with value `$rA`. |
| Operation   | ```return($rA);```                                            |
| Syntax      | `ret $rA`                                                     |
| Encoding    | `0x00 rA - - -`                                               |
| Notes       | `$ret` is set to the return value from `$rA`.                 |

Append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Return`                                                      |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val`  | `uint64`      | Value of register `$rA`.                                                  |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

If current context is external, append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `0`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

If current context is external, cease VM execution and return `$rA`.

Returns from contract call, popping the call frame. Before popping perform the following operations.

Return the unused forwarded gas to the caller:

1. `$cgas = $cgas + $fp->$cgas` (add remaining context gas from previous context to current remaining context gas)

Set the return value:

1. `$ret = $rA`
1. `$retl = 0`

Then pop the call frame and restore all registers _except_ `$ggas`, `$cgas`, `$ret`, `$retl` and `$hp`. Afterwards, set the following registers:

1. `$pc = $pc + 4` (advance program counter from where we called)

## Memory Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `ALOC`: Allocate memory

|             |                                           |
|-------------|-------------------------------------------|
| Description | Allocate a number of bytes from the heap. |
| Operation   | ```$hp = $hp - $rA;```                    |
| Syntax      | `aloc $rA`                                |
| Encoding    | `0x00 rA - - -`                           |
| Notes       | Newly allocated memory is zeroed.         |

Panic if:

- `$hp - $rA` underflows
- `$hp - $rA < $sp`

### `CFE`: Extend call frame

|             |                                        |
|-------------|----------------------------------------|
| Description | Extend the current call frame's stack. |
| Operation   | ```$sp = $sp + $rA```                  |
| Syntax      | `cfe $rA`                             |
| Encoding    | `0x00 rA - - -`                        |
| Notes       | Does not initialize memory.            |

Panic if:

- `$sp + $rA` overflows
- `$sp + $rA > $hp`

### `CFEI`: Extend call frame immediate

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | Extend the current call frame's stack by an immediate value. |
| Operation   | ```$sp = $sp + imm```                                        |
| Syntax      | `cfei imm`                                                   |
| Encoding    | `0x00 i i i i`                                               |
| Notes       | Does not initialize memory.                                  |

Panic if:

- `$sp + imm` overflows
- `$sp + imm > $hp`

### `CFS`: Shrink call frame

|             |                                        |
|-------------|----------------------------------------|
| Description | Shrink the current call frame's stack. |
| Operation   | ```$sp = $sp - $rA```                  |
| Syntax      | `cfs $rA`                              |
| Encoding    | `0x00 $rA - - -`                       |
| Notes       | Does not clear memory.                 |

Panic if:

- `$sp - $rA` underflows
- `$sp - $rA < $ssp`

### `CFSI`: Shrink call frame immediate

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | Shrink the current call frame's stack by an immediate value. |
| Operation   | ```$sp = $sp - imm```                                        |
| Syntax      | `cfsi imm`                                                   |
| Encoding    | `0x00 i i i i`                                               |
| Notes       | Does not clear memory.                                       |

Panic if:

- `$sp - imm` underflows
- `$sp - imm < $ssp`

### `LB`: Load byte

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | A byte is loaded from the specified address offset by `imm`. |
| Operation   | ```$rA = MEM[$rB + imm, 1];```                               |
| Syntax      | `lb $rA, $rB, imm`                                           |
| Encoding    | `0x00 rA rB i i`                                             |
| Notes       |                                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + imm + 1` overflows or `> VM_MAX_RAM`

### `LQW`: Load quarter word

|             |                                                                      |
|-------------|----------------------------------------------------------------------|
| Description | A quarter word is loaded from the specified address offset by `imm`. |
| Operation   | ```$rA = MEM[$rB + (imm * 2), 2];```                                 |
| Syntax      | `lqw $rA, $rB, imm`                                                  |
| Encoding    | `0x00 rA rB i i`                                                     |
| Notes       |                                                                      |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + (imm * 2) + 2` overflows or `> VM_MAX_RAM`

### `LHW`: Load half word

|             |                                                                      |
|-------------|----------------------------------------------------------------------|
| Description | A half word is loaded from the specified address offset by `imm`.    |
| Operation   | ```$rA = MEM[$rB + (imm * 4), 4];```                                 |
| Syntax      | `lhw $rA, $rB, imm`                                                  |
| Encoding    | `0x00 rA rB i i`                                                     |
| Notes       |                                                                      |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + (imm * 4) + 4` overflows or `> VM_MAX_RAM`

### `LW`: Load word

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | A word is loaded from the specified address offset by `imm`. |
| Operation   | ```$rA = MEM[$rB + (imm * 8), 8];```                         |
| Syntax      | `lw $rA, $rB, imm`                                           |
| Encoding    | `0x00 rA rB i i`                                             |
| Notes       |                                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + (imm * 8) + 8` overflows or `> VM_MAX_RAM`

### `MCL`: Memory clear

|             |                          |
|-------------|--------------------------|
| Description | Clear bytes in memory.   |
| Operation   | ```MEM[$rA, $rB] = 0;``` |
| Syntax      | `mcl $rA, $rB`           |
| Encoding    | `0x00 rA rB - -`         |
| Notes       |                          |

Panic if:

- `$rA + $rB` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, $rB]`  does not pass [ownership check](./index.md#ownership)

### `MCLI`: Memory clear immediate

|             |                          |
|-------------|--------------------------|
| Description | Clear bytes in memory.   |
| Operation   | ```MEM[$rA, imm] = 0;``` |
| Syntax      | `mcli $rA, imm`          |
| Encoding    | `0x00 rA i i i`          |
| Notes       |                          |

Panic if:

- `$rA + imm` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, imm]`  does not pass [ownership check](./index.md#ownership)

### `MCP`: Memory copy

|             |                                      |
|-------------|--------------------------------------|
| Description | Copy bytes in memory.                |
| Operation   | ```MEM[$rA, $rC] = MEM[$rB, $rC];``` |
| Syntax      | `mcp $rA, $rB, $rC`                  |
| Encoding    | `0x00 rA rB rC -`                    |
| Notes       |                                      |

Panic if:

- `$rA + $rC` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- The memory ranges `MEM[$rA, $rC]` and `MEM[$rB, $rC]` overlap
- The memory range `MEM[$rA, $rC]`  does not pass [ownership check](./index.md#ownership)

### `MCPI`: Memory copy immediate

|             |                                      |
|-------------|--------------------------------------|
| Description | Copy bytes in memory.                |
| Operation   | ```MEM[$rA, imm] = MEM[$rB, imm];``` |
| Syntax      | `mcpi $rA, $rB, imm`                 |
| Encoding    | `0x00 rA rB imm imm`                 |
| Notes       |                                      |

Panic if:

- `$rA + imm` overflows or `> VM_MAX_RAM`
- `$rB + imm` overflows or `> VM_MAX_RAM`
- The memory ranges `MEM[$rA, imm]` and `MEM[$rB, imm]` overlap
- The memory range `MEM[$rA, imm]`  does not pass [ownership check](./index.md#ownership)

### `MEQ`: Memory equality

|             |                                             |
|-------------|---------------------------------------------|
| Description | Compare bytes in memory.                    |
| Operation   | ```$rA = MEM[$rB, $rD] == MEM[$rC, $rD];``` |
| Syntax      | `meq $rA, $rB, $rC, $rD`                    |
| Encoding    | `0x00 rA rB rC rD`                          |
| Notes       |                                             |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + $rD` overflows or `> VM_MAX_RAM`
- `$rC + $rD` overflows or `> VM_MAX_RAM`

### `PSHH`: Push a set of high registers to stack

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Push a set of registers from range 40..64 to the stack in order.                  |
| Operation   | `tmp=$sp;`<br>`$sp+=popcnt(imm)*8;`<br>`MEM[tmp,$sp]=registers[40..64].mask(imm)` |
| Syntax      | `pshh imm`                                                                        |
| Encoding    | `0x00 i i i i`                                                                    |
| Notes       | The immediate value is used as a bitmask for selecting the registers.             |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pushes the register 61 followed by register 62.

Panic if:

- `$sp + popcnt(imm)*8` overflows
- `$sp + popcnt(imm)*8 > $hp`

### `PSHL`: Push a set of low registers to stack

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Push a set of registers from range 16..40 to the stack in order.                  |
| Operation   | `tmp=$sp;`<br>`$sp+=popcnt(imm)*8;`<br>`MEM[tmp,$sp]=registers[16..40].mask(imm)` |
| Syntax      | `pshl imm`                                                                        |
| Encoding    | `0x00 i i i i`                                                                    |
| Notes       | The immediate value is used as a bitmask for selecting the registers.             |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pushes the register 37 followed by register 38.

Panic if:

- `$sp + popcnt(imm)*8` overflows
- `$sp + popcnt(imm)*8 > $hp`

### `POPH`: Pop a set of high registers from stack

|             |                                                                                       |
|-------------|---------------------------------------------------------------------------------------|
| Description | Pop to a set of registers from range 40..64 from the stack.                           |
| Operation   | `tmp=$sp-popcnt(imm)*8;`<br>`registers[40..64].mask(imm)=MEM[tmp,$sp]`<br>`$sp-=tmp;` |
| Syntax      | `poph imm`                                                                            |
| Encoding    | `0x00 i i i i`                                                                        |
| Notes       | The immediate value is used as a bitmask for selecting the registers.                 |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pops the register 62 followed by register 61.

Note that the order is reverse from `PSHH`, so that `PSHH a; POPH a` returns to the original state.

Panic if:

- `$sp - popcnt(imm)*8` overflows
- `$sp - popcnt(imm)*8 < $ssp`

### `POPL`: Pop a set of low registers from stack

|             |                                                                                       |
|-------------|---------------------------------------------------------------------------------------|
| Description | Pop to a set of registers from range 16..40 from the stack.                           |
| Operation   | `tmp=$sp-popcnt(imm)*8;`<br>`registers[16..40].mask(imm)=MEM[tmp,$sp]`<br>`$sp-=tmp;` |
| Syntax      | `poph imm`                                                                            |
| Encoding    | `0x00 i i i i`                                                                        |
| Notes       | The immediate value is used as a bitmask for selecting the registers.                 |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pops the register 38 followed by register 37.

Note that the order is reverse from `PSHL`, so that `PSHL a; POPL a` returns to the original state.

Panic if:

- `$sp - popcnt(imm)*8` overflows
- `$sp - popcnt(imm)*8 < $ssp`

### `SB`: Store byte

|             |                                                                                     |
|-------------|-------------------------------------------------------------------------------------|
| Description | The least significant byte of `$rB` is stored at the address `$rA` offset by `imm`. |
| Operation   | ```MEM[$rA + imm, 1] = $rB[7, 1];```                                                |
| Syntax      | `sb $rA, $rB, imm`                                                                  |
| Encoding    | `0x00 rA rB i i`                                                                    |
| Notes       |                                                                                     |

Panic if:

- `$rA + imm + 1` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA + imm, 1]`  does not pass [ownership check](./index.md#ownership)

### `SQW`: Store quarter word

|             |                                                                                               |
|-------------|-----------------------------------------------------------------------------------------------|
| Description | The two least significant bytes of  of `$rB` is stored at the address `$rA` offset by `imm`.  |
| Operation   | ```MEM[$rA + (imm * 2), 2] = $rB;```                                                          |
| Syntax      | `sqw $rA, $rB, imm`                                                                           |
| Encoding    | `0x00 rA rB i i`                                                                              |
| Notes       |                                                                                               |

### `SHW`: Store half word

|             |                                                                                               |
|-------------|-----------------------------------------------------------------------------------------------|
| Description | The four least significant bytes of  of `$rB` is stored at the address `$rA` offset by `imm`. |
| Operation   | ```MEM[$rA + (imm * 4), 4] = $rB;```                                                          |
| Syntax      | `shw $rA, $rB, imm`                                                                           |
| Encoding    | `0x00 rA rB i i`                                                                              |
| Notes       |                                                                                               |

Panic if:

- `$rA + (imm * 4) + 4` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA + (imm * 4), 4]`  does not pass [ownership check](./index.md#ownership)

### `SW`: Store word

|             |                                                                    |
|-------------|--------------------------------------------------------------------|
| Description | The value of `$rB` is stored at the address `$rA` offset by `imm`. |
| Operation   | ```MEM[$rA + (imm * 8), 8] = $rB;```                               |
| Syntax      | `sw $rA, $rB, imm`                                                 |
| Encoding    | `0x00 rA rB i i`                                                   |
| Notes       |                                                                    |

Panic if:

- `$rA + (imm * 8) + 8` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA + (imm * 8), 8]`  does not pass [ownership check](./index.md#ownership)

## Contract Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation, except for [CALL](#call-call-contract), [`RETD`](#retd-return-from-context-with-data) and [`RVRT`](#rvrt-revert).

### `BAL`: Balance of contract ID

|             |                                                                              |
|-------------|------------------------------------------------------------------------------|
| Description | Set `$rA` to the balance of asset ID at `$rB` for contract with ID at `$rC`. |
| Operation   | ```$rA = balance(MEM[$rB, 32], MEM[$rC, 32]);```                             |
| Syntax      | `bal $rA, $rB, $rC`                                                          |
| Encoding    | `0x00 rA rB rC -`                                                            |
| Effects     | Balance tree read                                                            |
| Notes       |                                                                              |

Where helper `balance(asset_id: byte[32], contract_id: byte[32]) -> uint64` returns the current balance of `asset_id` of contract with ID `contract_id`.

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rC, 32]` is not in `tx.inputs`

### `BHEI`: Block height

|             |                            |
|-------------|----------------------------|
| Description | Get Fuel block height.     |
| Operation   | ```$rA = blockheight();``` |
| Syntax      | `bhei $rA`                 |
| Encoding    | `0x00 rA - - -`            |
| Notes       |                            |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

### `BHSH`: Block hash

|             |                                      |
|-------------|--------------------------------------|
| Description | Get block header hash.               |
| Operation   | ```MEM[$rA, 32] = blockhash($rB);``` |
| Syntax      | `bhsh $rA $rB`                       |
| Encoding    | `0x00 rA rB - -`                     |
| Notes       |                                      |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

Block header hashes for blocks with height greater than or equal to current block height are zero (```0x00**32```).

### `BURN`: Burn existing coins

|             |                                                             |
|-------------|-------------------------------------------------------------|
| Description | Burn `$rA` coins of the `$rB` ID from the current contract. |
| Operation   | ```burn($rA, $rB);```                                       |
| Syntax      | `burn $rA $rB`                                              |
| Encoding    | `0x00 rA rB - -`                                            |
| Notes       | `$rB` is a pointer to a 32 byte ID in memory.               |

The asset ID is constructed using the asset ID construction method.

Panic if:

- `$rB + 32` overflows or `> VM_MAX_RAM`
- Balance of asset ID from `constructAssetID(MEM[$fp, 32], MEM[$rB, 32])` of output with contract ID `MEM[$fp, 32]` minus `$rA` underflows
- `$fp == 0` (in the script context)

For output with contract ID `MEM[$fp, 32]`, decrease balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB, 32])` by `$rA`.

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts:

| name          | type          | description                                |
|---------------|---------------|--------------------------------------------|
| `type`        | `ReceiptType` | `ReceiptType.Burn`                         |
| `sub_id`      | `byte[32]`    | Asset sub identifier `MEM[$rB, $rB + 32]`. |
| `contract_id` | `byte[32]`    | Contract ID of the current context.        |
| `val`         | `uint64`      | Value of register `$rA`.                   |
| `pc`          | `uint64`      | Value of register `$pc`.                   |
| `is`          | `uint64`      | Value of register `$is`.                   |

### `CALL`: Call contract

|             |                        |
|-------------|------------------------|
| Description | Call contract.         |
| Operation   |                        |
| Syntax      | `call $rA $rB $rC $rD` |
| Encoding    | `0x00 rA rB rC rD`     |
| Effects     | External call          |
| Notes       |                        |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- Reading past `MEM[VM_MAX_RAM - 1]`
- In an external context, if `$rB > MEM[balanceOfStart(MEM[$rC, 32]), 8]`
- In an internal context, if `$rB` is greater than the balance of asset ID `MEM[$rC, 32]` of output with contract ID `MEM[$fp, 32]`

Register `$rA` is a memory address from which the following fields are set (word-aligned):

| bytes | type       | value    | description          |
|-------|------------|----------|----------------------|
| 32    | `byte[32]` | `to`     | Contract ID to call. |
| 8     | `byte[8]`  | `param1` | First parameter.     |
| 8     | `byte[8]`  | `param2` | Second parameter.    |

`$rB` is the amount of coins to forward. `$rC` points to the 32-byte asset ID of the coins to forward. `$rD` is the amount of gas to forward. If it is set to an amount greater than the available gas, all available gas is forwarded.

Append a receipt to the list of receipts:

| name       | type          | description                                                               |
|------------|---------------|---------------------------------------------------------------------------|
| `type`     | `ReceiptType` | `ReceiptType.Call`                                                        |
| `from`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `to`       | `byte[32]`    | Contract ID of called contract.                                           |
| `amount`   | `uint64`      | Amount of coins to forward, i.e. `$rB`.                                   |
| `asset_id` | `byte[32]`    | Asset ID of coins to forward, i.e. `MEM[$rC, 32]`.                        |
| `gas`      | `uint64`      | Gas to forward, i.e. `min($rD, $cgas)`.                                   |
| `param1`   | `uint64`      | First parameter.                                                          |
| `param2`   | `uint64`      | Second parameter.                                                         |
| `pc`       | `uint64`      | Value of register `$pc`.                                                  |
| `is`       | `uint64`      | Value of register `$is`.                                                  |

For output with contract ID `MEM[$rA, 32]`, increase balance of asset ID `MEM[$rC, 32]` by `$rB`. In an external context, decrease `MEM[balanceOfStart(MEM[$rC, 32]), 8]` by `$rB`. In an internal context, decrease asset ID `MEM[$rC, 32]` balance of output with contract ID `MEM[$fp, 32]` by `$rB`.

A [call frame](./index.md#call-frames) is pushed at `$sp`. In addition to filling in the values of the call frame, the following registers are set:

1. `$fp = $sp` (on top of the previous call frame is the beginning of this call frame)
1. Set `$ssp` and `$sp` to the start of the writable stack area of the call frame.
1. Set `$pc` and `$is` to the starting address of the code.
1. `$flag` set to zero.
1. `$bal = $rB` (forward coins)
1. `$cgas = $rD` or all available gas (forward gas)

This modifies the `balanceRoot` field of the appropriate output(s).

### `CB`: Coinbase contract id

|             |                                                                                                                     |
|-------------|---------------------------------------------------------------------------------------------------------------------|
| Description | Get the [coinbase contract id](../protocol/tx-validity.md#coinbase-transaction) associated with the block proposer. |
| Operation   | ```MEM[$rA, 32] = coinbase();```                                                                                    |
| Syntax      | `cb $rA`                                                                                                            |
| Encoding    | `0x00 rA - - -`                                                                                                     |
| Notes       |                                                                                                                     |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

### `CCP`: Code copy

|             |                                                                                                                                                  |
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| Description | Copy `$rD` bytes of code starting at `$rC` for contract with ID equal to the 32 bytes in memory starting at `$rB` into memory starting at `$rA`. |
| Operation   | ```MEM[$rA, $rD] = code($rB, $rC, $rD);```                                                                                                       |
| Syntax      | `ccp $rA, $rB, $rC, $rD`                                                                                                                         |
| Encoding    | `0x00 rA rB rC rD`                                                                                                                               |
| Notes       | If `$rD` is greater than the code size, zero bytes are filled in.                                                                                |

This is used only for reading and inspecting code of other contracts.
Use [`LDC`](#ldc-load-code-from-an-external-contract-blob-or-memory) to load code for executing.

Panic if:

- `$rA + $rD` overflows or `> VM_MAX_RAM`
- `$rB + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, $rD]`  does not pass [ownership check](./index.md#ownership)
- Contract with ID `MEM[$rB, 32]` is not in `tx.inputs`

### `CROO`: Code Merkle root

|             |                                                                                                                                       |
|-------------|---------------------------------------------------------------------------------------------------------------------------------------|
| Description | Set the 32 bytes in memory starting at `$rA` to the code root for contract with ID equal to the 32 bytes in memory starting at `$rB`. |
| Operation   | ```MEM[$rA, 32] = coderoot(MEM[$rB, 32]);```                                                                                          |
| Syntax      | `croo $rA, $rB`                                                                                                                       |
| Encoding    | `0x00 rA rB - -`                                                                                                                      |
| Notes       |                                                                                                                                       |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- Contract with ID `MEM[$rB, 32]` is not in `tx.inputs`

Code root computation is defined [here](../identifiers/contract-id.md).

### `CSIZ`: Code size

|             |                                                                                                           |
|-------------|-----------------------------------------------------------------------------------------------------------|
| Description | Set `$rA` to the size of the code for contract with ID equal to the 32 bytes in memory starting at `$rB`. |
| Operation   | ```$rA = codesize(MEM[$rB, 32]);```                                                                       |
| Syntax      | `csiz $rA, $rB`                                                                                           |
| Encoding    | `0x00 rA rB - -`                                                                                          |
| Notes       |                                                                                                           |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rB, 32]` is not in `tx.inputs`

### `LDC`: Load code from an external contract, blob or memory

|             |                                                                                                                                                   |
|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| Description | Copy `$rC` bytes of code at offset `$rB` from object identified with `$rA` into memory starting at `$ssp`. Object type is in `imm`.               |
| Operation   | `code = match imm { 0 => contract_code(mem[$rA,32]), 1 => blob_payload(mem[$rA,32]), 2 => mem[$ra, ..] }; MEM[$ssp, $rC] = code[$rB, $rC];`       |
| Syntax      | `ldc $rA, $rB, $rC, imm`                                                                                                                          |
| Encoding    | `0x00 rA rB rC imm`                                                                                                                               |
| Notes       | If `$rC` is greater than the code size, zero bytes are filled in. Final length is always padded to word boundary.                                 |

Object type from `imm` determines the source for loading as follows:

| `imm` | Object type   |
|-------|---------------|
| `0`   | Contract code |
| `1`   | Blob payload  |
| `2`   | VM memory     |
| other | _reserved_    |

Panic if:

- `$ssp + $rC` overflows or `> VM_MAX_RAM`
- `imm <= 1` and `$rA + 32` overflows or `> VM_MAX_RAM`
- `$ssp + $rC >= $hp`
- `imm == 0` and `$rC > CONTRACT_MAX_SIZE`
- `imm == 0` and contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- `imm == 0` and context is a predicate
- `imm == 1` and blob with ID `MEM[$rA, 32]` is not found in the chain state
- `imm == 2` and `$rA + $rB + $rC` overflows or `> VM_MAX_RAM`
- `imm >= 3` (reserved value)

Increment `$fp->codesize`, `$ssp` by `$rC` padded to word alignment. Then set `$sp` to `$ssp`.

This instruction can be used to concatenate the code of multiple contracts or blobs together. It can only be used when the stack area of the call frame is zero-sized.

### `LOG`: Log event

|             |                                |
|-------------|--------------------------------|
| Description | Log an event. This is a no-op. |
| Operation   | ```log($rA, $rB, $rC, $rD);``` |
| Syntax      | `log $rA, $rB, $rC, $rD`       |
| Encoding    | `0x00 rA rB rC rD`             |
| Notes       |                                |

Append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Log`                                                         |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val0` | `uint64`      | Value of register `$rA`.                                                  |
| `val1` | `uint64`      | Value of register `$rB`.                                                  |
| `val2` | `uint64`      | Value of register `$rC`.                                                  |
| `val3` | `uint64`      | Value of register `$rD`.                                                  |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

### `LOGD`: Log data event

|             |                                 |
|-------------|---------------------------------|
| Description | Log an event. This is a no-op.  |
| Operation   | ```logd($rA, $rB, $rC, $rD);``` |
| Syntax      | `logd $rA, $rB, $rC, $rD`       |
| Encoding    | `0x00 rA rB rC rD`              |
| Notes       |                                 |

Append a receipt to the list of receipts:

| name     | type          | description                                                               |
|----------|---------------|---------------------------------------------------------------------------|
| `type`   | `ReceiptType` | `ReceiptType.LogData`                                                     |
| `id`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val0`   | `uint64`      | Value of register `$rA`.                                                  |
| `val1`   | `uint64`      | Value of register `$rB`.                                                  |
| `ptr`    | `uint64`      | Value of register `$rC`.                                                  |
| `len`    | `uint64`      | Value of register `$rD`.                                                  |
| `digest` | `byte[32]`    | [Hash](#s256-sha-2-256) of `MEM[$rC, $rD]`.                               |
| `pc`     | `uint64`      | Value of register `$pc`.                                                  |
| `is`     | `uint64`      | Value of register `$is`.                                                  |

Logs the memory range `MEM[$rC, $rD]`.

Panics if:

- `$rC + $rD` overflows or `> VM_MAX_RAM`

### `MINT`: Mint new coins

|             |                                                             |
|-------------|-------------------------------------------------------------|
| Description | Mint `$rA` coins of the `$rB` ID from the current contract. |
| Operation   | ```mint($rA, $rB);```                                       |
| Syntax      | `mint $rA $rB`                                              |
| Encoding    | `0x00 rA rB - -`                                            |
| Notes       | `$rB` is a pointer to a 32 byte ID in memory                |

The asset ID will be constructed using the asset ID construction method.

Panic if:

- `$rB + 32` overflows or `> VM_MAX_RAM`
- Balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB])` of output with contract ID `MEM[$fp, 32]` plus `$rA` overflows
- `$fp == 0` (in the script context)

For output with contract ID `MEM[$fp, 32]`, increase balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB])` by `$rA`.

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts:

| name          | type          | description                                |
|---------------|---------------|--------------------------------------------|
| `type`        | `ReceiptType` | `ReceiptType.Mint`                         |
| `sub_id`      | `byte[32]`    | Asset sub identifier `MEM[$rB, $rB + 32]`. |
| `contract_id` | `byte[32]`    | Contract ID of the current context.        |
| `val`         | `uint64`      | Value of register `$rA`.                   |
| `pc`          | `uint64`      | Value of register `$pc`.                   |
| `is`          | `uint64`      | Value of register `$is`.                   |

### `RETD`: Return from context with data

|             |                                                                         |
|-------------|-------------------------------------------------------------------------|
| Description | Returns from [context](./index.md#contexts) with value `MEM[$rA, $rB]`. |
| Operation   | ```returndata($rA, $rB);```                                             |
| Syntax      | `retd $rA, $rB`                                                         |
| Encoding    | `0x00 rA rB - -`                                                        |
| Notes       | `$ret` is set to the pointer `$rA`, and `$retl` to length `$rB`.        |

Panic if:

- `$rA + $rB` overflows or `> VM_MAX_RAM`

Append a receipt to the list of receipts:

| name     | type          | description                                                               |
|----------|---------------|---------------------------------------------------------------------------|
| `type`   | `ReceiptType` | `ReceiptType.ReturnData`                                                  |
| `id`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `ptr`    | `uint64`      | Value of register `$rA`.                                                  |
| `len`    | `uint64`      | Value of register `$rB`.                                                  |
| `digest` | `byte[32]`    | [Hash](#s256-sha-2-256) of `MEM[$rA, $rB]`.                               |
| `pc`     | `uint64`      | Value of register `$pc`.                                                  |
| `is`     | `uint64`      | Value of register `$is`.                                                  |

If current context is a script, append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `0`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

If current context is external, cease VM execution and return `MEM[$rA, $rB]`.

Returns from contract call, popping the call frame. Before popping, perform the following operations.

Return the unused forwarded gas to the caller:

1. `$cgas = $cgas + $fp->$cgas` (add remaining context gas from previous context to current remaining context gas)

Set the return value:

1. `$ret = $rA`
1. `$retl = $rB`

Then pop the call frame and restore all registers _except_ `$ggas`, `$cgas`, `$ret`, `$retl` and `$hp`. Afterwards, set the following registers:

1. `$pc = $pc + 4` (advance program counter from where we called)

### `RVRT`: Revert

|             |                                                                       |
|-------------|-----------------------------------------------------------------------|
| Description | Halt execution, reverting state changes and returning value in `$rA`. |
| Operation   | ```revert($rA);```                                                    |
| Syntax      | `rvrt $rA`                                                            |
| Encoding    | `0x00 rA - - -`                                                       |
| Notes       |                                                                       |

Append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Revert`                                                      |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val`  | `uint64`      | Value of register `$rA`.                                                  |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

Then append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `1`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

Cease VM execution and revert script effects. After a revert:

1. All [`OutputContract`](../tx-format/output.md#outputcontract) outputs will have the same `balanceRoot` and `stateRoot` as on initialization.
1. All [`OutputVariable`](../tx-format/output.md#outputvariable) outputs will have `to`, `amount`, and `asset_id` of zero.

### `SMO`: Send message out

|             |                                                                                                                                                               |
|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Description | Send a message to recipient address `MEM[$rA, 32]` from the `MEM[$fp, 32]` sender with message data `MEM[$rB, $rC]` and the `$rD` amount of base asset coins. |
| Operation   | ```outputmessage(MEM[$fp, 32], MEM[$rA, 32], MEM[$rB, $rC], $rD);```                                                                                          |
| Syntax      | `smo $rA, $rB, $rC, $rD`                                                                                                                                      |
| Encoding    | `0x00 rA rB rC rD`                                                                                                                                            |
| Effects     | Output message                                                                                                                                                |
| Notes       |                                                                                                                                                               |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- `$rC > MESSAGE_MAX_DATA_SIZE`
- In an external context, if `$rD > MEM[balanceOfStart(0), 8]`
- In an internal context, if `$rD` is greater than the balance of asset ID 0 of output with contract ID `MEM[$fp, 32]`

Append a receipt to the list of receipts:

| name        | type          | description                                                                     |
|-------------|---------------|---------------------------------------------------------------------------------|
| `type`      | `ReceiptType` | `ReceiptType.MessageOut`                                                        |
| `sender`    | `byte[32]`    | The address of the message sender: `MEM[$fp, 32]`.                              |
| `recipient` | `byte[32]`    | The address of the message recipient: `MEM[$rA, 32]`.                           |
| `amount`    | `uint64`      | Amount of base asset coins sent with message: `$rD`.                            |
| `nonce`     | `byte[32]`    | The message nonce as described [here](../identifiers/utxo-id.md#message-nonce). |
| `len`       | `uint64`      | Length of message data, in bytes: `$rC`.                                        |
| `digest`    | `byte[32]`    | [Hash](#s256-sha-2-256) of `MEM[$rB, $rC]`.                                     |

In an external context, decrease `MEM[balanceOfStart(0), 8]` by `$rD`. In an internal context, decrease asset ID 0 balance of output with contract ID `MEM[$fp, 32]` by `$rD`. This modifies the `balanceRoot` field of the appropriate contract that had its' funds deducted.

### `SCWQ`: State clear sequential 32 byte slots

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | A sequential series of 32 bytes is cleared from the current contract's state. |
| Operation   | ```STATE[MEM[$rA, 32], 32 * $rC] = None;```                                   |
| Syntax      | `scwq $rA, $rB, $rC`                                                          |
| Encoding    | `0x00 rA rB rC -`                                                             |
| Notes       |                                                                               |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if any storage slot in the requested range was already unset (default) and `true` if all the slots were set.

### `SRW`: State read word

|             |                                                   |
|-------------|---------------------------------------------------|
| Description | A word is read from the current contract's state. |
| Operation   | ```$rA = STATE[MEM[$rC, 32]][0, 8];```            |
| Syntax      | `srw $rA, $rB, $rC`                               |
| Encoding    | `0x00 rA rB rC -`                                 |
| Effects     | Storage read                                      |
| Notes       | Returns zero if the state element does not exist. |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB` is a [reserved register](./index.md#semantics)
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if the requested slot is unset (default) and `true` if it's set.

### `SRWQ`: State read sequential 32 byte slots

|             |                                                                            |
|-------------|----------------------------------------------------------------------------|
| Description | A sequential series of 32 bytes is read from the current contract's state. |
| Operation   | ```MEM[$rA, 32 * rD] = STATE[MEM[$rC, 32], 32 * rD];```                    |
| Syntax      | `srwq $rA, $rB, $rC, $rD`                                                  |
| Encoding    | `0x00 rA rB rC rD`                                                         |
| Effects     | Storage read                                                               |
| Notes       | Returns zero if the state element does not exist.                          |

Panic if:

- `$rA + 32 * rD` overflows or `> VM_MAX_RAM`
- `$rC + 32 * rD` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- The memory range `MEM[$rA, 32 * rD]`  does not pass [ownership check](./index.md#ownership)
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if any storage slot in the requested range is unset (default) and `true` if all the slots are set.

### `SWW`: State write word

|             |                                                                                 |
|-------------|---------------------------------------------------------------------------------|
| Description | A word is written to the current contract's state.                              |
| Operation   | ```STATE[MEM[$rA, 32]][0, 8] = $rC;```<br>```STATE[MEM[$rA, 32]][8, 24] = 0;``` |
| Syntax      | `sww $rA $rB $rC`                                                               |
| Encoding    | `0x00 rA rB rC -`                                                               |
| Effects     | Storage write                                                                   |
| Notes       | Additional gas is charged when a new storage slot is created.                   |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- `$fp == 0` (in the script context)

The last 24 bytes of `STATE[MEM[$rA, 32]]` are set to `0`. Register `$rB` will be set to the number of new slots written, i.e. `1` if the slot was previously unset, and `0` if it already contained a value.

### `SWWQ`: State write sequential 32 byte slots

|             |                                                                             |
|-------------|-----------------------------------------------------------------------------|
| Description | A sequential series of 32 bytes is written to the current contract's state. |
| Operation   | ```STATE[MEM[$rA, 32], 32 * $rD] = MEM[$rC, 32 * $rD];```                   |
| Syntax      | `swwq $rA, $rB, $rC, $rD`                                                   |
| Encoding    | `0x00 rA rB rC rD`                                                          |
| Effects     | Storage write                                                               |
| Notes       | Additional gas is charged when for each new storage slot created.           |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32 * $rD` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- `$fp == 0` (in the script context)

Register `$rB` will be set to the number of storage slots that were previously unset, and were set by this operation.

### `TIME`: Timestamp at height

|             |                                         |
|-------------|-----------------------------------------|
| Description | Get timestamp of block at given height. |
| Operation   | ```$rA = time($rB);```                  |
| Syntax      | `time $rA, $rB`                         |
| Encoding    | `0x00 rA rB - -`                        |
| Notes       |                                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB` is greater than the current block height.

Gets the timestamp of the block at height `$rB`. Time is in [TAI64](https://cr.yp.to/libtai/tai64.html) format.

### `TR`: Transfer coins to contract

|             |                                                                           |
|-------------|---------------------------------------------------------------------------|
| Description | Transfer `$rB` coins with asset ID at `$rC` to contract with ID at `$rA`. |
| Operation   | ```transfer(MEM[$rA, 32], $rB, MEM[$rC, 32]);```                          |
| Syntax      | `tr $rA, $rB, $rC`                                                        |
| Encoding    | `0x00 rA rB rC -`                                                         |
| Effects     | Balance tree read, balance tree write                                     |
| Notes       |                                                                           |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- In an external context, if `$rB > MEM[balanceOfStart(MEM[$rC, 32]), 8]`
- In an internal context, if `$rB` is greater than the balance of asset ID `MEM[$rC, 32]` of output with contract ID `MEM[$fp, 32]`
- `$rB == 0`

Append a receipt to the list of receipts:

| name       | type          | description                                                               |
|------------|---------------|---------------------------------------------------------------------------|
| `type`     | `ReceiptType` | `ReceiptType.Transfer`                                                    |
| `from`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `to`       | `byte[32]`    | Contract ID of contract to transfer coins to.                             |
| `amount`   | `uint64`      | Amount of coins transferred.                                              |
| `asset_id` | `byte[32]`    | asset ID of coins transferred.                                            |
| `pc`       | `uint64`      | Value of register `$pc`.                                                  |
| `is`       | `uint64`      | Value of register `$is`.                                                  |

For output with contract ID `MEM[$rA, 32]`, increase balance of asset ID `MEM[$rC, 32]` by `$rB`. In an external context, decrease `MEM[balanceOfStart(MEM[$rC, 32]), 8]` by `$rB`. In an internal context, decrease asset ID `MEM[$rC, 32]` balance of output with contract ID `MEM[$fp, 32]` by `$rB`.

This modifies the `balanceRoot` field of the appropriate output(s).

### `TRO`: Transfer coins to output

|             |                                                                                     |
|-------------|-------------------------------------------------------------------------------------|
| Description | Transfer `$rC` coins with asset ID at `$rD` to address at `$rA`, with output `$rB`. |
| Operation   | ```transferout(MEM[$rA, 32], $rB, $rC, MEM[$rD, 32]);```                            |
| Syntax      | `tro $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                  |
| Effects     | Balance tree read, balance tree write                                               |
| Notes       |                                                                                     |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`
- `$rB > tx.outputsCount`
- In an external context, if `$rC > MEM[balanceOfStart(MEM[$rD, 32]), 8]`
- In an internal context, if `$rC` is greater than the balance of asset ID `MEM[$rD, 32]` of output with contract ID `MEM[$fp, 32]`
- `$rC == 0`
- `tx.outputs[$rB].type != OutputType.Variable`
- `tx.outputs[$rB].amount != 0`

Append a receipt to the list of receipts:

| name       | type          | description                                                               |
|------------|---------------|---------------------------------------------------------------------------|
| `type`     | `ReceiptType` | `ReceiptType.TransferOut`                                                 |
| `from`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `to`       | `byte[32]`    | Address to transfer coins to.                                             |
| `amount`   | `uint64`      | Amount of coins transferred.                                              |
| `asset_id` | `byte[32]`    | asset ID of coins transferred.                                            |
| `pc`       | `uint64`      | Value of register `$pc`.                                                  |
| `is`       | `uint64`      | Value of register `$is`.                                                  |

In an external context, decrease `MEM[balanceOfStart(MEM[$rD, 32]), 8]` by `$rC`. In an internal context, decrease asset ID `MEM[$rD, 32]` balance of output with contract ID `MEM[$fp, 32]` by `$rC`. Then set:

- `tx.outputs[$rB].to = MEM[$rA, 32]`
- `tx.outputs[$rB].amount = $rC`
- `tx.outputs[$rB].asset_id = MEM[$rD, 32]`

This modifies the `balanceRoot` field of the appropriate output(s).

## Blob Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `BSIZ`: Blob size

|             |                                                                                                           |
|-------------|-----------------------------------------------------------------------------------------------------------|
| Description | Set `$rA` to the size of the blob with ID equal to the 32 bytes in memory starting at `$rB`.              |
| Operation   | `$rA = len(blob(MEM[$rB, 32]));`                                                                          |
| Syntax      | `bsiz $rA, $rB`                                                                                           |
| Encoding    | `0x00 rA rB - -`                                                                                          |
| Notes       |                                                                                                           |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Blob ID `MEM[$rB, 32]` is not found

### `BLDD`: Load data from a blob

|             |                                                                                                             |
|-------------|-------------------------------------------------------------------------------------------------------------|
| Description | Load 32-byte blob id at `$rB`, and copy `$rD` bytes starting from `$rC` into `$sA`.                         |
| Operation   | `MEM[$rA, $rD] = blob(MEM[$rB, 32])[$rC, $rD];`                                                             |
| Syntax      | `bldd $rA, $rB, rC, $rD`                                                                                    |
| Encoding    | `0x00 rA rB rC rD`                                                                                          |
| Notes       | If `$rC >` blob size, zero bytes are filled in.                                                             |

Panic if:

- `$rA + $rD` overflows or `> VM_MAX_RAM` or `> $hp`
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Blob ID `MEM[$rB, 32]` is not found

## Cryptographic Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `ECK1`: Secp256k1 signature recovery

|             |                                                                                                                             |
|-------------|-----------------------------------------------------------------------------------------------------------------------------|
| Description | The 64-byte public key (x, y) recovered from 64-byte signature starting at `$rB` on 32-byte message hash starting at `$rC`. |
| Operation   | ```MEM[$rA, 64] = ecrecover_k1(MEM[$rB, 64], MEM[$rC, 32]);```                                                              |
| Syntax      | `eck1 $rA, $rB, $rC`                                                                                                        |
| Encoding    | `0x00 rA rB rC -`                                                                                                           |
| Notes       | Takes message hash as an input. You can use `S256` to hash the message if needed.                                           |

Panic if:

- `$rA + 64` overflows or `> VM_MAX_RAM`
- `$rB + 64` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 64]` does not pass [ownership check](./index.md#ownership)

Signatures and signature verification are specified [here](../protocol/cryptographic-primitives.md#ecdsa-public-key-cryptography).

If the signature cannot be verified, `MEM[$rA, 64]` is set to `0` and `$err` is set to `1`, otherwise `$err` is cleared.

To get the address from the public key, hash the public key with [SHA-2-256](../protocol/cryptographic-primitives.md#hashing).

### `ECR1`: Secp256r1 signature recovery

|             |                                                                                                                             |
|-------------|-----------------------------------------------------------------------------------------------------------------------------|
| Description | The 64-byte public key (x, y) recovered from 64-byte signature starting at `$rB` on 32-byte message hash starting at `$rC`. |
| Operation   | ```MEM[$rA, 64] = ecrecover_r1(MEM[$rB, 64], MEM[$rC, 32]);```                                                              |
| Syntax      | `ecr1 $rA, $rB, $rC`                                                                                                        |
| Encoding    | `0x00 rA rB rC -`                                                                                                           |
| Notes       | Takes message hash as an input. You can use `S256` to hash the message if needed.                                           |

Panic if:

- `$rA + 64` overflows or `> VM_MAX_RAM`
- `$rB + 64` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 64]` does not pass [ownership check](./index.md#ownership)

Signatures and signature verification are specified [here](../protocol/cryptographic-primitives.md#ecdsa-public-key-cryptography).

If the signature cannot be verified, `MEM[$rA, 64]` is set to `0` and `$err` is set to `1`, otherwise `$err` is cleared.

To get the address from the public key, hash the public key with [SHA-2-256](../protocol/cryptographic-primitives.md#hashing).

### `ED19`: EdDSA curve25519 verification

|             |                                                                                                                             |
|-------------|-----------------------------------------------------------------------------------------------------------------------------|
| Description | Verification 64-byte signature at `$rB` with 32-byte public key at `$rA` for a message starting at `$rC` with length `$rD`. |
| Operation   | ```ed19verify(MEM[$rA, 32], MEM[$rB, 64], MEM[$rC, $rD]);```                                                                |
| Syntax      | `ed19 $rA, $rB, $rC, $rD`                                                                                                   |
| Encoding    | `0x00 rA rB rC rD`                                                                                                          |
| Notes       | Takes message instead of hash. **For backwards compatibility reasons, if `$rD == 0`, it will be treated as `32`.**          |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + 64` overflows or `> VM_MAX_RAM`
- `$rC + $rD` overflows or `> VM_MAX_RAM`

Verification are specified [here](../protocol/cryptographic-primitives.md#eddsa-public-key-cryptography).

If there is an error in verification, `$err` is set to `1`, otherwise `$err` is cleared.

### `K256`: keccak-256

|             |                                                       |
|-------------|-------------------------------------------------------|
| Description | The keccak-256 hash of `$rC` bytes starting at `$rB`. |
| Operation   | ```MEM[$rA, 32] = keccak256(MEM[$rB, $rC]);```        |
| Syntax      | `k256 $rA, $rB, $rC`                                  |
| Encoding    | `0x00 rA rB rC -`                                     |
| Notes       |                                                       |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

### `S256`: SHA-2-256

|             |                                                      |
|-------------|------------------------------------------------------|
| Description | The SHA-2-256 hash of `$rC` bytes starting at `$rB`. |
| Operation   | ```MEM[$rA, 32] = sha256(MEM[$rB, $rC]);```          |
| Syntax      | `s256 $rA, $rB, $rC`                                 |
| Encoding    | `0x00 rA rB rC -`                                    |
| Notes       |                                                      |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

### `ECOP`: Elliptic curve point operation

|             |                                                     |
|-------------|-----------------------------------------------------|
| Description | Perform arithmetic operation `$rC` on points of the elliptic curve `$rB`. Arguments are read from memory at `$rD`, and result is written to the memory at `$rA`, as per the table below.                                                   |
| Operation   | ```MEM[$rA, X] = ecop(MEM[$rD, Y]);```              |
| Syntax      | `ecop $rA, $rB, $rC, $rD`                           |
| Encoding    | `0x00 rA rB rC rD`                                  |
| Notes       | For now, only `$rB` = 0 is accepted                 |

#### Curve ID `$rB` possible values

- `0`: `alt_bn128` elliptic curve.

#### Operation type `$rC` supported

- `0`: two points addition
- `1`: one point and one scalar multiplication

#### Encoding of points and results by curve ID and operation type

- 1P = one point = (X, Y) = ([32 bytes], [32 bytes])
- 1S = one scalar = X = [32 bytes]

| `$rB` Curve ID | `$rC` Operation type | `$rA` format         | `$rD` format               |
|----------------|----------------------|----------------------|----------------------------|
|    `0`         | `0`                  | `MEM[$rA, 64]` `1P`  | `MEM[$rD, 128]` `1P1P`     |
|    `0`         | `1`                  | `MEM[$rA, 64]` `1P`  | `MEM[$rD, 96]` `1P1S`      |

#### Panic cases

- Curve ID is not supported (`$rB`)
- Operation type is not supported (`$rC`)
- `$rD` + (size depending on the table above) overflows or `> VM_MAX_RAM`
- Decoding of `$rD` memory doesn't match the expected format described above for each case.
- The memory range at `$rA` (size depending on the curve/operation types) does not pass [ownership check](./index.md#ownership)

### `EPAR`: Elliptic curve point pairing check

|             |                                                     |
|-------------|-----------------------------------------------------|
| Description | Check if `$rC` groups of points at `$rD` all form valid pairings in (curve, pairing type) identified by `$rB`. Set `$rA` to the result of the pairing, either `0` or `1`. |
| Operation   | ```$rA = epar(MEM[$rD, X * $rC]);```                |
| Syntax      | `epar $rA, $rB, $rC, $rD`                           |
| Encoding    | `0x00 rA rB rC rD`                                  |
| Notes       | For now, only `$rB` = 0 is accepted.                |

<!-- markdownlint-disable-next-line no-duplicate-header -->
#### Curve/Pairing ID `$rB` possible values

- `0`: optimal ate pairing on `alt_bn128` elliptic curve.

#### Encoding of points by curve ID and check type

- 1P = one point = (X, Y) = ([32 bytes], [32 bytes])

| `$rB` Curve / Pairing ID  | `$rD` format               |
|---------------------------|----------------------------|
|    `0`                    | `MEM[$rD, (64 + 64 + 64) * $rC]` Each element is `1P1P1P` (three points coordinates) (192 bytes)   |

<!-- markdownlint-disable-next-line no-duplicate-header -->
#### Panic cases

- Curve ID/Pairing is not supported (`$rB`)
- `$rD` has elements than described in `$rC`
- `$rD` + (size depending on the table above) overflows or `> VM_MAX_RAM`
- Decoding of `$rD` memory doesn't match the expected format described above for each case.
- The memory range at `$rA` (size depending on the curve/operation types) does not pass [ownership check](./index.md#ownership)

## Other Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `ECAL`: Call external function

|             |                                                                          |
|-------------|--------------------------------------------------------------------------|
| Description | Call an external function that has full access to the VM state.          |
| Operation   | `external(&mut vm, $rA, $rB, $rC, $rD)`                                  |
| Syntax      | `ecal $rA $rB $rC $rD`                                                   |
| Encoding    | `0x00 rA rB rC rD`                                                       |
| Notes       | Does nothing by default, but the VM user can define this to do anything. |

This function provides an escape hatch from the VM, similar to `ecall` instruction of RISC-V. The suggested convention is to use `$rA` for "system call number", i.e. identifying the procedure to call, but all arguments can be used freely. The operation can modify the VM state freely, including writing to registers and memory. Again, the suggested convention is to use `$rA` for the return value and `$err` for any possible errors. However, these conventions can be ignored when necessary.

Panic if:

- The external function panics.

### `FLAG`: Set flags

|             |                       |
|-------------|-----------------------|
| Description | Set `$flag` to `$rA`. |
| Operation   | ```$flag = $rA;```    |
| Syntax      | `flag $rA`            |
| Encoding    | `0x00 rA - - -`       |
| Notes       |                       |

Panic if:

- Any reserved flags are set

### `GM`: Get metadata

|             |                           |
|-------------|---------------------------|
| Description | Get metadata from memory. |
| Operation   | Varies (see below).       |
| Syntax      | `gm $rA, imm`             |
| Encoding    | `0x00 rA imm imm imm`     |
| Notes       |                           |

Read metadata from memory. A convenience instruction to avoid manually extracting metadata.

| name                         | value     | description                      |
|------------------------------|-----------|----------------------------------|
| `GM_IS_CALLER_EXTERNAL`      | `0x00001` | Get if caller is external.       |
| `GM_GET_CALLER`              | `0x00002` | Get caller's contract ID.        |
| `GM_GET_VERIFYING_PREDICATE` | `0x00003` | Get index of current predicate.  |
| `GM_GET_CHAIN_ID`            | `0x00004` | Get the value of `CHAIN_ID`      |
| `GM_TX_START`                | `0x00005` | Transaction start memory address |
| `GM_BASE_ASSET_ID`           | `0x00006` | Base asset ID                    |

If `imm == GM_IS_CALLER_EXTERNAL`:

Panic if:

- `$fp == 0` (in an external context)

Set `$rA` to `true` if parent is an external context, `false` otherwise.

If `imm == GM_GET_CALLER`:

Panic if:

- `$fp == 0` (in an external context)
- `$fp->$fp == 0` (if parent context is external)

Set `$rA` to `$fp->$fp` (i.e. `$rA` will point to the previous call frame's contract ID).

If `imm == GM_GET_VERIFYING_PREDICATE`:

Panic if:

- not in a predicate context

Set `$rA` to the index of the currently-verifying predicate.

### `GTF`: Get transaction fields

|             |                                         |
|-------------|-----------------------------------------|
| Description | Get transaction fields.                 |
| Operation   | Set `$rA` according to the table below. |
| Syntax      | `gtf $rA, $rB, imm`                     |
| Encoding    | `0x00 rA rB i i`                        |
| Notes       | `$rB` is ignored for many variants.     |

Get [fields from the transaction](../tx-format/transaction.md).

| name                                      | `imm`   | set `$rA` to                                                      |
|-------------------------------------------|---------|-------------------------------------------------------------------|
| `GTF_TYPE`                                | `0x001` | `tx.type`                                                         |
| `GTF_SCRIPT_GAS_LIMIT`                    | `0x002` | `tx.scriptGasLimit`                                               |
| `GTF_SCRIPT_SCRIPT_LENGTH`                | `0x003` | `tx.scriptLength`                                                 |
| `GTF_SCRIPT_SCRIPT_DATA_LENGTH`           | `0x004` | `tx.scriptDataLength`                                             |
| `GTF_SCRIPT_INPUTS_COUNT`                 | `0x005` | `tx.inputsCount`                                                  |
| `GTF_SCRIPT_OUTPUTS_COUNT`                | `0x006` | `tx.outputsCount`                                                 |
| `GTF_SCRIPT_WITNESSES_COUNT`              | `0x007` | `tx.witnessesCount`                                               |
| `GTF_SCRIPT_SCRIPT`                       | `0x009` | Memory address of `tx.script`                                     |
| `GTF_SCRIPT_SCRIPT_DATA`                  | `0x00A` | Memory address of `tx.scriptData`                                 |
| `GTF_SCRIPT_INPUT_AT_INDEX`               | `0x00B` | Memory address of `tx.inputs[$rB]`                                |
| `GTF_SCRIPT_OUTPUT_AT_INDEX`              | `0x00C` | Memory address of `t.outputs[$rB]`                                |
| `GTF_SCRIPT_WITNESS_AT_INDEX`             | `0x00D` | Memory address of `tx.witnesses[$rB]`                             |
| `GTF_TX_LENGTH`                           | `0x00E` | Length of raw transaction types in memory                        |
| `GTF_CREATE_BYTECODE_WITNESS_INDEX`       | `0x101` | `tx.bytecodeWitnessIndex`                                         |
| `GTF_CREATE_STORAGE_SLOTS_COUNT`          | `0x102` | `tx.storageSlotsCount`                                            |
| `GTF_CREATE_INPUTS_COUNT`                 | `0x103` | `tx.inputsCount`                                                  |
| `GTF_CREATE_OUTPUTS_COUNT`                | `0x104` | `tx.outputsCount`                                                 |
| `GTF_CREATE_WITNESSES_COUNT`              | `0x105` | `tx.witnessesCount`                                               |
| `GTF_CREATE_SALT`                         | `0x106` | Memory address of `tx.salt`                                       |
| `GTF_CREATE_STORAGE_SLOT_AT_INDEX`        | `0x107` | Memory address of `tx.storageSlots[$rB]`                          |
| `GTF_CREATE_INPUT_AT_INDEX`               | `0x108` | Memory address of `tx.inputs[$rB]`                                |
| `GTF_CREATE_OUTPUT_AT_INDEX`              | `0x109` | Memory address of `t.outputs[$rB]`                                |
| `GTF_CREATE_WITNESS_AT_INDEX`             | `0x10A` | Memory address of `tx.witnesses[$rB]`                             |
| `GTF_INPUT_TYPE`                          | `0x200` | `tx.inputs[$rB].type`                                             |
| `GTF_INPUT_COIN_TX_ID`                    | `0x201` | Memory address of `tx.inputs[$rB].txID`                           |
| `GTF_INPUT_COIN_OUTPUT_INDEX`             | `0x202` | `tx.inputs[$rB].outputIndex`                                      |
| `GTF_INPUT_COIN_OWNER`                    | `0x203` | Memory address of `tx.inputs[$rB].owner`                          |
| `GTF_INPUT_COIN_AMOUNT`                   | `0x204` | `tx.inputs[$rB].amount`                                           |
| `GTF_INPUT_COIN_ASSET_ID`                 | `0x205` | Memory address of `tx.inputs[$rB].asset_id`                       |
| `GTF_INPUT_COIN_WITNESS_INDEX`            | `0x207` | `tx.inputs[$rB].witnessIndex`                                     |
| `GTF_INPUT_COIN_PREDICATE_LENGTH`         | `0x209` | `tx.inputs[$rB].predicateLength`                                  |
| `GTF_INPUT_COIN_PREDICATE_DATA_LENGTH`    | `0x20A` | `tx.inputs[$rB].predicateDataLength`                              |
| `GTF_INPUT_COIN_PREDICATE`                | `0x20B` | Memory address of `tx.inputs[$rB].predicate`                      |
| `GTF_INPUT_COIN_PREDICATE_DATA`           | `0x20C` | Memory address of `tx.inputs[$rB].predicateData`                  |
| `GTF_INPUT_COIN_PREDICATE_GAS_USED`       | `0x20D` | `tx.inputs[$rB].predicateGasUsed`                                 |
| `GTF_INPUT_CONTRACT_CONTRACT_ID`          | `0x225` | Memory address of `tx.inputs[$rB].contractID`                     |
| `GTF_INPUT_MESSAGE_SENDER`                | `0x240` | Memory address of `tx.inputs[$rB].sender`                         |
| `GTF_INPUT_MESSAGE_RECIPIENT`             | `0x241` | Memory address of `tx.inputs[$rB].recipient`                      |
| `GTF_INPUT_MESSAGE_AMOUNT`                | `0x242` | `tx.inputs[$rB].amount`                                           |
| `GTF_INPUT_MESSAGE_NONCE`                 | `0x243` | Memory address of `tx.inputs[$rB].nonce`                          |
| `GTF_INPUT_MESSAGE_WITNESS_INDEX`         | `0x244` | `tx.inputs[$rB].witnessIndex`                                     |
| `GTF_INPUT_MESSAGE_DATA_LENGTH`           | `0x245` | `tx.inputs[$rB].dataLength`                                       |
| `GTF_INPUT_MESSAGE_PREDICATE_LENGTH`      | `0x246` | `tx.inputs[$rB].predicateLength`                                  |
| `GTF_INPUT_MESSAGE_PREDICATE_DATA_LENGTH` | `0x247` | `tx.inputs[$rB].predicateDataLength`                              |
| `GTF_INPUT_MESSAGE_DATA`                  | `0x248` | Memory address of `tx.inputs[$rB].data`                           |
| `GTF_INPUT_MESSAGE_PREDICATE`             | `0x249` | Memory address of `tx.inputs[$rB].predicate`                      |
| `GTF_INPUT_MESSAGE_PREDICATE_DATA`        | `0x24A` | Memory address of `tx.inputs[$rB].predicateData`                  |
| `GTF_INPUT_MESSAGE_PREDICATE_GAS_USED`    | `0x24B` | `tx.inputs[$rB].predicateGasUsed`                                 |
| `GTF_OUTPUT_TYPE`                         | `0x300` | `tx.outputs[$rB].type`                                            |
| `GTF_OUTPUT_COIN_TO`                      | `0x301` | Memory address of `tx.outputs[$rB].to`                            |
| `GTF_OUTPUT_COIN_AMOUNT`                  | `0x302` | `tx.outputs[$rB].amount`                                          |
| `GTF_OUTPUT_COIN_ASSET_ID`                | `0x303` | Memory address of `tx.outputs[$rB].asset_id`                      |
| `GTF_OUTPUT_CONTRACT_INPUT_INDEX`         | `0x304` | `tx.outputs[$rB].inputIndex`                                      |
| `GTF_OUTPUT_CONTRACT_BALANCE_ROOT`        | `0x305` | Memory address of `tx.outputs[$rB].balanceRoot`                   |
| `GTF_OUTPUT_CONTRACT_STATE_ROOT`          | `0x306` | Memory address of `tx.outputs[$rB].stateRoot`                     |
| `GTF_OUTPUT_CONTRACT_CREATED_CONTRACT_ID` | `0x307` | Memory address of `tx.outputs[$rB].contractID`                    |
| `GTF_OUTPUT_CONTRACT_CREATED_STATE_ROOT`  | `0x308` | Memory address of `tx.outputs[$rB].stateRoot`                     |
| `GTF_WITNESS_DATA_LENGTH`                 | `0x400` | `tx.witnesses[$rB].dataLength`                                    |
| `GTF_WITNESS_DATA`                        | `0x401` | Memory address of `tx.witnesses[$rB].data`                        |
| `GTF_POLICY_TYPES`                        | `0x500` | `tx.policies.policyTypes`                                         |
| `GTF_POLICY_TIP`                          | `0x501` | `tx.policies[0x00].tip`                                           |
| `GTF_POLICY_WITNESS_LIMIT`                | `0x502` | `tx.policies[count_ones(0b11 & tx.policyTypes) - 1].witnessLimit` |
| `GTF_POLICY_MATURITY`                     | `0x503` | `tx.policies[count_ones(0b111 & tx.policyTypes) - 1].maturity`    |
| `GTF_POLICY_MAX_FEE`                      | `0x504` | `tx.policies[count_ones(0b1111 & tx.policyTypes) - 1].maxFee`     |
| `GTF_POLICY_EXPIRATION`                   | `0x505` | `tx.policies[count_ones(0b11111 & tx.policyTypes) - 1].expiration`|
| `GTF_UPLOAD_ROOT`                         | `0x600` | Memory address of `tx.root`                                       |
| `GTF_UPLOAD_WITNESS_INDEX`                | `0x601` | Set `$rA` to `tx.witnessIndex`                                    |
| `GTF_UPLOAD_SUBSECTION_INDEX`             | `0x602` | Set `$rA` to `tx.subsectionIndex`                                 |
| `GTF_UPLOAD_SUBSECTIONS_COUNT`            | `0x603` | Set `$rA` to `tx.subsectionsNumber`                               |
| `GTF_UPLOAD_PROOF_SET_COUNT`              | `0x604` | Set `$rA` to `tx.proofSetCount`                                   |
| `GTF_UPLOAD_PROOF_SET_AT_INDEX`           | `0x605` | Set `$rA` to `Memory address of tx.proofSet[$rB]`                 |
| `GTF_BLOB_ID`                             | `0x700` | Set `$rA` to `Memory address of tx.id`                            |
| `GTF_BLOB_WITNESS_INDEX`                  | `0x701` | Set `$rA` to the blob `tx.witnessIndex`                           |
| `GTF_UPGRADE_PURPOSE`                     | `0x800` | Set `$rA` to `Memory address of tx.purpose`                       |
| `GTF_TX_INPUTS_COUNT`                     | `0x900` | Set `$rA` to `tx.inputsCount`                                     |
| `GTF_TX_OUTPUTS_COUNT`                    | `0x901` | Set `$rA` to `tx.outputsCount`                                    |
| `GTF_TX_WITNESSES_COUNT`                  | `0x902` | Set `$rA` to `tx.witnessesCount`                                  |
| `GTF_TX_INPUT_AT_INDEX`                   | `0x903` | Set `$rA` to `Memory address of tx.inputs[$rB]`                   |
| `GTF_TX_OUTPUT_AT_INDEX`                  | `0x904` | Set `$rA` to `Memory address of t.outputs[$rB]`                   |
| `GTF_TX_WITNESS_AT_INDEX`                 | `0x905` | Set `$rA` to `Memory address of tx.witnesses[$rB]`                |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `imm` is not one of the values listed above
- The value of `$rB` results in an out of bounds access for variable-length fields
- The input or output type does not match (`OutputChange` and `OutputVariable` count as `OutputCoin`)
- The requested policy type is not set for this transaction.

For fixed-length fields, the value of `$rB` is ignored.


---

### File: docs/fuel-specs/src/identifiers/asset.md

# Asset ID

The _asset ID_ (also called _asset hash_) of a asset is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of the `CONTRACT_ID` and a 256-bit `SUB_IDENTIFIER`.

```python
sha256(CONTRACT_ID ++ SUB_IDENTIFIER)
```


---

### File: docs/fuel-specs/src/identifiers/blob-id.md

# Blob ID

The _blob ID_ (also called _blob hash_) of a transaction is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of the blob data.

Blob ID calculation doesn't vary between chains.

```python
sha256(blob_data)
```


---

### File: docs/fuel-specs/src/identifiers/contract-id.md

# Contract ID

For a transaction of type `TransactionType.Create`, `tx`, the contract ID is
`sha256(0x4655454C ++ tx.data.salt ++ root(tx.data.witnesses[bytecodeWitnessIndex].data) ++ root_smt(tx.storageSlots))`,
where `root` is the Merkle root of [the binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) with
each leaf being 16KiB of instructions, and `root_smt` is the
[Sparse Merkle tree](../protocol/cryptographic-primitives.md#sparse-merkle-tree) root of the provided key-value pairs.
If the bytecode is not a multiple of 16 KiB, the final leaf should be zero-padded rounding up to the nearest multiple
of 8 bytes.


---

### File: docs/fuel-specs/src/identifiers/index.md

# Identifiers

This chapter defines how to compute unique identifiers.

- [Asset ID](./asset.md)
- [Blob ID](./blob-id.md)
- [Contract ID](./contract-id.md)
- [Predicate ID](./predicate-id.md)
- [Transaction ID](./transaction-id.md)
- [UTXO ID](./utxo-id.md)
  - [Coin ID](./utxo-id.md#coin-id)
  - [Message ID](./utxo-id.md#message-id)
    - [Message Nonce](./utxo-id.md#message-nonce)
  - [Fee ID](./utxo-id.md#fee-id)


---

### File: docs/fuel-specs/src/identifiers/predicate-id.md

# Predicate ID

For an input of type `InputType.Coin` or `InputType.Message`, `input`, the predicate owner is calculated as:
`sha256(0x4655454C ++ root(input.predicate))`, where `root` is the Merkle root of
[the binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) each leaf being 16KiB of instructions.
If the bytecode is not a multiple of 16 KiB, the final leaf should be zero-padded rounding up to the nearest multiple of 8 bytes.


---

### File: docs/fuel-specs/src/identifiers/transaction-id.md

# Transaction ID

The _transaction ID_ (also called _transaction hash_) of a transaction is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of `CHAIN_ID` and the
[serialized transaction](../tx-format/transaction.md) with [fields zeroed out for signing](../tx-format/index.md)
(see different inputs and outputs for which fields are set to zero), and without witness data. In other words, only
all non-witness data is hashed.

```python
sha256(CHAIN_ID ++ serialized_tx(tx))
```


---

### File: docs/fuel-specs/src/identifiers/utxo-id.md

# UTXO ID

## Coin ID

Is represented as an _outpoint_: a pair of [transaction ID](./transaction-id.md) as `byte[32]` and output index as a `uint16`.

## Message ID

The ID of a message is computed as the [hash](../protocol/cryptographic-primitives.md#hashing) of:

1. the sender address as `byte[32]`,
1. the recipient address as `byte[32]`,
1. the [Message nonce](#message-nonce) as `byte[32]`,
1. the amount being sent with the message as `uint64`,
1. the message data as `byte[]`

`hash(byte[32] ++ byte[32] ++ byte[32] ++ uint64 ++ byte[])`. The address values are serialized as a byte array of length 32 left-padded with zeroes, and all other value types are serialized according to the standard [transaction serialization](../tx-format/transaction.md). Note that the message data length is not included since there is only one dynamically sized field and can be implicitly determined by the hash preimage size.

### Message Nonce

The nonce value for `InputMessage` is determined by the sending system and is published at the time the message is sent. The nonce value for `OutputMessage` is computed as the [hash](../protocol/cryptographic-primitives.md#hashing) of the [Transaction ID](./transaction-id.md) that emitted the message and the index of the message receipt `uint16` (with canonical encoding): `hash(byte[32] ++ canonical(uint16))`.

## Fee ID

The UTXO ID of collected fees in a block is the block height as a 32-byte big-endian unsigned integer (i.e. the first byte of the 32-byte array is the most significant byte, and so on).


---

### File: docs/fuel-specs/src/index.md

# Fuel Specifications

<!-- markdownlint-disable-next-line MD036 -->
**Fuel: A Secure Decentralized Generalized Massively Scalable Transaction Ledger**

This book specifies the Fuel protocol, including the Fuel Virtual Machine
(short: FuelVM), a blazingly fast verifiable blockchain virtual machine.

## Protocol

- [**Transaction Format**](./tx-format/index.md) - The Fuel transaction format.
- [**Computing Identifiers**](./identifiers/index.md) - Computing unique IDs for transactions, contracts and UTXOs.
- [**Transaction Validity**](./protocol/tx-validity.md) - Defines transaction validity rules.
- [**Cryptographic Primitives**](./protocol/cryptographic-primitives.md) - Cryptographic primitives used in Fuel.
- [**Application Binary Interface (ABI)**](./abi/index.md) - Low-level details on interfacing with Fuel bytecode.
- [**Storage Slot Initialization**](./protocol/storage-initialization.md) - JSON format for contract storage slot initialization.
- [**Block Header Format**](./protocol/block-header.md) - The Fuel block header format.
- [**Relayer/Bridge**](./protocol/relayer.md) - The Fuel relayer/bridge protocol.

## FuelVM

- [**Overview**](./fuel-vm/index.md) - Describes the FuelVM at a high level, from its architecture to how it is initialized.
- [**Instruction Set**](./fuel-vm/instruction-set.md) - Defines the FuelVM instruction set.

## Network-Specific

- [**Proof of Authority (PoA)**](./networks/poa.md) - The Fuel Proof of Authority Network.

## Testing

- [**Sparse Merkle Tree**](./tests/sparse-merkle-tree-tests.md) - A test suite for verifying correctness of SMT outputs.


---

### File: docs/fuel-specs/src/networks/index.md

# Networks

Specifications for network-specific components of the protocol.

- [PoA Network](./poa.md)


---

### File: docs/fuel-specs/src/networks/poa.md

# PoA Network

## Consensus Header

Wraps the [application header](../protocol/block-header.md#application-header).

name              | type       | description
------------------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------
`prevRoot`        | `byte[32]` | [Merkle root](../protocol/cryptographic-primitives.md#binary-merkle-tree) of all previous consensus header hashes (i.e. not including this block).
`height`          | `uint32`   | Height of this block.
`timestamp`       | `uint64`   | Time this block was created, in [TAI64](https://cr.yp.to/libtai/tai64.html) format.
`applicationHash` | `byte[32]` | [Hash](../protocol/cryptographic-primitives.md#hashing) of serialized [application header](../protocol/block-header.md#application-header) for this block.

Consensus for the consensus header is a single [signature](../protocol/cryptographic-primitives.md#public-key-cryptography) from the authority over the [hash](../protocol/cryptographic-primitives.md#hashing) of the serialized consensus header.

Since the system is secure under the assumption the authority is honest, there is no need for committing to the authority signatures in the header.


---

### File: docs/fuel-specs/src/protocol/block-header.md

# Block Header

## Application Header

The application header is a network-agnostic block header. Different [networks](../networks/index.md) may wrap the application header in a consensus header, depending on their consensus protocol.

| name                             | type       | description                                                                                                                                                                                                                                         |
|----------------------------------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `da_height`                      | `uint64`   | Height of the data availability layer up to which (inclusive) input messages are processed.                                                                                                                                                         |
| `consensusParametersVersion`     | `uint32`   | The version of the consensus parameters used to execute this block.                                                                                                                                                                                 |
| `stateTransitionBytecodeVersion` | `uint32`   | The version of the state transition bytecode used to execute this block.                                                                                                                                                                            |
| `txCount`                        | `uint16`   | Number of [transaction](../tx-format/transaction.md)s in this block.                                                                                                                                                                                |
| `message_receipt_count`          | `uint32`   | Number of [output message](../abi/receipts.md#messageout-receipt)s in this block.                                                                                                                                                                   |
| `txRoot`                         | `byte[32]` | [Merkle root](./cryptographic-primitives.md#binary-merkle-tree) of [transaction](../tx-format/transaction.md)s in this block.                                                                                                                       |
| `message_outbox_root`            | `byte[32]` | [Merkle root](./cryptographic-primitives.md#binary-merkle-tree) of [output message](../abi/receipts.md#messageout-receipt)s [`messageId`](../identifiers/utxo-id.md#message-id) in this block.                                                      |
| `event_inbox_root`               | `byte[32]` | [Merkle root](./cryptographic-primitives.md#binary-merkle-tree) of all [events](./relayer.md) imported from L1 in this block. The order of the events added to the Merkle tree is the L1 block order, and the index of each event within each block |


---

### File: docs/fuel-specs/src/protocol/cryptographic-primitives.md

# Cryptographic Primitives

- [Hashing](#hashing)
- [Merkle Trees](#merkle-trees)
  - [Binary Merkle Tree](#binary-merkle-tree)
  - [Sparse Merkle Tree](#sparse-merkle-tree)
- [EcDSA Public-Key Cryptography](#ecdsa-public-key-cryptography)
- [EdDSA Public-Key Cryptography](#eddsa-public-key-cryptography)

## Hashing

All hashing is done with SHA-2-256 (also known as SHA-256), defined in [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).

## `HashDigest`

Output of the [hashing](#hashing) function. Exactly 256 bits (32 bytes) long.

## Merkle Trees

Two Merkle tree structures are used: a Binary Merkle Tree (to commit to bytecode) and a Sparse Merkle Tree (to commit to contract storage, i.e. state).

### Binary Merkle Tree

Binary Merkle trees are constructed in the same fashion as described in [Certificate Transparency (RFC-6962)](https://tools.ietf.org/html/rfc6962), except for using [a different hashing function](#hashing). Leaves are hashed once to get leaf node values and internal node values are the hash of the concatenation of their children (either leaf nodes or other internal nodes).

Nodes contain a single field:

| name | type                      | description |
|------|---------------------------|-------------|
| `v`  | [`HashDigest`](#hashdigest) | Node value. |

The base case (an empty tree) is defined as the [hash](#hashing) of the empty string:

```C++
node.v = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```

For leaf node `node` of leaf data `d`:

```C++
node.v = h(0x00, serialize(d))
```

For internal node `node` with children `l` and `r`:

```C++
node.v = h(0x01, l.v, r.v)
```

Note that rather than duplicating the last node if there are an odd number of nodes (the [Bitcoin design](https://github.com/bitcoin/bitcoin/blob/5961b23898ee7c0af2626c46d5d70e80136578d3/src/consensus/merkle.cpp#L9-L43)), trees are allowed to be imbalanced. In other words, the height of each leaf may be different. For an example, see Section 2.1.3 of [Certificate Transparency (RFC-6962)](https://tools.ietf.org/html/rfc6962#section-2.1.3).

Leaves and internal nodes are hashed differently: the one-byte `0x00` is prepended for leaf nodes while `0x01` is prepended for internal nodes. This avoids a second-preimage attack [where internal nodes are presented as leaves](https://en.wikipedia.org/wiki/Merkle_tree#Second_preimage_attack) trees with leaves at different heights.

#### Binary Merkle Tree Inclusion Proofs

| name       | type                          | description                                                     |
|------------|-------------------------------|-----------------------------------------------------------------|
| `root`     | [`HashDigest`](#hashdigest)`[]` | The expected root of the Merkle tree.                           |
| `data`     | Bytes                         | The data of the leaf (unhashed).                                |
| `siblings` | [`HashDigest`](#hashdigest)`[]` | Sibling hash values, ordered starting from the leaf's neighbor. |

A proof for a leaf in a [binary Merkle tree](#binary-merkle-tree), as per Section 2.1.1 of [Certificate Transparency (RFC-6962)](https://tools.ietf.org/html/rfc6962#section-2.1.1).

In some contexts, the array of sibling hashes is also known as the proof set. Note that proof format prescribes that leaf data be in its original, unhashed state, while the proof set (array of sibling data) uses hashed data. This format precludes the proof set from itself including the leaf data from the leaf undergoing the proof; rather, proof verification explicitly requires hashing the leaf data during the calculation of the proof set root.

### Sparse Merkle Tree

Sparse Merkle Trees (SMTs) are _sparse_, i.e. they contain mostly empty leaves. They can be used as key-value stores for arbitrary data, as each leaf is keyed by its index in the tree. Storage efficiency is achieved through clever use of implicit defaults, avoiding the need to store empty leaves.

Additional rules are added on top of plain [binary Merkle trees](#binary-merkle-tree):

1. Default values are given to leaf nodes with empty leaves.
1. While the above rule is sufficient to pre-compute the values of intermediate nodes that are roots of empty subtrees, a further simplification is to extend this default value to all nodes that are roots of empty subtrees. The 32-byte zero, i.e. `0x0000000000000000000000000000000000000000000000000000000000000000`, is used as the default value. This rule takes precedence over the above one.
1. The number of hashing operations can be reduced to be logarithmic in the number of non-empty leaves on average, assuming a uniform distribution of non-empty leaf keys. An internal node that is the root of a subtree that contains exactly one non-empty leaf is replaced by that leaf's leaf node.

Nodes contain a single field:

| name | type                      | description |
|------|---------------------------|-------------|
| `v`  | [`HashDigest`](#hashdigest) | Node value. |

In the base case, where a sparse Merkle tree has `height = 0`, the root of a tree is defined as the [hash](#hashing) of the empty string:

```C++
node.v = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```

When a sparse Merkle tree has a height of 0, it can have no leaves, and, therefore, no default value children. The root is then calculated as the hash of the empty string, similar to that of an empty binary Merkle tree.

For a tree with `height > 0`, the root of an empty tree is defined as the default value:

```C++
node.v = 0x0000000000000000000000000000000000000000000000000000000000000000
```

Note that this is in contrast to the base case of the sparse and binary Merkle trees, where the root is the hash of the empty string. When a sparse Merkle tree has a height greater than 0, a new tree instance is composed of default value leaves. Nodes containing only default value children have the default value as well. Applying these rules recursively percolates the default value up to the tree's root.

For leaf node `node` of leaf data `d` with key `k`:

```C++
node.v = h(0x00, k, h(serialize(d)))
```

The key of leaf nodes must be prepended, since the index of a leaf node that is not at maximum depth cannot be determined without this information. Leaf values are hashed so that they do not need to be included in full in non-membership proofs.

For internal node `node` with children `l` and `r`:

```C++
node.v = h(0x01, l.v, r.v)
```

#### Insertion

Before insertion of the key-value pair, each key of the Sparse Merkle Tree should be hashed with `sha256` to prevent tree structure manipulations.
During the proof verification, the original leaf key should be hashed similarly. Otherwise, the root will not match.

#### Sparse Merkle Tree Inclusion Proofs

SMTs can further be extended with _compact_ proofs. Merkle proofs are composed, among other things, of a list of sibling node values. We note that, since nodes that are roots of empty subtrees have known values (the default value), these values do not need to be provided explicitly; it is sufficient to simply identify which siblings in the Merkle branch are roots of empty subtrees, which can be done with one bit per sibling.

For a Merkle branch of height `h`, an `h`-bit value is appended to the proof. The lowest bit corresponds to the sibling of the leaf node, and each higher bit corresponds to the next parent. A value of `1` indicates that the next value in the list of values provided explicitly in the proof should be used, and a value of `0` indicates that the default value should be used.

A proof into an SMT is structured as:

| name               | type                          | description                                                              |
|--------------------|-------------------------------|--------------------------------------------------------------------------|
| `depth`            | `uint16`                      | Depth of the leaf node. The root node is at depth `0`. Must be `<= 256`. |
| `siblings`         | [`HashDigest`](#hashdigest)`[]` | Sibling hash values, ordered starting from the leaf's neighbor.          |
| `includedSiblings` | `byte[32]`                    | Bitfield of explicitly included sibling hashes.                          |

The `includedSiblings` is ordered by most-significant-byte first, with each byte ordered by most-significant-bit first. The lowest bit corresponds to the leaf node level.

A specification describing a suite of test vectors and outputs of a Sparse Merkle Tree is [here](../tests/sparse-merkle-tree-tests.md).

## ECDSA Public-Key Cryptography

Consensus-critical data is authenticated using [ECDSA](https://www.secg.org/sec1-v2.pdf), with the curve [secp256k1](https://en.bitcoin.it/wiki/Secp256k1). A highly-optimized library is available in [C](https://github.com/bitcoin-core/secp256k1), with wrappers in [Go](https://pkg.go.dev/github.com/ethereum/go-ethereum/crypto/secp256k1) and [Rust](https://docs.rs/crate/secp256k1).

Public keys are encoded in uncompressed form, as the concatenation of the `x` and `y` values. No prefix is needed to distinguish between encoding schemes as this is the only encoding supported.

Deterministic signatures ([RFC-6979](https://www.rfc-editor.org/rfc/rfc6979)) should be used when signing, but this is not enforced at the protocol level as it cannot be.

Signatures are represented as the `r` and `s` (each 32 bytes), and `v` (1-bit) values of the signature. `r` and `s` take on their usual meaning (see: [SEC 1, 4.1.3 Signing Operation](https://www.secg.org/sec1-v2.pdf)), while `v` is used for recovering the public key from a signature more quickly (see: [SEC 1, 4.1.6 Public Key Recovery Operation](https://www.secg.org/sec1-v2.pdf)). Only low-`s` values in signatures are valid (i.e. `s <= secp256k1.n//2`); `s` can be replaced with `-s mod secp256k1.n` during the signing process if it is high. Given this, the first bit of `s` will always be `0`, and can be used to store the 1-bit `v` value.

`v` represents the parity of the `Y` component of the point, `0` for even and `1` for odd. The `X` component of the point is assumed to always be low, since [the possibility of it being high is negligible](https://bitcoin.stackexchange.com/a/38909).

Putting it all together, the encoding for signatures is:

<!-- markdownlint-disable-next-line MD040 -->
```
|    32 bytes   ||           32 bytes           |
[256-bit r value][1-bit v value][255-bit s value]
```

This encoding scheme is derived from [EIP 2098: Compact Signature Representation](https://eips.ethereum.org/EIPS/eip-2098).

## EdDSA Public-Key Cryptography

[Ed25519](https://datatracker.ietf.org/doc/html/rfc8032) is supported for use by applications built on Fuel. Edwards curve operations are performed by the [ed25519-dalek](https://github.com/dalek-cryptography/ed25519-dalek) Rust library.

Public keys are encoded in compressed form as specified by the Ed25519 format [RFC-8032 5.1.5](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5). Point compression is performed by replacing the most significant bit in the final octet of the `y` coordinate with the sign bit from the `x` coordinate:

```rust
let mut pk = y;
pk ^= x.is_negative().unwrap_u8() << 7;
```

Public keys are required to be strong enough to prevent malleability, and are checked for weakness during signature verification.

Signatures are 64 bytes, represented as the concatenation of `R` (32 bytes) and `S` (32 bytes) Where `R` and `S` are defined in [RFC-8032 5.1.6](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.6).

Signatures must conform to strict [verification requirements](https://github.com/dalek-cryptography/ed25519-dalek#validation-criteria) to avoid malleability concerns. While this is not part of the original Ed25519 specification, it has become a growing concern especially in cryptocurrency applications.


---

### File: docs/fuel-specs/src/protocol/index.md

# Protocol

- [Transaction Validity](./tx-validity.md)
- [Cryptographic Primitives](./cryptographic-primitives.md)
- [Storage Slot Initialization](./storage-initialization.md)
- [Block Header Format](./block-header.md)
- [Relayer/Bridge](./relayer.md)


---

### File: docs/fuel-specs/src/protocol/relayer.md

# Layer 1 Relayer/Bridge Protocol

The Fuel relayer/bridge protocol is a set of rules that govern the interaction between the Fuel blockchain and the
Layer 1 (L1) blockchain (e.g. Ethereum).  

The Fuel blockchain can emit messages that will be processed by the smart contract on the L1 blockchain. The smart
contract on the L1 can also emit events that will be processed by the Fuel blockchain.
This is used to move any data between the L1 blockchain and the Fuel blockchain.

## Fuel Message Outbox

The message outbox is the set of messages sent to the L1 blockchain from the Fuel blockchain.

## Fuel Event Inbox

The event inbox is the set of events received from the L1 blockchain by the Fuel blockchain.

The block producer will receive a list of events from the L1 by some relayer, and then include the
merkle root of the events in the block header.

There are two types of events that can be received from the L1:

1. Messages
2. Transactions

### Messages

An arbitrary message sent from the L1 to the Fuel blockchain. This can be used to move assets from the L1
to the Fuel blockchain or send other arbitrary information to the Fuel blockchain.

| name        | type    | description                                                         |
|-------------|---------|---------------------------------------------------------------------|
| `sender`    | `bytes[32]` | The identity of the sender of the message on the L1                 |
| `recipient` | `bytes[32]` | The recipient of the message on the Fuel Blockchain                 |
| `nonce`     | `bytes[32]` | Unique identifier of the message assigned by the L1 contract                                 |
| `amount`    | `uint64`  | The amount of the base asset transfer                              |
| `data`      | `byte[]`  | Arbitrary message data                                              |

### Transactions

These are transactions that are submitted on the L1 that must be executed on the Fuel blockchain.
This "Forced Transaction Inclusion" is a security feature that allows participants of the Fuel Blockchain to access
their funds in the (unlikely) event that the Fuel blockchain block production is compromised or malicious, e.g. the
block producer is censoring transactions.

| name                     | type      | description                                                                                                                               |
|--------------------------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------|
| `nonce`                  | `bytes[32]` | Unique identifier of the transaction assigned by the L1                                                                          contract |
| `max_gas`                | `uint64`   | The maximum amount of gas allowed to use on  Fuel Blockchain                                                                              |
| `serialized_transaction` | `byte[]`   | The serialized transaction bytes following canonical serialization                                                                        |

The `serialized_transaction` can be any [transaction variant](../tx-format/transaction.md) except the `Mint` transaction, which
is only ever created by the block producer. `Mint` transactions will be rejected by the Fuel blockchain if they are relayed
from the L1.

### Ordering

It is important that the L1 events are ordered correctly when they are relayed to the Fuel blockchain. The events will
be ordered by the L1 block height and then by the index of the event within the block.

The order is important because a merkle root will be generated each time events from L1 are included in a Fuel block.
This merkle root can later be used to prove that an arbitrary event was included on that block without having to store
every event on the block header explicitly. Just the merkle root will be on the [block header](./block-header.md).
The order of the events affects the value of the merkle root.


---

### File: docs/fuel-specs/src/protocol/storage-initialization.md

# JSON Format for Contract Storage Initializers

Contracts can request that certain storage slots are initialized to specific values. These initialized slots are represented in JSON format as an array where each element represents a storage slot and has the following properties:

- `"key"`: String, a 32-byte key for a given storage slot;
- `"value"`: String, a 32-byte value that initializes the slot;

For instance, the following is a JSON object that requests that the 3 storage slots with keys `0x11..11`, `0x22..22`, and `0x33..33`, are respectively initialized to the values indicated.

```json
[
  {
    "key": "0x1111111111111111111111111111111111111111111111111111111111111111",
    "value": "0x1010101010101010101010101010101010101010101010101010101010101010"
  }, 
  {
    "key": "0x2222222222222222222222222222222222222222222222222222222222222222",
    "value": "0x2020202020202020202020202020202020202020202020202020202020202020"
  },
  {
    "key": "0x3333333333333333333333333333333333333333333333333333333333333333",
    "value": "0x0303030303030303030303030303030303030303030303030303030303030303"
  },
]
```


---

### File: docs/fuel-specs/src/protocol/tx-validity.md

# Transaction Validity

- [Transaction Life Cycle](#transaction-life-cycle)
- [Access Lists](#access-lists)
- [VM Precondition Validity Rules](#vm-precondition-validity-rules)
  - [Base Sanity Checks](#base-sanity-checks)
  - [Spending UTXOs and Created Contracts](#spending-utxos-and-created-contracts)
  - [Sufficient Balance](#sufficient-balance)
  - [Valid Signatures](#valid-signatures)
- [Predicate Verification](#predicate-verification)
- [Script Execution](#script-execution)
- [VM Postcondition Validity Rules](#vm-postcondition-validity-rules)
  - [Correct Change](#correct-change)
  - [State Changes](#state-changes)

## Transaction Life Cycle

Once a transaction is seen, it goes through several stages of validation, in this order:

1. [Pre-checks](#vm-precondition-validity-rules)
1. [Predicate verification](#predicate-verification)
1. [Script execution](#script-execution)
1. [Post-checks](#vm-postcondition-validity-rules)

## Access Lists

The validity rules below assume sequential transaction validation for side effects (i.e. state changes). However, by construction, transactions with disjoint write access lists can be validated in parallel, including with overlapping read-only access lists. Transactions with overlapping write access lists must be validated and placed in blocks in topological order.

UTXOs and contracts in the read-only and write-destroy access lists must exist (i.e. have been created previously) in order for a transaction to be valid. In other words, for a unique state element ID, the write-create must precede the write-destroy.

Read-only access list:

Write-destroy access list:

- For each [input `InputType.Coin`](../tx-format/input.md#inputcoin)
  - The [UTXO ID](../identifiers/utxo-id.md) `(txId, outputIndex)`
- For each [input `InputType.Contract`](../tx-format/input.md#inputcontract)
  - The [UTXO ID](../identifiers/utxo-id.md) `(txId, outputIndex)`
- For each [input `InputType.Message`](../tx-format/input.md#inputmessage)
  - The [message ID](../identifiers/utxo-id.md#message-id) `messageID`

Write-create access list:

- For each [output `OutputType.ContractCreated`](../tx-format/output.md#outputcontractcreated)
  - The contract ID `contractID`
- For each output
  - The [created UTXO ID](../identifiers/utxo-id.md)

Note that block proposers use the contract ID `contractID` for inputs and outputs of type [`InputType.Contract`](../tx-format/input.md#inputcontract) and [`OutputType.Contract`](../tx-format/output.md#outputcontract) rather than the pair of `txId` and `outputIndex`.

## VM Precondition Validity Rules

This section defines _VM precondition validity rules_ for transactions: the bare minimum required to accept an unconfirmed transaction into a mempool, and preconditions that the VM assumes to hold prior to execution. Chains of unconfirmed transactions are omitted.

For a transaction `tx`, UTXO set `state`, contract set `contracts`, and message set `messages`, the following checks must pass.

> **Note:** [`InputMessages`](../tx-format/input.md#inputmessage) where `input.dataLength > 0` are not dropped from the `messages` message set until they are included in a transaction of type `TransactionType.Script` with a `ScriptResult` receipt where `result` is equal to `0` indicating a successful script exit.

### Base Sanity Checks

Base sanity checks are defined in the [transaction format](../tx-format/index.md).

### Spending UTXOs and Created Contracts

```py
for input in tx.inputs:
    if input.type == InputType.Contract:
        if not input.contractID in contracts:
                return False
    elif input.type == InputType.Message:
        if not input.nonce in messages:
                return False
    else:
        if not (input.txId, input.outputIndex) in state:
            return False
return True
```

If this check passes, the UTXO ID `(txId, outputIndex)` fields of each contract input is set to the UTXO ID of the respective contract. The `txPointer` of each input is also set to the TX pointer of the UTXO with ID `utxoID`.

### Sufficient Balance

For each asset ID `assetId` in the input and output set:

```py
def gas_to_fee(gas, gasPrice) -> int:
    """
    Converts gas units into a fee amount
    """
    return ceil(gas * gasPrice / GAS_PRICE_FACTOR)


def sum_data_messages(tx, assetId) -> int:
    """
    Returns the total balance available from messages containing data
    """
    total: int = 0
    if assetId == 0:
        for input in tx.inputs:
            if input.type == InputType.Message and input.dataLength > 0:
                total += input.amount
    return total


def sum_inputs(tx, assetId) -> int:
    total: int = 0
    for input in tx.inputs:
        if input.type == InputType.Coin and input.assetId == assetId:
            total += input.amount
        elif input.type == InputType.Message and assetId == 0 and input.dataLength == 0:
            total += input.amount
    return total


def transaction_size_gas_fees(tx) -> int:
    """
    Computes the intrinsic gas cost of a transaction based on size in bytes
    """
    return size(tx) * GAS_PER_BYTE


def minted(tx, assetId) -> int:
    """
    Returns any minted amounts by the transaction
    """
    if tx.type != TransactionType.Mint or assetId != tx.mintAssetId:
        return 0
    return tx.mint_amount


def sum_outputs(tx, assetId) -> int:
    total: int = 0
    for output in tx.outputs:
        if output.type == OutputType.Coin and output.assetId == assetId:
            total += output.amount
    return total


def input_gas_fees(tx) -> int:
    """
    Computes the intrinsic gas cost of verifying input utxos
    """
    total: int = 0
    witnessIndices = set()
    for input in tx.inputs:
        if input.type == InputType.Coin or input.type == InputType.Message:
            # add fees allocated for predicate execution
            if input.predicateLength == 0:
                # notate witness index if input is signed
                witnessIndices.add(input.witnessIndex)
            else:
                # add intrinsic gas cost of predicate merkleization based on number of predicate bytes
                total += contract_code_root_gas_fee(input.predicateLength)
                total += input.predicateGasUsed
                # add intrinsic cost of vm initialization
                total += vm_initialization_gas_fee()
    # add intrinsic cost of verifying witness signatures
    total += len(witnessIndices) * eck1_recover_gas_fee()
    return total


def metadata_gas_fees(tx) -> int:
    """
    Computes the intrinsic gas cost of processing transaction outputs
    
    The `contract_code_root_gas_fee`, `sha256_gas_fee`, and `contract_state_root_gas_fee` 
    are based on the benchmarked gas costs of these operations.
    
    Consensus parameters contain definitions of gas costs for all operations and opcodes in the network.
    """
    total: int = 0
    if tx.type == TransactionType.Create:
        for output in tx.outputs:
            if output.type == OutputType.OutputContractCreated:
                # add intrinsic cost of calculating the code root based on the size of the contract bytecode
                total += contract_code_root_gas_fee(tx.witnesses[tx.bytecodeWitnessIndex].dataLength)
                # add intrinsic cost of calculating the state root based on the number of sotrage slots
                total += contract_state_root_gas_fee(tx.storageSlotCount)
                # add intrinsic cost of calculating the contract id 
                # size = 4 byte seed + 32 byte salt + 32 byte code root + 32 byte state root
                total += sha256_gas_fee(100)
    elif tx.type == TransactionType.Upgrade:
        if tx.upgradePurpose.type == UpgradePurposeType.ConsensusParameters:
            # add intrinsic cost of calculating the consensus parameters hash
            total += sha256_gas_fee(size(tx.witnesses[tx.upgradePurpose.witnessIndex].data))
    elif tx.type == TransactionType.Upload:
        # add intrinsic cost of calculating the root based on the number of bytecode subsections
        total += contract_state_root_gas_fee(tx.subsectionsNumber)
        # add intrinsic cost of hashing the subsection for verification of the connection with Binary Merkle tree root
        total += sha256_gas_fee(size(tx.witnesses[tx.witnessIndex]))
            
    if tx.type != TransactionType.Mint:
        # add intrinsic cost of calculating the transaction id
        total += sha256_gas_fee(size(tx))
    return total


def intrinsic_gas_fees(tx) -> int:
    """
    Computes intrinsic costs for a transaction
    """
    fees: int = 0
    # add the cost of initializing a vm for the script
    if tx.type == TransactionType.Create or tx.type == TransactionType.Script:
        fees += vm_initialization_gas_fee()
        fees += metadata_gas_fees(tx)
        fees += intrinsic_input_gas_fees(tx)
    return fees


def min_gas(tx) -> int:
    """
    Comutes the minimum amount of gas required for a transaction to begin processing.
    """
    gas = transaction_size_gas_fees(tx) + intrinsic_gas_fees(tx)
    if tx.type == TransactionType.Upload
        # charge additionally for storing bytecode on chain
        gas += transaction_size_gas_fees(size(tx.witnesses[tx.witnessIndex]))
        
    return gas


def max_gas(tx) -> int:
    """
    Computes the amount of gas required to process a transaction.
    """
    gas = min_gas(tx)
    gas = gas + (tx.witnessBytesLimit - tx.witnessBytes) * GAS_PER_BYTE
    if tx.type == TransactionType.Script:
       gas += tx.gasLimit
    return gas
    
    
def maxFee(tx, assetId, gasPrice) -> int:
    """
    Computes the maximum potential amount of fees that may need to be charged to process a transaction.
    """
    maxGas = max_gas(tx)
    feeBalance = gas_to_fee(maxGas, gasPrice)
    # Only base asset can be used to pay for gas
    if assetId == 0:
        return feeBalance
    else:
        return 0


def available_balance(tx, assetId) -> int:
    """
    Make the data message balance available to the script
    """
    availableBalance = sum_inputs(tx, assetId) + sum_data_messages(tx, assetId) + minted(tx, assetId)
    return availableBalance


def unavailable_balance(tx, assetId) -> int:
    sentBalance = sum_outputs(tx, assetId)
    # Total fee balance
    feeBalance = tx.policies.max_fee
    # Only base asset can be used to pay for gas
    if assetId == 0:
        return sentBalance + feeBalance
    return sentBalance


# The sum_data_messages total is not included in the unavailable_balance since it is spendable as long as there 
# is enough base asset amount to cover gas costs without using data messages. Messages containing data can't
# cover gas costs since they are retryable.
return available_balance(tx, assetId) >= (unavailable_balance(tx, assetId) + sum_data_messages(tx, assetId))
```

### Valid Signatures

```py
def address_from(pubkey: bytes) -> bytes:
    return sha256(pubkey)[0:32]

for input in tx.inputs:
    if (input.type == InputType.Coin or input.type == InputType.Message) and input.predicateLength == 0:
        # ECDSA signatures must be 64 bytes
        if tx.witnesses[input.witnessIndex].dataLength != 64:
            return False
        # Signature must be from owner
        if address_from(ecrecover_k1(txhash(), tx.witnesses[input.witnessIndex].data)) != input.owner:
            return False
return True
```

Signatures and signature verification are specified [here](./cryptographic-primitives.md#public-key-cryptography).

The transaction hash is computed as defined [here](../identifiers/transaction-id.md).

## Predicate Verification

For each input of type `InputType.Coin` or `InputType.Message`, and `predicateLength > 0`, [verify its predicate](../fuel-vm/index.md#predicate-verification).

## Script Execution

Given transaction `tx`, the following checks must pass:

If `tx.scriptLength == 0`, there is no script and the transaction defines a simple balance transfer, so no further checks are required.

If `tx.scriptLength > 0`, the script must be executed. For each asset ID `assetId` in the input set, the free balance available to be moved around by the script and called contracts is `freeBalance[assetId]`. The initial message balance available to be moved around by the script and called contracts is `messageBalance`:

```py
freeBalance[assetId] = available_balance(tx, assetId) - unavailable_balance(tx, assetId)
messageBalance = sum_data_messages(tx, 0)
```

Once the free balances are computed, the [script is executed](../fuel-vm/index.md#script-execution). After execution, the following is extracted:

1. The transaction in-memory on VM termination is used as the final transaction which is included in the block.
1. The unspent free balance `unspentBalance` for each asset ID.
1. The unspent gas `unspentGas` from the `$ggas` register.

`size(tx)` encompasses the entire transaction serialized according to the transaction format, including witness data.
This ensures every byte of block space either on Fuel or corresponding DA layer can be accounted for.

If the transaction as included in a block does not match this final transaction, the block is invalid.

### Fees

The cost of a transaction can be described by:

```py
def cost(tx, gasPrice) -> int:
    return gas_to_fee(min_gas(tx) + tx.gasLimit - unspentGas, gasPrice)
```

where:

- `min_gas(tx)` is the minimum cost of the transaction in gas, including intrinsic gas fees incurred from:
  - The number of bytes comprising the transaction
  - Processing inputs, including predicates
  - Processing outputs
  - VM initialization
- `unspentGas` is the amount gas left over after intrinsic fees and execution of the transaction, extracted from the `$ggas` register. Converting unspent gas to a fee describes how much "change" is left over from the user's payment; the block producer collects this unspent gas as reward.
- `gas_to_fee` is a function that converts gas to a concrete fee based on a given gas price.

Fees incurred by transaction processing outside the context of execution are collectively referred to as intrinsic fees. Intrinsic fees include the cost of storing the transaction, calculated on a per-byte basis, the cost of processing inputs and outputs, including predicates and signature verification, and initialization of the VM prior to any predicate or script execution. Because intrinsic fees are independent of execution, they can be determined _a priori_ and represent the bare minimum cost of the transaction.

A naturally occurring result of a variable gas limit is the concept of minimum and maximum fees. The minimum fee is, thus, the exact fee required to pay the fee balance, while the maximum fee is the minimum fee plus the gas limit:

```py
min_gas = min_gas(tx)
max_gas = min_gas + (tx.witnessBytesLimit - tx.witnessBytes) * GAS_PER_BYTE + tx.gasLimit
min_fee = gas_to_fee(min_gas, gasPrice)
max_fee = gas_to_fee(max_gas, gasPrice)
```

The cost of the transaction `cost(tx)` must lie within the range defined by [`min_fee`, `max_fee`]. `min_gas` is defined as the sum of all intrinsic costs of the transaction known prior to execution. The definition of `max_gas` illustrates that the delta between minimum gas and maximum gas is the sum of:

- The remaining allocation of witness bytes, converted to gas
- The user-defined `tx.gasLimit`

Note that `gasLimit` applies to transactions of type `Script`. `gasLimit` is not applicable for transactions of type `Create` and is defined to equal `0` in the above formula.

A transaction cost `cost(tx)`, in gas, greater than `max_gas` is invalid and must be rejected; this signifies that the user must provide a higher gas limit for the given transaction. `min_fee` is the minimum reward the producer is guaranteed to collect, and `max_fee` is the maximum reward the producer is potentially eligible to collect. In practice, the user is always charged intrinsic fees; thus, `unspentGas` is the remainder of `max_gas` after intrinsic fees and the variable cost of execution. Calculating a conversion from `unspentGas` to an unspent fee describes the reward the producer will collect in addition to `min_fee`.

## VM Postcondition Validity Rules

This section defines _VM postcondition validity rules_ for transactions: the requirements for a transaction to be valid after it has been executed.

Given transaction `tx`, state `state`, and contract set `contracts`, the following checks must pass.

### Correct Change

If change outputs are present, they must have:

- if the transaction does not revert;
  - if the asset ID is `0`; an `amount` of `unspentBalance + floor((unspentGas * gasPrice) / GAS_PRICE_FACTOR)`
  - otherwise; an `amount` of the unspent free balance for that asset ID after VM execution is complete
- if the transaction reverts;
  - if the asset ID is `0`; an `amount` of the initial free balance plus `(unspentGas * gasPrice) - messageBalance`
  - otherwise; an `amount` of the initial free balance for that asset ID.

### State Changes

Transaction processing is completed by removing spent UTXOs from the state and adding created UTXOs to the state.

### Coinbase Transaction

The coinbase transaction is a mechanism for block creators to collect transaction fees.

In order for a coinbase transaction to be valid:

1. It must be a [Mint](../tx-format/transaction.md#TransactionMint) transaction.
1. The coinbase transaction must be the last transaction within a block, even if there are no other transactions in the block and the fee is zero.
1. The `mintAmount` doesn't exceed the total amount of fees processed from all other transactions within the same block.
1. The `mintAssetId` matches the `assetId` that fees are paid in (`assetId == 0`).

The minted amount of the coinbase transaction intrinsically increases the balance corresponding to the `inputContract`.
This means the balance of `mintAssetId` is directly increased by `mintAmount` on the input contract,
without requiring any VM execution. Compared to coin outputs, intrinsically increasing a contract balance to collect
coinbase amounts prevents the accumulation of dust during low-usage periods.


---

### File: docs/fuel-specs/src/tests/index.md

# Testing

Test suites for verifying the correctness of a Fuel implementation.

- [Sparse Merkle Tree Tests](./sparse-merkle-tree-tests.md)


---

### File: docs/fuel-specs/src/tests/sparse-merkle-tree-tests.md

# Sparse Merkle Tree Test Specifications

## Version

0.1.1

Last updated 2022/07/11

## Abstract

This document outlines a test suite specification that can be used to verify the correctness of a Sparse Merkle Tree's outputs. The scope of this document covers only Sparse Merkle Tree (SMT) implementations that are compliant with [Celestia Sparse Merkle Tree Specification](https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/data_structures.md#sparse-merkle-tree). The goal of this document is to equip SMT library developers with a supplemental indicator of correctness. Libraries implementing an SMT can additionally implement this test suite specification in the code base's native language. Passing all tests in the concrete test suite is an indication of correctness and consistency with the reference specification; however, it is not an absolute guarantee.

The tests described in this document are designed to test features common to most Sparse Merkle Tree implementations. Test specifications are agnostic of the implementation details or language, and therefore take a black-box testing approach. A test specification may provide an example of what a compliant test may look like in the form of pseudocode.

A test specification follows the format:

- Test name
- Test description
- Test inputs
- Test outputs
- Example pseudocode

For a concrete test to comply with its corresponding test specification, the System Under Test (SUT) must take in the prescribed inputs. When the SUT produces the prescribed outputs, the test passes. When the SUT produces any result or error that is not prescribed by the specification, the test fails. For a library to comply with the complete specification described herein, it must implement all test specifications, and each test must pass.

All test specifications assume that the Merkle Tree implementation under test uses the SHA-2-256 hashing algorithm as defined in [FIPS PUB 180-4](https://doi.org/10.6028/NIST.FIPS.180-4) to produce its outputs. The following test cases stipulate a theoretical function `Sum(N)` that takes in a big endian data slice `N` and returns the 32 byte SHA-256 hash of `N`.

## Root Signature Tests

1. [Test Empty Root](#test-empty-root)
2. [Test Update 1](#test-update-1)
3. [Test Update 2](#test-update-2)
4. [Test Update 3](#test-update-3)
5. [Test Update 5](#test-update-5)
6. [Test Update 10](#test-update-10)
7. [Test Update 100](#test-update-100)
8. [Test Update With Repeated Inputs](#test-update-with-repeated-inputs)
9. [Test Update Overwrite Key](#test-update-overwrite-key)
10. [Test Update Union](#test-update-union)
11. [Test Update Sparse Union](#test-update-sparse-union)
12. [Test Update With Empty Data](#test-update-with-empty-data)
13. [Test Update With Empty Data Performs Delete](#test-update-with-empty-data-performs-delete)
14. [Test Update 1 Delete 1](#test-update-1-delete-1)
15. [Test Update 2 Delete 1](#test-update-2-delete-1)
16. [Test Update 10 Delete 5](#test-update-10-delete-5)
17. [Test Delete Non-existent Key](#test-delete-non-existent-key)
18. [Test Interleaved Update Delete](#test-interleaved-update-delete)
19. [Test Delete Sparse Union](#test-delete-sparse-union)

---

### Test Empty Root

**Description**:

Tests the default root given no update or delete operations. The input set is described by `S = {Ø}`.

**Inputs**:

_No inputs_.

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 1

**Description**:

Tests the root after performing a single update call with the specified input.

**Inputs**:

1. Update the empty tree with `(K, D)` where leaf key `K = Sum(0u32)` (32 bytes) and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
root = smt.root()
expected_root = '39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 2

**Description**:

Tests the root after performing two update calls with the specified inputs.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x8d0ae412ca9ca0afcb3217af8bcd5a673e798bd6fd1dfacad17711e883f494cb`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x01"), b"DATA")
root = smt.root()
expected_root = '8d0ae412ca9ca0afcb3217af8bcd5a673e798bd6fd1dfacad17711e883f494cb'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 3

**Description**:

Tests the root after performing three update calls with the specified inputs.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. Update the tree with `(K, D)`, where leaf key `K = Sum(2u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x52295e42d8de2505fdc0cc825ff9fead419cbcf540d8b30c7c4b9c9b94c268b7`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x01"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x02"), b"DATA")
root = smt.root()
expected_root = '52295e42d8de2505fdc0cc825ff9fead419cbcf540d8b30c7c4b9c9b94c268b7'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 5

**Description**:

Tests the root after performing five update calls with the specified inputs.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. Update the tree with `(K, D)`, where leaf key `K = Sum(2u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
4. Update the tree with `(K, D)`, where leaf key `K = Sum(3u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
5. Update the tree with `(K, D)`, where leaf key `K = Sum(4u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 10

**Description**:

Tests the root after performing 10 update calls with the specified inputs.

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x21ca4917e99da99a61de93deaf88c400d4c082991cb95779e444d43dd13e8849`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '21ca4917e99da99a61de93deaf88c400d4c082991cb95779e444d43dd13e8849'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 100

**Description**:

Tests the root after performing 100 update calls with the specified inputs.

**Inputs**:

1. For each `i` in `0..100`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x82bf747d455a55e2f7044a03536fc43f1f55d43b855e72c0110c986707a23e4d`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..100 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '82bf747d455a55e2f7044a03536fc43f1f55d43b855e72c0110c986707a23e4d'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update With Repeated Inputs

**Description**:

Tests the root after performing two update calls with the same inputs. The resulting input set is described by `S = {A} U {A} = {A}`, where `{A}` is the input. This test expects a root signature identical to that produced by [Test Update 1](#test-update-1).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree again with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
root = smt.root()
expected_root = '39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update Overwrite Key

**Description**:

Tests the root after performing two update calls with the same leaf keys but different leaf data. The second update call is expected to overwrite the data originally written by the first update call.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"CHANGE"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0xdd97174c80e5e5aa3a31c61b05e279c1495c8a07b2a08bca5dbc9fb9774f9457`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x00"), b"CHANGE")
root = smt.root()
expected_root = 'dd97174c80e5e5aa3a31c61b05e279c1495c8a07b2a08bca5dbc9fb9774f9457'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update Union

**Description**:

Tests the root after performing update calls with discontinuous sets of inputs. The resulting input set is described by `S = [0..5) U [10..15) U [20..25)`.

**Inputs**:

1. For each `i` in `0..5`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `10..15`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. For each `i` in `20..25`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 10..15 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 20..25 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update Sparse Union

**Description**:

Tests the root after performing update calls with discontinuous sets of inputs. The resulting input set is described by `S = [0, 2, 4, 6, 8]`.

**Inputs**:

1. For each `i` in `0..5`, update the tree with `(K, D)`, where leaf key `K = Sum(i * 2)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0xe912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32 * 2).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = 'e912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update With Empty Data

**Description**:

Tests the root after performing one update call with empty data. Updating the empty tree with empty data does not change the root, and the expected root remains the default root. The resulting input set is described by `S = {Ø} U {Ø} = {Ø}`. This test expects a root signature identical to that produced by [Test Empty Root](#test-empty-root).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and empty leaf data `D = b""` (0 bytes)

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"")
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update With Empty Data Performs Delete

**Description**:

Tests the root after performing one update call with arbitrary data followed by a second update call on the same key with empty data. Updating a key with empty data is equivalent to calling delete. By deleting the only key, we have an empty tree and expect to arrive at the default root. The resulting input set is described by `S = {0} - {0} = {Ø}`. This test expects a root signature identical to that produced by [Test Empty Root](#test-empty-root).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(0u32)` and empty leaf data `D = b""` (0 bytes)

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x00"), b"")
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 1 Delete 1

**Description**:

Tests the root after performing one update call followed by a subsequent delete call on the same key. By deleting the only key, we have an empty tree and expect to arrive at the default root. The resulting input set is described by `S = {0} - {0} = {Ø}`. This test expects a root signature identical to that produced by [Test Empty Root](#test-empty-root).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Delete `(K)` from the tree, where leaf key `K = Sum(0u32)`  

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.delete(&sum(b"\x00\x00\x00\x00"))
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 2 Delete 1

**Description**:

Tests the root after performing two update calls followed by a subsequent delete call on the first key. By deleting the second key, we have a tree with only one key remaining, equivalent to a single update. This test expects a root signature identical to that produced by [Test Update 1](#test-update-1).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. Delete `(K)` from the tree, where leaf key `K = Sum(1u32)`

**Outputs**:

- The expected root signature: `0x39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x01"), b"DATA")
smt.delete(&sum(b"\x00\x00\x00\x01"))
root = smt.root()
expected_root = '39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 10 Delete 5

**Description**:

Tests the root after performing 10 update calls followed by 5 subsequent delete calls on the latter keys. By deleting the last five keys, we have a tree with the first five keys remaining, equivalent to five updates. This test expects a root signature identical to that produced by [Test Update 5](#test-update-5).

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `5..10`, delete `(K)` from the tree, where leaf key `K = Sum(i)`

**Outputs**:

- The expected root signature: `0x108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 5..10 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
root = smt.root()
expected_root = '108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Delete Non-existent Key

**Description**:

Tests the root after performing five update calls followed by a subsequent delete on a key that is not present in the input set. This test expects a root signature identical to that produced by [Test Update 5](#test-update-5).

**Inputs**:

1. For each `i` in `0..5`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Delete `(K)` from the tree, where leaf key `K = Sum(1024u32)`

**Outputs**:

- The expected root signature: `0x108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
smt.delete(&sum(b"\x00\x00\x04\x00"))

root = smt.root()
expected_root = '108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Interleaved Update Delete

**Description**:

Tests the root after performing a series of interleaved update and delete calls. The resulting input set is described by `[0..5) U [10..15) U [20..25)`. This test demonstrates the inverse relationship between operations `update` and `delete`. This test expects a root signature identical to that produced by [Test Update Union](#test-update-union).

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `5..15`, delete `(K)` from the tree, where leaf key `K = Sum(i)` from the tree
3. For each `i` in `10..20`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
4. For each `i` in `15..25`, delete `(K)` from the tree, where leaf key `K = Sum(i)` from the tree
5. For each `i` in `20..30`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
6. For each `i` in `25..35`, delete `(K)` from the tree, where leaf key `K = Sum(i)` from the tree

**Outputs**:

- The expected root signature: `0x7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 5..15 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
for i in 10..20 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 15..25 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
for i in 20..30 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 25..35 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
root = smt.root()
expected_root = '7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Delete Sparse Union

**Description**:

Tests the root after performing delete calls with discontinuous sets of inputs. The resulting input set is described by `S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - [1, 3, 5, 7, 9] = [0, 2, 4, 6, 8]`. This test expects a root signature identical to that produced by [Test Update Sparse Union](#test-update-sparse-union).

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `0..5`, delete `(K)` from the tree, where leaf key `K = Sum(i * 2 + 1)`

**Outputs**:

- The expected root signature: `0xe912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 0..5 {
    key = &(i as u32 * 2 + 1).to_big_endian_bytes()
    smt.delete(&sum(key))
}
root = smt.root()
expected_root = 'e912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696'
expect(hex_encode(root), expected_root).to_be_equal
```


---

### File: docs/fuel-specs/src/tx-format/consensus_parameters.md

# Consensus Parameters

| name                        | type      | description                                                    |
|-----------------------------|-----------|----------------------------------------------------------------|
| `GAS_PER_BYTE`              | `uint64`  | Gas charged per byte of the transaction.                       |
| `GAS_PRICE_FACTOR`          | `uint64`  | Unit factor for gas price.                                     |
| `MAX_GAS_PER_TX`            | `uint64`  | Maximum gas per transaction.                                   |
| `MAX_INPUTS`                | `uint64`  | Maximum number of inputs.                                      |
| `MAX_OUTPUTS`               | `uint64`  | Maximum number of outputs.                                     |
| `MAX_PREDICATE_LENGTH`      | `uint64`  | Maximum length of predicate, in instructions.                  |
| `MAX_GAS_PER_PREDICATE`     | `uint64`  | Maximum gas per predicate.                                     |
| `MAX_PREDICATE_DATA_LENGTH` | `uint64`  | Maximum length of predicate data, in bytes.                    |
| `MAX_SCRIPT_LENGTH`         | `uint64`  | Maximum length of script, in instructions.                     |
| `MAX_SCRIPT_DATA_LENGTH`    | `uint64`  | Maximum length of script data, in bytes.                       |
| `MAX_MESSAGE_DATA_LENGTH`   | `uint64`  | Maximum length of message data, in bytes.                      |
| `MAX_STORAGE_SLOTS`         | `uint64`  | Maximum number of initial storage slots.                       |
| `MAX_TRANSACTION_SIZE`      | `uint64`  | Maximum size of a transaction, in bytes.                       |
| `MAX_WITNESSES`             | `uint64`  | Maximum number of witnesses.                                   |
| `MAX_BYTECODE_SUBSECTIONS`  | `uint64`  | Maximum number of bytecode subsections.                        |
| `CHAIN_ID`                  | `uint64`  | A unique per-chain identifier.                                 |
| `BASE_ASSET_ID`             | `bytes32` | The base asset of the chain.                                   |
| `PRIVILEGED_ADDRESS`        | `bytes32` | The privileged address of the network who can perform upgrade. |


---

### File: docs/fuel-specs/src/tx-format/index.md

# Transaction Format

The Fuel Transaction Format.

- [Consensus Parameters](./consensus_parameters.md)
- [Transaction](./transaction.md)
  - [`TransactionScript`](./transaction.md#transactionscript)
  - [`TransactionCreate`](./transaction.md#transactioncreate)
  - [`TransactionMint`](./transaction.md#transactionmint)
  - [`TransactionUpgrade`](./transaction.md#transactionupgrade)
  - [`TransactionUpload`](./transaction.md#transactionupload)
  - [`TransactionBlob`](./transaction.md#transactionblob)
- [Input](./input.md)
  - [`InputCoin`](./input.md#inputcoin)
  - [`InputContract`](./input.md#inputcontract)
  - [`InputMessage`](./input.md#inputmessage)
- [Output](./output.md)
  - [`OutputCoin`](./output.md#outputcoin)
  - [`OutputContract`](./output.md#outputcontract)
  - [`OutputChange`](./output.md#outputchange)
  - [`OutputVariable`](./output.md#outputvariable)
  - [`OutputContractCreated`](./output.md#outputcontractcreated)
- [`Witness`](./witness.md)
- [`Policy`](./policy.md)
- [`TXPointer`](./tx-pointer.md)


---

### File: docs/fuel-specs/src/tx-format/input.md

# Input

```c++
enum InputType : uint8 {
    Coin = 0,
    Contract = 1,
    Message = 2,
}
```

| name   | type                                                                                              | description    |
|--------|---------------------------------------------------------------------------------------------------|----------------|
| `type` | [`InputType`](#input)                                                                               | Type of input. |
| `data` | One of [`InputCoin`](#inputcoin), [`InputContract`](#inputcontract), or [`InputMessage`](#inputmessage) | Input data.    |

Transaction is invalid if:

- `type > InputType.Message`

## `InputCoin`

| name                  | type                         | description                                                            |
|-----------------------|------------------------------|------------------------------------------------------------------------|
| `txID`                | `byte[32]`                   | Hash of transaction.                                                   |
| `outputIndex`         | `uint16`                      | Index of transaction output.                                           |
| `owner`               | `byte[32]`                   | Owning address or predicate root.                                      |
| `amount`              | `uint64`                     | Amount of coins.                                                       |
| `asset_id`            | `byte[32]`                   | Asset ID of the coins.                                                 |
| `txPointer`           | [`TXPointer`](./tx-pointer.md) | Points to the TX whose output is being spent.                          |
| `witnessIndex`        | `uint16`                     | Index of witness that authorizes spending the coin.                    |
| `predicateGasUsed`    | `uint64`                     | Gas used by predicate.                                                 |
| `predicateLength`     | `uint64`                     | Length of predicate, in instructions.                                  |
| `predicateDataLength` | `uint64`                     | Length of predicate input data, in bytes.                              |
| `predicate`           | `byte[]`                     | Predicate bytecode.                                                    |
| `predicateData`       | `byte[]`                     | Predicate input data (parameters).                                     |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- `witnessIndex >= tx.witnessesCount`
- `predicateLength > MAX_PREDICATE_LENGTH`
- `predicateDataLength > MAX_PREDICATE_DATA_LENGTH`
- If `predicateLength > 0`; the computed predicate root (see below) is not equal `owner`
- `predicateLength * 4 != len(predicate)`
- `predicateDataLength != len(predicateData)`
- `predicateGasUsed > MAX_GAS_PER_PREDICATE`

> **Note:** when signing a transaction, `txPointer` and `predicateGasUsed` are set to zero.
>
> **Note:** when verifying and estimating a predicate or executing a script, `txPointer` and `predicateGasUsed` are initialized to zero.

The predicate root is computed [here](../identifiers/predicate-id.md).

## `InputContract`

| name          | type                         | description                                                             |
|---------------|------------------------------|-------------------------------------------------------------------------|
| `txID`        | `byte[32]`                   | Hash of transaction.                                                    |
| `outputIndex` | `uint16`                      | Index of transaction output.                                            |
| `balanceRoot` | `byte[32]`                   | Root of amount of coins owned by contract before transaction execution. |
| `stateRoot`   | `byte[32]`                   | State root of contract before transaction execution.                    |
| `txPointer`   | [`TXPointer`](./tx-pointer.md) | Points to the TX whose output is being spent.                           |
| `contractID`  | `byte[32]`                   | Contract ID.                                                            |

Transaction is invalid if:

- there is not exactly one output of type `OutputType.Contract` with `inputIndex` equal to this input's index

> **Note:** when signing a transaction, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are set to zero.
>
> **Note:** when verifying a predicate or executing a script, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are initialized to zero.

## `InputMessage`

| name                  | type       | description                                             |
|-----------------------|------------|---------------------------------------------------------|
| `sender`              | `byte[32]` | The address of the message sender.                      |
| `recipient`           | `byte[32]` | The address or predicate root of the message recipient. |
| `amount`              | `uint64`   | Amount of base asset coins sent with message.           |
| `nonce`               | `byte[32]` | The message nonce.                                      |
| `witnessIndex`        | `uint16`   | Index of witness that authorizes spending the coin.     |
| `predicateGasUsed`    | `uint64`   | Gas used by predicate execution.                        |
| `dataLength`          | `uint64`   | Length of message data, in bytes.                       |
| `predicateLength`     | `uint64`   | Length of predicate, in instructions.                   |
| `predicateDataLength` | `uint64`   | Length of predicate input data, in bytes.               |
| `data`                | `byte[]`   | The message data.                                       |
| `predicate`           | `byte[]`   | Predicate bytecode.                                     |
| `predicateData`       | `byte[]`   | Predicate input data (parameters).                      |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- `witnessIndex >= tx.witnessesCount`
- `dataLength > MAX_MESSAGE_DATA_LENGTH`
- `predicateLength > MAX_PREDICATE_LENGTH`
- `predicateDataLength > MAX_PREDICATE_DATA_LENGTH`
- If `predicateLength > 0`; the computed predicate root (see below) is not equal `recipient`
- `dataLength != len(data)`
- `predicateLength * 4 != len(predicate)`
- `predicateDataLength != len(predicateData)`
- `predicateGasUsed > MAX_GAS_PER_PREDICATE`

The predicate root is computed [here](../identifiers/predicate-id.md).

> **Note:** `InputMessages` with data length greater than zero are not considered spent until they are included in a transaction of type `TransactionType.Script` with a `ScriptResult` receipt where `result` is equal to `0` indicating a successful script exit
>
> **Note:** when signing a transaction, `predicateGasUsed` is set to zero.
>
> **Note:** when verifying and estimating a predicate, `predicateGasUsed` is initialized to zero.


---

### File: docs/fuel-specs/src/tx-format/output.md

# Output

```c++
enum OutputType : uint8 {
    Coin = 0,
    Contract = 1,
    Change = 2,
    Variable = 3,
    ContractCreated = 4,
}
```

| name   | type                                                                                                                                                                                       | description     |
|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------|
| `type` | [`OutputType`](#output)                                                                                                                                                                      | Type of output. |
| `data` | One of [`OutputCoin`](#outputcoin), [`OutputContract`](#outputcontract), [`OutputChange`](#outputchange), [`OutputVariable`](#outputvariable), or [`OutputContractCreated`](#outputcontractcreated). | Output data.    |

Transaction is invalid if:

- `type > OutputType.ContractCreated`

## `OutputCoin`

| name       | type       | description                          |
|------------|------------|--------------------------------------|
| `to`       | `byte[32]` | Receiving address or predicate root. |
| `amount`   | `uint64`   | Amount of coins to send.             |
| `asset_id` | `byte[32]` | Asset ID of coins.                   |

## `OutputContract`

| name          | type       | description                                                            |
|---------------|------------|------------------------------------------------------------------------|
| `inputIndex`  | `uint16`    | Index of input contract.                                               |
| `balanceRoot` | `byte[32]` | Root of amount of coins owned by contract after transaction execution. |
| `stateRoot`   | `byte[32]` | State root of contract after transaction execution.                    |

Transaction is invalid if:

- `inputIndex >= tx.inputsCount`
- `tx.inputs[inputIndex].type != InputType.Contract`

> **Note:** when signing a transaction, `balanceRoot` and `stateRoot` are set to zero.
>
> **Note:** when verifying a predicate or executing a script, `balanceRoot` and `stateRoot` are initialized to zero.

The balance root `balanceRoot` is the root of the [SMT](../protocol/cryptographic-primitives.md#sparse-merkle-tree) of balance leaves. Each balance is a `uint64`, keyed by asset ID (a `byte[32]`).

The state root `stateRoot` is the root of the [SMT](../protocol/cryptographic-primitives.md#sparse-merkle-tree) of storage slots. Each storage slot is a `byte[32]`, keyed by a `byte[32]`.

## `OutputChange`

| name       | type       | description                          |
|------------|------------|--------------------------------------|
| `to`       | `byte[32]` | Receiving address or predicate root. |
| `amount`   | `uint64`   | Amount of coins to send.             |
| `asset_id` | `byte[32]` | Asset ID of coins.                   |

Transaction is invalid if:

- any other output has type `OutputType.OutputChange` and asset ID `asset_id` (i.e. only one change output per asset ID is allowed)

> **Note:** when signing a transaction, `amount` is set to zero.
>
> **Note:** when verifying a predicate or executing a script, `amount` is initialized to zero.

This output type indicates that the output's amount may vary based on transaction execution, but is otherwise identical to a [Coin](#outputcoin) output. An `amount` of zero after transaction execution indicates that the output is unspendable and can be pruned from the UTXO set.

## `OutputVariable`

| name       | type       | description                          |
|------------|------------|--------------------------------------|
| `to`       | `byte[32]` | Receiving address or predicate root. |
| `amount`   | `uint64`   | Amount of coins to send.             |
| `asset_id` | `byte[32]` | Asset ID of coins.                   |

> **Note:** when signing a transaction, `to`, `amount`, and `asset_id` are set to zero.
>
> **Note:** when verifying a predicate or executing a script, `to`, `amount`, and `asset_id` are initialized to zero.

This output type indicates that the output's amount and owner may vary based on transaction execution, but is otherwise identical to a [Coin](#outputcoin) output. An `amount` of zero after transaction execution indicates that the output is unspendable and can be pruned from the UTXO set.

## `OutputContractCreated`

| name         | type       | description                     |
|--------------|------------|---------------------------------|
| `contractID` | `byte[32]` | Contract ID.                    |
| `stateRoot`  | `byte[32]` | Initial state root of contract. |


---

### File: docs/fuel-specs/src/tx-format/policy.md

# Policy

```c++
// index using powers of 2 for efficient bitmasking
enum PolicyType : uint32 {
    Tip = 1,
    WitnessLimit = 2,
    Maturity = 4,
    MaxFee = 8,
    Expiration = 16,
}
```

| name   | type                                                                              | description  |
|--------|-----------------------------------------------------------------------------------|--------------|
| `data` | One of [`Tip`](#tip), [`WitnessLimit`](#witnesslimit), [`Maturity`](#maturity) or [`Expiration`](#expiration) | Policy data. |

## `Tip`

| name       | type     | description                                                                                   |
|------------|----------|-----------------------------------------------------------------------------------------------|
| `tip` | `uint64` | Additional, optional fee in `BASE_ASSET` to incentivize block producer to include transaction |

## `WitnessLimit`

| name           | type     | description                                                    |
|----------------|----------|----------------------------------------------------------------|
| `witnessLimit` | `uint64` | The maximum amount of witness data allowed for the transaction |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- `len(tx.witnesses) > witnessLimit`

## `Maturity`

| name       | type     | description                              |
|------------|----------|------------------------------------------|
| `maturity` | `uint32` | Block until which the transaction cannot be included. |

Transaction is invalid if:

- `blockheight() < maturity`

## `Expiration`

| name         | type     | description                              |
|--------------|----------|------------------------------------------|
| `expiration` | `uint32` | Block after which the transaction cannot be included. |

Transaction is invalid if:

- `blockheight() > expiration`

## `MaxFee`

| name      | type     | description                                                                                                                                                           |
|-----------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `max_fee` | `uint64` | Required policy to specify the maximum fee payable by this transaction using `BASE_ASSET`. This is used to check transactions before the actual `gas_price` is known. |

Transaction is invalid if:

- `max_fee > sum_inputs(tx, BASE_ASSET_ID) - sum_outputs(tx, BASE_ASSET_ID)`
- `max_fee < max_fee(tx, BASE_ASSET_ID, gas_price)`


---

### File: docs/fuel-specs/src/tx-format/transaction.md

# Transaction

```c++
enum TransactionType : uint8 {
    Script = 0,
    Create = 1,
    Mint = 2,
    Upgrade = 3,
    Upload = 4,
    Blob = 5,
}
```

| name   | type                                                                                                                                                                                                                          | description       |
|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
| `type` | [`TransactionType`](#transaction)                                                                                                                                                                                             | Transaction type. |
| `data` | One of [`TransactionScript`](#transactionscript), [`TransactionCreate`](#transactioncreate), [`TransactionMint`](#transactionmint), [`TransactionUpgrade`](#transactionupgrade), or [`TransactionUpload`](#transactionupload) | Transaction data. |

Given helper `max_gas()` returns the maximum gas that the transaction can use.
Given helper `count_ones()` that returns the number of ones in the binary representation of a field.
Given helper `count_variants()` that returns the number of variants in an enum.
Given helper `sum_variants()` that sums all variants of an enum.

Transaction is invalid if:

- `type` is not valid `TransactionType` value
- `inputsCount > MAX_INPUTS`
- `outputsCount > MAX_OUTPUTS`
- `witnessesCount > MAX_WITNESSES`
- `size > MAX_TRANSACTION_SIZE`. The size of a transaction is calculated as the sum of the sizes of its static and dynamic parts, as determined by canonical serialization.
- No inputs are of type `InputType.Coin` or `InputType.Message` with `input.dataLength` == 0
- More than one output is of type `OutputType.Change` for any asset ID in the input set
- More than one output is of type `OutputType.Change` with identical `asset_id` fields.
- Any output is of type `OutputType.Change` for any asset ID not in the input set
- More than one input of type `InputType.Coin` for any [Coin ID](../identifiers/utxo-id.md#coin-id) in the input set
- More than one input of type `InputType.Contract` for any [Contract ID](../identifiers/utxo-id.md#contract-id) in the input set
- More than one input of type `InputType.Message` for any [Message ID](../identifiers/utxo-id.md#message-id) in the input set
- if `type != TransactionType.Mint`
  - `max_gas(tx) > MAX_GAS_PER_TX`
  - No policy of type `PolicyType.MaxFee` is set
  - `count_ones(policyTypes) > count_variants(PolicyType)`
  - `policyTypes > sum_variants(PolicyType)`
  - `len(policies) > count_ones(policyTypes)`

When serializing a transaction, fields are serialized as follows (with inner structs serialized recursively):

1. `uint8`, `uint16`, `uint32`, `uint64`: big-endian right-aligned to 8 bytes.
1. `byte[32]`: as-is.
1. `byte[]`: as-is, with padding zeroes aligned to 8 bytes.

When deserializing a transaction, the reverse is done. If there are insufficient bytes or too many bytes, the transaction is invalid.

## `TransactionScript`

```c++
enum ReceiptType : uint8 {
    Call = 0,
    Return = 1,
    ReturnData = 2,
    Panic = 3,
    Revert = 4,
    Log = 5,
    LogData = 6,
    Transfer = 7,
    TransferOut = 8,
    ScriptResult = 9,
    MessageOut = 10,
    Mint = 11,
    Burn = 12,
}
```

| name               | type                        | description                             |
|--------------------|-----------------------------|-----------------------------------------|
| `scriptGasLimit`   | `uint64`                    | Gas limits the script execution.        |
| `receiptsRoot`     | `byte[32]`                  | Merkle root of receipts.                |
| `scriptLength`     | `uint64`                    | Script length, in instructions.         |
| `scriptDataLength` | `uint64`                    | Length of script input data, in bytes.  |
| `policyTypes`      | `uint32`                    | Bitfield of used policy types.          |
| `inputsCount`      | `uint16`                    | Number of inputs.                       |
| `outputsCount`     | `uint16`                    | Number of outputs.                      |
| `witnessesCount`   | `uint16`                    | Number of witnesses.                    |
| `script`           | `byte[]`                    | Script to execute.                      |
| `scriptData`       | `byte[]`                    | Script input data (parameters).         |
| `policies`         | [Policy](./policy.md)`[]`   | List of policies, sorted by `PolicyType`. |
| `inputs`           | [Input](./input.md)`[]`     | List of inputs.                         |
| `outputs`          | [Output](./output.md)`[]`   | List of outputs.                        |
| `witnesses`        | [Witness](./witness.md)`[]` | List of witnesses.                      |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- Any output is of type `OutputType.ContractCreated`
- `scriptLength > MAX_SCRIPT_LENGTH`
- `scriptDataLength > MAX_SCRIPT_DATA_LENGTH`
- `scriptLength * 4 != len(script)`
- `scriptDataLength != len(scriptData)`

> **Note:** when signing a transaction, `receiptsRoot` is set to zero.
>
> **Note:** when verifying a predicate or executing a script, `receiptsRoot` is initialized to zero.

The receipts root `receiptsRoot` is the root of the [binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) of receipts. If there are no receipts, its value is set to the root of the empty tree, i.e. `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`.

## `TransactionCreate`

| name                   | type                        | description                                       |
|------------------------|-----------------------------|---------------------------------------------------|
| `bytecodeWitnessIndex` | `uint16`                    | Witness index of contract bytecode to create.     |
| `salt`                 | `byte[32]`                  | Salt.                                             |
| `storageSlotsCount`    | `uint64`                    | Number of storage slots to initialize.            |
| `policyTypes`          | `uint32`                    | Bitfield of used policy types.                    |
| `inputsCount`          | `uint16`                    | Number of inputs.                                 |
| `outputsCount`         | `uint16`                    | Number of outputs.                                |
| `witnessesCount`       | `uint16`                    | Number of witnesses.                              |
| `storageSlots`         | `(byte[32], byte[32]])[]`   | List of storage slots to initialize (key, value). |
| `policies`             | [Policy](./policy.md)`[]`    | List of policies.                                  |
| `inputs`               | [Input](./input.md)`[]`     | List of inputs.                                   |
| `outputs`              | [Output](./output.md)`[]`   | List of outputs.                                  |
| `witnesses`            | [Witness](./witness.md)`[]` | List of witnesses.                                |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- It does not have exactly one output of type `OutputType.ContractCreated`
- `tx.data.witnesses[bytecodeWitnessIndex].dataLength > CONTRACT_MAX_SIZE`
- `bytecodeWitnessIndex >= tx.witnessesCount`
- The keys of `storageSlots` are not in ascending lexicographic order
- The computed contract ID (see below) is not equal to the `contractID` of the one `OutputType.ContractCreated` output
- `storageSlotsCount > MAX_STORAGE_SLOTS`
- The [Sparse Merkle tree](../protocol/cryptographic-primitives.md#sparse-merkle-tree) root of `storageSlots` is not equal to the `stateRoot` of the one `OutputType.ContractCreated` output

Creates a contract with contract ID as computed [here](../identifiers/contract-id.md).

## `TransactionMint`

The transaction is created by the block producer and is not signed. Since it is not usable outside of block creation or execution, all fields must be fully set upon creation without any zeroing.
This means that the transaction ID must also include the correct `txPointer` value, not zeroed out.

| name             | type                            | description                                                                |
|------------------|---------------------------------|----------------------------------------------------------------------------|
| `txPointer`      | [`TXPointer`](./tx-pointer.md)  | The location of the `Mint` transaction in the block.                       |
| `inputContract`  | [`InputContract`](./input.md)   | The contract UTXO that assets are minted to.                               |
| `outputContract` | [`OutputContract`](./output.md) | The contract UTXO that assets are being minted to.                         |
| `mintAmount`     | `uint64`                        | The amount of funds minted.                                                |
| `mintAssetId`    | `byte[32]`                      | The asset IDs corresponding to the minted amount.                          |
| `gasPrice`       | `uint64`                        | The gas price to be used in calculating all fees for transactions on block |

Transaction is invalid if:

- `txPointer` is zero or doesn't match the block.
- `outputContract.inputIndex` is not zero

## `TransactionUpgrade`

The `Upgrade` transaction allows upgrading either consensus parameters or state transition function used by the network to produce future blocks. The `Upgrade Purpose` type defines the purpose of the upgrade.

The `Upgrade` transaction is chargeable, and the sender should pay for it. Transaction inputs should contain only base assets.

Only the privileged address from [`ConsensusParameters`](./consensus_parameters.md) can upgrade the network. The privileged address can be either a real account or a predicate.

When the upgrade type is `UpgradePurposeType.ConsensusParameters` serialized consensus parameters are available in the witnesses and the `Upgrade` transaction is self-contained because it has all the required information.

When the upgrade type is `UpgradePurposeType.StateTransition`, the `bytecodeRoot` field contains the Merkle root of the new bytecode of the state transition function. The bytecode should already be available on the blockchain at the upgrade point; otherwise, the upgrade will fail. The bytecode can be part of the genesis block or can be uploaded via the `TransactionUpload` transaction.

The block header contains information about which versions of consensus parameters and state transition function are used to produce a block, and the `Upgrade` transaction defines behavior corresponding to the version. When the block executes the `Upgrade` transaction, it defines new behavior for either `BlockHeader.consensusParametersVersion + 1` or `BlockHeader.stateTransitionBytecodeVersion + 1`(it depends on the purpose of the upgrade).

When the `Upgrade` transaction is included in the block, it doesn't affect the current block execution. Since behavior is now defined, the inclusion of the `Upgrade` transaction allows the production of the next block with a new version. The block producer can still continue to use the previous version and start using a new version later unless the state transition function forbids it.

The behavior is set once per version. It is forbidden to override the behavior of the network. Each behavior should have its own version. The version should grow monotonically without jumps.

The `BlockHeader.consensusParametersVersion` and `BlockHeader.stateTransitionBytecodeVersion` are independent and can grow at different speeds.

| name             | type                                   | description                    |
|------------------|----------------------------------------|--------------------------------|
| `upgradePurpose` | [UpgradePurpose](./upgrade_purpose.md) | The purpose of the upgrade.    |
| `policyTypes`    | `uint32`                               | Bitfield of used policy types. |
| `inputsCount`    | `uint16`                               | Number of inputs.              |
| `outputsCount`   | `uint16`                               | Number of outputs.             |
| `witnessesCount` | `uint16`                               | Number of witnesses.           |
| `policies`       | [Policy](./policy.md)`[]`              | List of policies.              |
| `inputs`         | [Input](./input.md)`[]`                | List of inputs.                |
| `outputs`        | [Output](./output.md)`[]`              | List of outputs.               |
| `witnesses`      | [Witness](./witness.md)`[]`            | List of witnesses.             |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- No input where `InputType.Message.owner == PRIVILEGED_ADDRESS` or `InputType.Coint.owner == PRIVILEGED_ADDRESS`
- The `UpgradePurpose` is invalid

## `TransactionUpload`

The `Upload` transaction allows the huge bytecode to be divided into subsections and uploaded slowly to the chain. The [Binary Merkle root](../protocol/cryptographic-primitives.md#binary-merkle-tree) built on top of subsections is an identifier of the bytecode.

Each transaction uploads a subsection of the code and must contain proof of connection to the root. All subsections should be uploaded sequentially, which allows the concatenation of previously uploaded subsections with new subsection. The bytecode is considered final when the last subsection is uploaded, and future `Upload` transactions with the same `root` fields should be rejected.

When the bytecode is completed it can be used to upgrade the network.

The size of each subsection can be arbitrary; the only limit is the maximum number of subsections allowed by the network. The combination of the transaction gas limit and the number of subsections limits the final maximum size of the bytecode.

| name                | type                        | description                                                                             |
|---------------------|-----------------------------|-----------------------------------------------------------------------------------------|
| `root`              | `byte[32]`                  | The root of the Merkle tree is created over the bytecode.                               |
| `witnessIndex`      | `uint16`                    | The witness index of the subsection of the bytecode.                                    |
| `subsectionIndex`   | `uint16`                    | The index of the subsection of the bytecode.                                            |
| `subsectionsNumber` | `uint16`                    | The total number of subsections on which bytecode was divided.                          |
| `proofSetCount`     | `uint16`                    | Number of Merkle nodes in the proof.                                                    |
| `policyTypes`       | `uint32`                    | Bitfield of used policy types.                                                          |
| `inputsCount`       | `uint16`                    | Number of inputs.                                                                       |
| `outputsCount`      | `uint16`                    | Number of outputs.                                                                      |
| `witnessesCount`    | `uint16`                    | Number of witnesses.                                                                    |
| `proofSet`          | `byte[32][]`                | The proof set of Merkle nodes to verify the connection of the subsection to the `root`. |
| `policies`          | [Policy](./policy.md)`[]`   | List of policies.                                                                       |
| `inputs`            | [Input](./input.md)`[]`     | List of inputs.                                                                         |
| `outputs`           | [Output](./output.md)`[]`   | List of outputs.                                                                        |
| `witnesses`         | [Witness](./witness.md)`[]` | List of witnesses.                                                                      |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- `witnessIndex >= tx.witnessesCount`
- `subsectionIndex` >= `subsectionsNumber`
- `subsectionsNumber > MAX_BYTECODE_SUBSECTIONS`
- The [Binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) root calculated from `(witnesses[witnessIndex], subsectionIndex, subsectionsNumber, proofSet)` is not equal to the `root`. Root calculation is affected by all fields, so modification of one of them invalidates the proof.

## `TransactionBlob`

The `Blob` inserts a simple binary blob in the chain. It's raw immutable data that can be cheaply loaded by the VM and used as instructions or just data. Unlike `Create`, it doesn't hold any state or balances.

`Blob`s are content-addressed, i.e. the they are uniquely identified by hash of the data field. Programs running on the VM can load an already-posted blob just by the hash, without having to specify it in contract inputs.

| name                | type                        | description                      |
|---------------------|-----------------------------|----------------------------------|
| `id`                | `byte[32]`                  | Blob id, i.e. hash of the data.  |
| `witnessIndex`      | `uint16`                    | The witness index of the data.   |
| `policyTypes`       | `uint32`                    | Bitfield of used policy types.   |
| `inputsCount`       | `uint16`                    | Number of inputs.                |
| `outputsCount`      | `uint16`                    | Number of outputs.               |
| `witnessesCount`    | `uint16`                    | Number of witnesses.             |
| `policies`          | [Policy](./policy.md)`[]`   | List of policies.                |
| `inputs`            | [Input](./input.md)`[]`     | List of inputs.                  |
| `outputs`           | [Output](./output.md)`[]`   | List of outputs.                 |
| `witnesses`         | [Witness](./witness.md)`[]` | List of witnesses.               |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- `witnessIndex >= tx.witnessesCount`
- `sha256(witnesses[witnessIndex]) != id`


---

### File: docs/fuel-specs/src/tx-format/tx-pointer.md

# `TXPointer`

The location of the transaction in the block. It can be used by UTXOs as a reference to the transaction or by the transaction itself to make it unique.

| name          | type     | description        |
|---------------|----------|--------------------|
| `blockHeight` | `uint32` | Block height.      |
| `txIndex`     | `uint16` | Transaction index. |


---

### File: docs/fuel-specs/src/tx-format/upgrade_purpose.md

# `UpgradePurposeType`

```c++
enum UpgradePurposeType : uint8 {
    ConsensusParameters = 0,
    StateTransition = 1,
}
```

| name   | type                                                                                        | description              |
|--------|---------------------------------------------------------------------------------------------|--------------------------|
| `type` | [`UpgradePurposeType`](#upgradepurposetype)                                                 | Type of upgrade purpose. |
| `data` | One of [`ConsensusParameters`](#consensusparameters), [`StateTransition`](#statetransition) | Upgrade purposes.        |

Transaction is invalid if:

- `type` is not valid `UpgradePurposeType` value`

## `ConsensusParameters`

| name           | type       | description                                                                                                                   |
|----------------|------------|-------------------------------------------------------------------------------------------------------------------------------|
| `witnessIndex` | `uint16`   | Index of witness that contains a serialized(with [postcard](https://docs.rs/postcard/latest/postcard/)) consensus parameters. |
| `checksum`     | `byte[32]` | The hash of the serialized consensus parameters.                                                                              |

Given helper `deserialize_consensus_parameters()` that deserializes the consensus parameters from a witness by using [postcard](https://docs.rs/postcard/latest/postcard/) algorithm.

Transaction is invalid if:

- `witnessIndex >= tx.witnessesCount`
- `checksum != sha256(tx.data.witnesses[witnessIndex])`
- `deserialize_consensus_parameters(tx.data.witnesses[witnessIndex])` returns an error.

## `StateTransition`

| name           | type       | description                                                    |
|----------------|------------|----------------------------------------------------------------|
| `bytecodeRoot` | `byte[32]` | The root of the new bytecode of the state transition function. |


---

### File: docs/fuel-specs/src/tx-format/witness.md

# Witness

| name         | type     | description                       |
|--------------|----------|-----------------------------------|
| `dataLength` | `uint64` | Length of witness data, in bytes. |
| `data`       | `byte[]` | Witness data.                     |


---

### File: docs/fuel-token-overview/docs/src/claim-genesis-drop.md

# Claim Genesis Drop

Please visit [app.fuel.network/earn-points/drop/](https://app.fuel.network/earn-points/drop/) to claim your FUEL airdrop. Below is a brief help guide to assist you.

## Check Eligibility

Start by connecting all accounts eligible for Phase 1 of the FUEL airdrop. This includes GitHub accounts, Fuel wallets (both native and non-native), and Ethereum wallets.

![Connect Accounts](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/1-connect-wallet.png)

You connect all three wallet types at the same time and view the claimable amount for each individual account.

![Airdrop Amount Multi](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/2-airdrop-amount-multi.png)

Note that any eligible Ethereum accounts you connect will automatically load their corresponding eligible Fuel accounts. If rewards were earned using a non-Fuel wallet, they will still appear in the Fuel Wallet where the tokens were bridged.

![Airdrop Amount Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/3-airdrop-amount-pt3.png)

## Claim

To start the claiming process, click “Join the Claim Queue.”

![Join Queue](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/4-join-queue.png)

Once you have joined the queue, you will have exactly 10 minutes to claim your FUEL tokens from each of your eligible accounts or else you will have to requeue.

![Claim](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/5-claim.png)

Please carefully read over the terms of service before proceeding to claim your tokens. Once you’re ready, simply click “Claim.”

![Claim Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/6-claim-pt2.png)

When claiming through an Ethereum wallet, you can connect a Fuel wallet to receive your tokens. Plus, as a bonus, if you don't have any ETH on Fuel Ignition, you’ll get a small amount of  gas to help you claim your Fuel tokens!

![Claim Eth](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/7-claim-eth.png)

Congratulations and thank you for being a part of the Fuel community! Now, please head over to Fuel Ignition and follow this [guide](./stake-on-fuel.md) to stake your tokens.


---

### File: docs/fuel-token-overview/docs/src/fuel-v1-upgrade.md

# How to Upgrade Fuel V1 to FUEL

> The Fuel V1 token was the previous iteration of the FUEL token. The initial supply of Fuel V1 tokens was 100 million. The supply of the current FUEL token is 10 billion. Fuel V1 tokens can accordingly be upgraded at a ratio of 1:100.

Please visit [app.fuel.network/upgrade](https://app.fuel.network/upgrade) to upgrade your Fuel V1 tokens to FUEL tokens. Below is a short help guide:

## Connecting an EVM Wallet

Fuel V1 grants exist only on the Ethereum mainnet. Please connect an EVM wallet with a token grant or Fuel V1 tokens using the button in the top-right corner.

![Connect EVM Wallet](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/1-connect-evm-wallet.png)

## Claiming a Token Grant

If you have a token grant, the amount of unclaimed tokens will be displayed, along with a button to claim the tokens into your wallet. If you already have Fuel V1 tokens ready to upgrade, you can skip this step.

![Claim Token Grant](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/2-claim-token-grant.png)

## Upgrade Fuel V1 Tokens to Fuel Tokens

Once you have Fuel V1 tokens in your wallet, click the "Upgrade to FUEL" button to start the upgrading process. This will take you to two screens.

![Upgrade To FUEL](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/3-convert-to-fuel.png)

The first screen is to approve the amount of tokens to be upgraded.

![Approve Amount](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/4-approve-amount.png)

The second screen is to complete upgrading of Fuel V1 tokens to FUEL tokens.

![Confirm Conversion](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/5-confirm-conversion.png)

That's it! You can now deposit and delegate your tokens to start earning rewards. Since your tokens are on the Ethereum mainnet, you have two options:

1. Stake on Ethereum:

    Use [app.fuel.network/staking/on-ethereum](https://app.fuel.network/staking/on-ethereum) to stake your tokens on the shared sequencer network from Ethereum. Note that this interface differs from the one used for tokens on Fuel Ignition. Follow the instructions provided in [How to Stake on Mainnet Ethereum](./stake-on-ethereum.md).

2. Bridge and Stake on Fuel Ignition:

    Alternatively, you can withdraw and bridge your tokens to Fuel Ignition to benefit from lower costs and higher speeds. Use the [Fuel Bridge](https://app.fuel.network/bridge?from=eth&to=fuel) to transfer your tokens, then stake them using [app.fuel.network/staking/on-fuel](https://app.fuel.network/staking/on-fuel). Follow the instructions provided in the [How to Stake on Fuel Ignition guide](./stake-on-fuel.md).

![Balance](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/6-balance.png)

> **Note:** It may take some time for your balance to appear on the shared sequencer network. Please don’t panic—your balance will update soon.


---

### File: docs/fuel-token-overview/docs/src/index.md

# FUEL Token

| Property                | Details                                    |
|-------------------------|--------------------------------------------|
| Ticker                  | FUEL                                       |
| Total supply at genesis | 10,000,000,000 FUEL                        |
| Decimals                | 9                                          |
| Address                 | [0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c](https://etherscan.io/address/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c) |
| Inflation Schedule      | 3% annually                                |

## The Role of FUEL

FUEL powers Fuels decentralized sequencer and eliminates gas fees for users by introducing a novel economic incentive structure based on Application Specific Sequencing. By enabling fee-less, web2-like, fee-less experiences for users, FUEL makes blockchain technology more usable and accessible to the masses.

FUEL secures the Fuel sequencing network, pays for chain resources and eliminates transaction fees for users– all while fostering new markets for L2 applications. Beyond sequencing, FUEL is on a mission to make blockchain usable without compromising on decentralization, setting a new standard for rollups in a space dominated by centralized solutions today.

Learn more about the Fuel Sequencer or see the [Fuel Genesis announcement](https://fuel.mirror.xyz/T6A4x8ReVu5ucAdwXXhrJawN9n4op7de4y7xW9MJ8ew) to learn more about the FUEL token's utility and distribution.

## FUEL Overview

![Fuel Banner](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/about/1-fuel-banner.png)

$FUEL will secure the Fuel sequencing network, pay for chain resources and eliminate transaction fees for users while creating new markets for L2 applications.

### 1. Securing the Network

The rollup landscape today is dominated by centralized sequencing solutions, raising concerns about censorship resistance, fairness, and liveness.

Fuel is taking steps to address these challenges. Initially, Fuel will decentralize a network of proposers, then decentralize building, and then will aim to increase the total number of proposers and builders.

The Fuel sequencer employs proof-of-stake (PoS) based on the Tendermint consensus, enabling a decentralized staking network. Users can actively participate in securing the network by delegating their FUEL to sequencer proposers in exchange for a share of staking rewards.

Our vision is to fully decentralize sequencing, which is essential for improving fault tolerance, liveness and censorship resistance. While centralized solutions dominate the space today, Fuel is committed to evolving toward a shared, permissionless network for its rollups.

Validator participation and staking will commence with Fuel Genesis, with detailed information on permissionless staking and running a validator available at a later date.

### 2. Paying for Chain Resources

FUEL will be used to pay for sequencer resources such as data availability, ordering and inclusion of blocks for rollups on the Fuel sequencer. FUEL will also be used for sequencer network fees, which play an essential role in decentralizing L2s built on Fuel as well as ensuring an open and decentralized sequencing network.

Fuel Ignition will continue to accept gas fees in ETH.

### 3. Application Specific Sequencing & Eliminating Fees

FUEL gives dApps greater influence on the inclusion and sequencing of transactions, while avoiding the complexities and limitations of traditional blockchain architectures. Stakers can bond their FUEL tokens to a specific application and earn rewards from those applications in exchange for locking their tokens. This allows transactions to be free for the user and executed according to application specific order. The result is a novel market for L2 chain resources that engages stakers to enable best in class user experiences (i.e. staking resources will receive tokens from applications, and enable free user transactions).

Note: More details about these activities, including instructions on how to delegate and stake will be provided soon.

## Progressive Decentralization

We outline three key phases for advancing the decentralization of the network.

- Phase 0, now completed, established 12 sequencer proposers and introduced initial security measures.
- Phase 1 focuses on decentralized block building and enhanced security.
- Phase 2 aims to significantly scale the network with more proposers, and advanced security features.

This is just the start of our journey, and we're excited to share our plans for advancing the network.

![Progressive Decentralization](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/about/2-progressive-decentralization.png)

## Helpful Links

- Have a question? Ask us a question at [forum.fuel.network](https://forum.fuel.network/) or [Discord](https://discord.com/invite/xfpK4Pe)
- [Genesis Drop Claims](./claim-genesis-drop.md)
- [Upgrade Fuel V1 to FUEL](./fuel-v1-upgrade.md)
- [Stake, Withdrawal and Reward Claims from Fuel Ignition](./stake-on-fuel.md)
- [Stake, Withdrawal and Reward Claims from Ethereum](./stake-on-ethereum.md)


---

### File: docs/fuel-token-overview/docs/src/stake-on-ethereum.md

# How to Stake on Mainnet Ethereum

Please visit [app.fuel.network/staking/on-ethereum](https://app.fuel.network/staking/on-ethereum) to stake your tokens on the Fuel Shared Sequencer Network from Ethereum. Below is a help guide:

## Connect EVM Wallet

Start by connecting an Ethereum wallet with FUEL tokens, whether they are already in the shared sequencer network or in your mainnet wallet.

![Connect EVM Wallet](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/1-connect-evm-wallet.png)

## Stake

From left to right, you can see your balance of FUEL tokens in your Ethereum wallet, your balance of FUEL tokens in the shared sequencer network, and the rewards accumulated.

Please note that tokens still in your mainnet Ethereum wallet must be migrated to the shared sequencer network first before you can delegate and stake. Don’t worry, as this will follow the same flow.

![Token Balances](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/2-token-balances.png)

### Select Validator

Scroll down to the bottom of the page. There, you will see a list of validators. From the list, choose the validator to which you want to stake and delegate your FUEL tokens. Click the "Deposit" button.

![Select Validator](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/3-select-validator.png)

### Delegating Tokens

Select the amount of FUEL tokens you want to delegate, and approve those tokens.

![Delegate Tokens](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/4-delegation-amount.png)

Once approved, confirm your delegation.

![Open Positions](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/5-confirm-delegation.png)

After the tokens have been successfully delegated and staked, you will see your tokens under "Delegated Positions."

![Open Positions](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/5.5-open-delegated-positions.png)

## Claim Rewards

After staking your FUEL tokens, you will immediately start to accumulate FUEL rewards, which you can claim. Click "Claim" on any of your open delegated positions to collect your rewards.

![Claim Rewards](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/6-claim-rewards.png)

Your rewards will be added to your balance in the Fuel shared sequencer network.

![Claim Rewards Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/7-claim-rewards-pt2.png)

## Withdrawal

You can undelegate and withdraw your staked FUEL tokens at any time. However, there is a standard 14-day unbonding period before the undelegation is completed, ensuring economic security within the PoS shared sequencer network and the Ethereum mainnet. After the 14-day period, the withdrawal process requires 4096 sequencer blocks approximately seven more hours before your tokens become available in your mainnet Ethereum wallet.

### Undelegate

To undelegate your open positions, simply press the hamburger button beside your position and click the "Undelegate" button.

![Withdrawal](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/8-undelegate.png)

Here, you can select how many delegated tokens you wish to undelegate. These tokens will return to your balance in the shared sequencer network.

![Withdrawal Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/9-undelegate-pt2.png)

### Withdraw Balance in Sequencer

Lastly, you can withdraw your tokens from the shared sequencer network back to your mainnet Ethereum wallet by clicking the "Withdraw" button beside your balance in the shared sequencer.

![Withdrawal](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/10-withdrawal.png)

Here you can specify how many tokens you want to withdraw.

![Withdrawal Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/10.5-withdrawal-pt2.png)


---

### File: docs/fuel-token-overview/docs/src/stake-on-fuel.md

# How to Stake on Fuel

Please visit [app.fuel.network/staking/on-fuel](https://app.fuel.network/staking/on-fuel) to stake your tokens on the Fuel Shared Sequencer Network through Fuel Ignition. Below, you'll find a helpful guide to get started.

## Connect Fuel Wallet

Start by connecting a Fuel wallet with FUEL tokens. This includes both non-native EVM and SVM wallets.

![Connect EVM Wallet](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/1-connect-wallet.png)  
![Connect EVM Wallet 1.5](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/1.5-connect-wallet.png)

## Stake

From left to right, you can view your FUEL token balance in your Fuel wallet, your staked FUEL token balance on the shared sequencer network, and your accumulated rewards.

Press the "Stake" button next to your balance to begin the staking process.

![Stake Tokens](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/2-stake-token.png)

Enter the number of tokens you wish to delegate to the validators. Then, click the "Deposit" button to stake your tokens.

Please note: unlike staking on mainnet Ethereum, the validator delegation process is automatically assigned, so you don’t need to manage each validator manually.

![Stake Tokens](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/3-stake-token-pt2.png)

After successfully depositing, your total staked token balance will update. The dashboard below will display the distribution of your delegated tokens. In the example diagram, the tokens are distributed evenly among the validators.

![Validator Distribution](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/4-validator-distribution.png)

## Withdraw

Withdrawing from the shared sequencer network is as simple as staking. Click the "Withdraw" button beside the amount of tokens you have staked.

![Withdrawal](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/5-withdrawal.png)

Select the amount of FUEL tokens you wish to withdraw, then click the "Withdraw" button.

![Withdrawal Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/6-withdrawal-pt2.png)

Your undelegated token balance will return to your Fuel wallet, and the validator dashboard will update accordingly as well.

![Withdrawal Pt3](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/6.5-withdrawal-pt3.png)

## Claim Rewards

Once you have staked your FUEL tokens, you will start to accumulate FUEL rewards. Click "Claim" next to your earned rewards balance to collect your tokens.

![Claim Rewards](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/7-claim-rewards.png)


---

### File: docs/fuel-token-overview/docs/src/tokenomics.md

# Tokenomics

With the introduction of FUEL and its total initial supply of 10 billion tokens, we aim to create a level playing field that ensures fair access for both existing members and newcomers to our growing ecosystem. To acknowledge and reward our long-standing friends, builders, and users, 20% of the initial supply will be distributed to the community, with eligibility determined by factors such as participation in the Fuel Points Program and our incentivized testnet. In total, over 51% of all FUEL tokens will ultimately be allocated to the community, the broader ecosystem, and ongoing research and development efforts, reflecting our commitment to inclusivity and shared growth.

![Allocation Pie Chart](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/tokenomics/1-pie.png)

| Group                | Details                                                                                                                                                                                                    | Amount       |
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|
| Community Expansion  | Used for incentives, programs, campaigns and activations for the Fuel community and expansion.                                                                                                             | 2.00 billion |
| Ecosystem and R&D    | Used to establish the sequencing network, and for ecosystem development and Fuel technology R&D.                                                                                                           | 1.55 billion |
| Ecosystem and R&D 24 | Same as above. These locked tokens can be staked during the 24 month block-by-block linear release. Staking rewards will only be used for ecosystem development efforts and to enable L2 level incentives. | 1.55 billion |
| Contributors 24      | Includes past and present Fuel contributors.                                                                                                                                                               | 0.60 billion |
| Contributors 48      | Core project contributors.                                                                                                                                                                                 | 0.98 billion |
| Purchasers           | Token purchasers from 2020 to 2022.                                                                                                                                                                        | 3.31 billion |

## Inflation

Inflation will be 3% annually. Note that inflation and Fuel economics are configured by the sequencer validator set.

## Unlocks

Note: Team and Purchasers can't stake locked tokens.

![Release Schedule](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/tokenomics/2-release-schedule.png)

| Group                | Details                                                                                                                                                                                                    | Vesting Schedule        |
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|
| Community            | Used for incentives, programs, campaigns and activations for the Fuel community and expansion.                                                                                                             | Immediate               |
| Ecosystem and R&D    | Used to establish the sequencing network, and for ecosystem development and Fuel technology R&D.                                                                                                           | Immediate               |
| Ecosystem and R&D 24 | Same as above. These locked tokens can be staked during the 24 month block-by-block linear release. Staking rewards will only be used for ecosystem development efforts and to enable L2 level incentives. | 24 month linear release |
| Contributors 24      | Includes past and present Fuel contributors.                                                                                                                                                               | 24 month linear release |
| Contributors 48      | Core project contributors.                                                                                                                                                                                 | 48 month linear release |
| Purchasers           | Token purchasers from 2020 to 2022.                                                                                                                                                                        | 24 month linear release |


---

### File: docs/fuels-rs/docs/src/abigen/index.md

# Generating bindings with abigen

You might have noticed this snippet in the previous sections:

```rust,ignore
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
```

<!-- This section should explain the purpose of the abigen -->
<!-- abigen:example:start -->
The SDK lets you transform ABI methods of a smart contract, specified as JSON objects (which you can get from [Forc](https://github.com/FuelLabs/sway/tree/master/forc)), into Rust structs and methods that are type-checked at compile time.
In order to call your contracts, scripts or predicates, you first need to generate the Rust bindings for them.
<!-- abigen:example:end -->

The following subsections contain more details about the `abigen!` syntax and the code generated from it.


---

### File: docs/fuels-rs/docs/src/abigen/the-abigen-macro.md

# abigen

<!-- This section explain the `abigen!` macro -->
<!-- abigen:example:start -->
`abigen!` is a procedural macro -- it generates code. It accepts inputs in the format of:

```text
ProgramType(name="MyProgramType", abi="my_program-abi.json")...
```

where:

- `ProgramType` is one of: `Contract`, `Script` or `Predicate`,

- `name` is the name that will be given to the generated bindings,

- `abi` is either a path to the JSON ABI file or its actual contents.
<!-- abigen:example:end -->

---
So, an `abigen!` which generates bindings for two contracts and one script looks like this:

```rust,ignore
        abigen!(
            Contract(
                name = "ContractA",
                abi = "e2e/sway/bindings/sharing_types/contract_a/out/release/contract_a-abi.json"
            ),
            Contract(
                name = "ContractB",
                abi = "e2e/sway/bindings/sharing_types/contract_b/out/release/contract_b-abi.json"
            ),
            Script(
                name = "MyScript",
                abi = "e2e/sway/scripts/arguments/out/release/arguments-abi.json"
            ),
            Predicate(
                name = "MyPredicateEncoder",
                abi = "e2e/sway/predicates/basic_predicate/out/release/basic_predicate-abi.json"
            ),
        );
```

## How does the generated code look?

A rough overview:

```rust,ignore
pub mod abigen_bindings {
    pub mod contract_a_mod {
        struct SomeCustomStruct{/*...*/};
        // other custom types used in the contract

        struct ContractA {/*...*/};
        impl ContractA {/*...*/};
        // ...
    }
    pub mod contract_b_mod {
        // ...
    }
    pub mod my_script_mod {
        // ...
    }
    pub mod my_predicate_mod{
        // ...
    }
    pub mod shared_types{
        // ...
    }
}

pub use contract_a_mod::{/*..*/};
pub use contract_b_mod::{/*..*/};
pub use my_predicate_mod::{/*..*/};
pub use shared_types::{/*..*/};
```

Each `ProgramType` gets its own `mod` based on the `name` given in the `abigen!`. Inside the respective mods, the custom types used by that program are generated, and the bindings through which the actual calls can be made.

One extra `mod` called `shared_types` is generated if `abigen!` detects that the given programs share types. Instead of each `mod` regenerating the type for itself, the type is lifted out into the `shared_types` module, generated only once, and then shared between all program bindings that use it. Reexports are added to each mod so that even if a type is deemed shared, you can still access it as though each `mod` had generated the type for itself (i.e. `my_contract_mod::SharedType`).

A type is deemed shared if its name and definition match up. This can happen either because you've used the same library (a custom one or a type from the `stdlib`) or because you've happened to define the exact same type.

Finally, `pub use` statements are inserted, so you don't have to fully qualify the generated types. To avoid conflict, only types that have unique names will get a `pub use` statement. If you find `rustc` can't find your type, it might just be that there is another generated type with the same name. To fix the issue just qualify the path by doing `abigen_bindings::whatever_contract_mod::TheType`.

> **Note:**
> It is **highly** encouraged that you generate all your bindings in one `abigen!` call. Doing it in this manner will allow type sharing and avoid name collisions you'd normally get when calling `abigen!` multiple times inside the same namespace. If you choose to proceed otherwise, keep in mind the generated code overview presented above and appropriately separate the `abigen!` calls into different modules to resolve the collision.

## Using the bindings

Let's look at a contract with two methods: `initialize_counter(arg: u64) -> u64` and `increment_counter(arg: u64) -> u64`, with the following JSON ABI:

```json,ignore
{
  "programType": "contract",
  "specVersion": "1",
  "encodingVersion": "1",
  "concreteTypes": [
    {
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
      "type": "u64"
    }
  ],
  "functions": [
    {
      "inputs": [
        {
          "name": "value",
          "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
        }
      ],
      "name": "initialize_counter",
      "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    },
    {
      "inputs": [
        {
          "name": "value",
          "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
        }
      ],
      "name": "increment_counter",
      "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    }
  ],
  "metadataTypes": []
}

```

By doing this:

```rust,ignore
            use fuels::prelude::*;
            // Replace with your own JSON abi path (relative to the root of your crate)
            abigen!(Contract(
                name = "MyContractName",
                abi = "examples/rust_bindings/src/abi.json"
            ));
```

or this:

```rust,ignore
            use fuels::prelude::*;
            abigen!(Contract(
                name = "MyContract",
                abi = r#"
            {
              "programType": "contract",
              "specVersion": "1",
              "encodingVersion": "1",
              "concreteTypes": [
                {
                  "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
                  "type": "u64"
                }
              ],
              "functions": [
                {
                  "inputs": [
                    {
                      "name": "value",
                      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                    }
                  ],
                  "name": "initialize_counter",
                  "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                },
                {
                  "inputs": [
                    {
                      "name": "value",
                      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                    }
                  ],
                  "name": "increment_counter",
                  "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                }
              ],
              "metadataTypes": []
            }
            "#
            ));
```

you'll generate this (shortened for brevity's sake):

```rust,ignore
pub mod abigen_bindings {
    pub mod my_contract_mod {
        #[derive(Debug, Clone)]
        pub struct MyContract<A: ::fuels::accounts::Account> {
            contract_id: ::fuels::types::ContractId,
            account: A,
            log_decoder: ::fuels::core::codec::LogDecoder,
            encoder_config: ::fuels::core::codec::EncoderConfig,
        }
        impl<A: ::fuels::accounts::Account> MyContract<A> {
            pub fn new(contract_id: ::fuels::types::ContractId, account: A) -> Self {
                let log_decoder = ::fuels::core::codec::LogDecoder::new(
                    ::fuels::core::codec::log_formatters_lookup(vec![], contract_id.clone().into()),
                );
                let encoder_config = ::fuels::core::codec::EncoderConfig::default();
                Self {
                    contract_id,
                    account,
                    log_decoder,
                    encoder_config,
                }
            }
            pub fn contract_id(&self) -> &::fuels::types::ContractId {
                self.contract_id
            }
            pub fn account(&self) -> A {
                self.account.clone()
            }
            pub fn with_account<U: ::fuels::accounts::Account>(self, account: U) -> MyContract<U> {
                MyContract {
                    contract_id: self.contract_id,
                    account,
                    log_decoder: self.log_decoder,
                    encoder_config: self.encoder_config,
                }
            }
            pub fn with_encoder_config(
                mut self,
                encoder_config: ::fuels::core::codec::EncoderConfig,
            ) -> MyContract<A> {
                self.encoder_config = encoder_config;
                self
            }
            pub async fn get_balances(
                &self,
            ) -> ::fuels::types::errors::Result<
                ::std::collections::HashMap<::fuels::types::AssetId, u64>,
            > {
                ::fuels::accounts::ViewOnlyAccount::try_provider(&self.account)?
                    .get_contract_balances(&self.contract_id)
                    .await
                    .map_err(::std::convert::Into::into)
            }
            pub fn methods(&self) -> MyContractMethods<A> {
                MyContractMethods {
                    contract_id: self.contract_id.clone(),
                    account: self.account.clone(),
                    log_decoder: self.log_decoder.clone(),
                    encoder_config: self.encoder_config.clone(),
                }
            }
        }
        pub struct MyContractMethods<A: ::fuels::accounts::Account> {
            contract_id: ::fuels::types::ContractId,
            account: A,
            log_decoder: ::fuels::core::codec::LogDecoder,
            encoder_config: ::fuels::core::codec::EncoderConfig,
        }
        impl<A: ::fuels::accounts::Account> MyContractMethods<A> {
            #[doc = " This method will read the counter from storage, increment it"]
            #[doc = " and write the incremented value to storage"]
            pub fn increment_counter(
                &self,
                value: ::core::primitive::u64,
            ) -> ::fuels::programs::calls::CallHandler<
                A,
                ::fuels::programs::calls::ContractCall,
                ::core::primitive::u64,
            > {
                ::fuels::programs::calls::CallHandler::new_contract_call(
                    self.contract_id.clone(),
                    self.account.clone(),
                    ::fuels::core::codec::encode_fn_selector("increment_counter"),
                    &[::fuels::core::traits::Tokenizable::into_token(value)],
                    self.log_decoder.clone(),
                    false,
                    self.encoder_config.clone(),
                )
            }
            pub fn initialize_counter(
                &self,
                value: ::core::primitive::u64,
            ) -> ::fuels::programs::calls::CallHandler<
                A,
                ::fuels::programs::calls::ContractCall,
                ::core::primitive::u64,
            > {
                ::fuels::programs::calls::CallHandler::new_contract_call(
                    self.contract_id.clone(),
                    self.account.clone(),
                    ::fuels::core::codec::encode_fn_selector("initialize_counter"),
                    &[::fuels::core::traits::Tokenizable::into_token(value)],
                    self.log_decoder.clone(),
                    false,
                    self.encoder_config.clone(),
                )
            }
        }
        impl<A: ::fuels::accounts::Account> ::fuels::programs::calls::ContractDependency for MyContract<A> {
            fn id(&self) -> ::fuels::types::ContractId {
                self.contract_id.clone()
            }
            fn log_decoder(&self) -> ::fuels::core::codec::LogDecoder {
                self.log_decoder.clone()
            }
        }
        #[derive(Clone, Debug, Default)]
        pub struct MyContractConfigurables {
            offsets_with_data: ::std::vec::Vec<(u64, ::std::vec::Vec<u8>)>,
            encoder: ::fuels::core::codec::ABIEncoder,
        }
        impl MyContractConfigurables {
            pub fn new(encoder_config: ::fuels::core::codec::EncoderConfig) -> Self {
                Self {
                    encoder: ::fuels::core::codec::ABIEncoder::new(encoder_config),
                    ..::std::default::Default::default()
                }
            }
        }
        impl From<MyContractConfigurables> for ::fuels::core::Configurables {
            fn from(config: MyContractConfigurables) -> Self {
                ::fuels::core::Configurables::new(config.offsets_with_data)
            }
        }
    }
}
pub use abigen_bindings::my_contract_mod::MyContract;
pub use abigen_bindings::my_contract_mod::MyContractConfigurables;
pub use abigen_bindings::my_contract_mod::MyContractMethods;

```

> **Note:** that is all **generated** code. No need to write any of that. Ever. The generated code might look different from one version to another, this is just an example to give you an idea of what it looks like.

Then, you're able to use it to call the actual methods on the deployed contract:

```rust,ignore
        // This will generate your contract's methods onto `MyContract`.
        // This means an instance of `MyContract` will have access to all
        // your contract's methods that are running on-chain!
        // ANCHOR: abigen_example
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        // ANCHOR_END: abigen_example

        // This is an instance of your contract which you can use to make calls to your functions
        let contract_instance = MyContract::new(contract_id_2, wallet);

        let response = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .call() // Perform the network call
            .await?;

        assert_eq!(42, response.value);

        let response = contract_instance
            .methods()
            .increment_counter(10)
            .call()
            .await?;

        assert_eq!(52, response.value);
```


---

### File: docs/fuels-rs/docs/src/abigen/the-json-abi-file.md

# The JSON ABI file

<!-- This section should talk about the importance of the ABI -->
<!-- abi:example:start -->
Whether you want to deploy or connect to a pre-existing smart contract, the JSON ABI file is extremely important: it's what tells the SDK about the [ABI methods](https://docs.fuel.network/guides/quickstart/building-a-smart-contract/#abi) in your smart contracts.
<!-- abi:example:end -->

For the same example Sway code as above:

```Rust
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

The JSON ABI file looks like this:

```json
$ cat out/release/my-test-abi.json
[
  {
    "type": "function",
    "inputs": [],
    "name": "test_function",
    "outputs": [
      {
        "name": "",
        "type": "bool",
        "components": null
      }
    ]
  }
]
```

The Fuel Rust SDK will take this file as input and generate equivalent methods (and custom types if applicable) that you can call from your Rust code.


---

### File: docs/fuels-rs/docs/src/accounts.md

# Accounts

The `ViewOnlyAccount` trait provides a common interface to query balances.

The `Account` trait, in addition to the above, also provides a way to transfer assets. When performing actions in the SDK that lead to a transaction, you will typically need to provide an account that will be used to allocate resources required by the transaction, including transaction fees.

The traits are implemented by the following types:

- [`Wallet`](./wallets/index.md)
- [`Predicate`](./predicates/index.md)

## Transferring assets

An account implements the following methods for transferring assets:

- `transfer`
- `force_transfer_to_contract`
- `withdraw_to_base_layer`

The following examples are provided for a `Wallet` account. A `Predicate` account would work similarly, but you might need to set its predicate data before attempting to spend resources owned by it.

With `wallet.transfer` you can initiate a transaction to transfer an asset from your account to a target address.

```rust,ignore
        use fuels::prelude::*;

        // Setup 2 test wallets with 1 coin each.
        let num_wallets = 2;
        let coins_per_wallet = 1;
        let coin_amount = 2;

        let wallets = launch_custom_provider_and_get_wallets(
            WalletsConfig::new(Some(num_wallets), Some(coins_per_wallet), Some(coin_amount)),
            None,
            None,
        )
        .await?;

        // Transfer the base asset with amount 1 from wallet 1 to wallet 2.
        let transfer_amount = 1;
        let asset_id = Default::default();
        let _res = wallets[0]
            .transfer(
                wallets[1].address(),
                transfer_amount,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        let wallet_2_final_coins = wallets[1].get_coins(AssetId::zeroed()).await?;

        // Check that wallet 2 now has 2 coins.
        assert_eq!(wallet_2_final_coins.len(), 2);
```

You can transfer assets to a contract via `wallet.force_transfer_to_contract`.

```rust,ignore
        // Check the current balance of the contract with id 'contract_id'.
        let contract_balances = wallet
            .try_provider()?
            .get_contract_balances(&contract_id)
            .await?;
        assert!(contract_balances.is_empty());

        // Transfer an amount of 300 to the contract.
        let amount = 300;
        let asset_id = random_asset_id;
        let _res = wallet
            .force_transfer_to_contract(contract_id, amount, asset_id, TxPolicies::default())
            .await?;

        // Check that the contract now has 1 coin.
        let contract_balances = wallet
            .try_provider()?
            .get_contract_balances(&contract_id)
            .await?;
        assert_eq!(contract_balances.len(), 1);

        let random_asset_balance = contract_balances.get(&random_asset_id).unwrap();
        assert_eq!(*random_asset_balance, 300);
```

For transferring assets to the base layer chain, you can use `wallet.withdraw_to_base_layer`.

```rust,ignore
        use std::str::FromStr;

        use fuels::prelude::*;

        let wallets = launch_custom_provider_and_get_wallets(
            WalletsConfig::new(Some(1), None, None),
            None,
            None,
        )
        .await?;
        let wallet = wallets.first().unwrap();

        let amount = 1000;
        let base_layer_address = Address::from_str(
            "0x4710162c2e3a95a6faff05139150017c9e38e5e280432d546fae345d6ce6d8fe",
        )?;

        // Transfer an amount of 1000 to the specified base layer address.
        let response = wallet
            .withdraw_to_base_layer(base_layer_address, amount, TxPolicies::default())
            .await?;

        let _block_height = wallet.provider().produce_blocks(1, None).await?;

        // Retrieve a message proof from the provider.
        let proof = wallet
            .try_provider()?
            .get_message_proof(&response.tx_id, &response.nonce, None, Some(2))
            .await?;

        // Verify the amount and recipient.
        assert_eq!(proof.amount, amount);
        assert_eq!(proof.recipient, base_layer_address);
```

The above example creates an `Address` from a string. Next, it calls `wallet.withdraw_to_base_layer` by providing the address, the amount to be transferred, and the transaction policies. Lastly, to verify that the transfer succeeded, the relevant message proof is retrieved with `provider.get_message_proof,` and the amount and the recipient are verified.


---

### File: docs/fuels-rs/docs/src/calling-contracts/call-params.md

# Call parameters

<!-- This section should explain what the call params are and how to configure them -->
<!-- call_params:example:start -->
The parameters for a contract call are:

1. Amount
2. Asset ID
3. Gas forwarded
<!-- call_params:example:end -->

You can use these to forward coins to a contract. You can configure these parameters by creating an instance of [`CallParameters`](https://docs.rs/fuels/latest/fuels/programs/calls/struct.CallParameters.html) and passing it to a chain method called `call_params`.
<!-- use_call_params:example:end -->

For instance, suppose the following contract that uses Sway's `msg_amount()` to return the amount sent in that transaction.

```rust,ignore
    #[payable]
    fn get_msg_amount() -> u64 {
        msg_amount()
    }
```

Then, in Rust, after setting up and deploying the above contract, you can configure the amount being sent in the transaction like this:

```rust,ignore
        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();

        let tx_policies = TxPolicies::default();

        // Forward 1_000_000 coin amount of base asset_id
        // this is a big number for checking that amount can be a u64
        let call_params = CallParameters::default().with_amount(1_000_000);

        let response = contract_methods
            .get_msg_amount() // Our contract method.
            .with_tx_policies(tx_policies) // Chain the tx policies.
            .call_params(call_params)? // Chain the call parameters.
            .call() // Perform the contract call.
            .await?;
        let response = contract_methods
            .initialize_counter(42)
            .call_params(CallParameters::default())?
            .call()
            .await?;
```

<!-- This section should explain why `call_params` returns a result -->
<!-- payable:example:start -->
`call_params` returns a result to ensure you don't forward assets to a contract method that isn't payable.
<!-- payable:example:end -->
In the following example, we try to forward an amount of `100` of the base asset to `non_payable`. As its name suggests, `non_payable` isn't annotated with `#[payable]` in the contract code. Passing `CallParameters` with an amount other than `0` leads to an error:

```rust,ignore
    let err = contract_methods
        .non_payable()
        .call_params(CallParameters::default().with_amount(100))
        .expect_err("should return error");

    assert!(matches!(err, Error::Other(s) if s.contains("assets forwarded to non-payable method")));
```

> **Note:** forwarding gas to a contract call is always possible, regardless of the contract method being non-payable.

You can also use `CallParameters::default()` to use the default values:

```rust,ignore
pub const DEFAULT_CALL_PARAMS_AMOUNT: u64 = 0;
```

This way:

```rust,ignore
        let response = contract_methods
            .initialize_counter(42)
            .call_params(CallParameters::default())?
            .call()
            .await?;
```

<!-- This section should explain what the `gas_forwarded` parameter does -->
<!-- gas:example:start -->
The `gas_forwarded` parameter defines the limit for the actual contract call as opposed to the gas limit for the whole transaction. This means that it is constrained by the transaction limit. If it is set to an amount greater than the available gas, all available gas will be forwarded.
<!-- gas:example:end -->

```rust,ignore
        // Set the transaction `gas_limit` to 1_000_000 and `gas_forwarded` to 4300 to specify that
        // the contract call transaction may consume up to 1_000_000 gas, while the actual call may
        // only use 4300 gas
        let tx_policies = TxPolicies::default().with_script_gas_limit(1_000_000);
        let call_params = CallParameters::default().with_gas_forwarded(4300);

        let response = contract_methods
            .get_msg_amount() // Our contract method.
            .with_tx_policies(tx_policies) // Chain the tx policies.
            .call_params(call_params)? // Chain the call parameters.
            .call() // Perform the contract call.
            .await?;
```

<!-- This section should explain the default forwarding behavior for a call -->
<!-- forwarding:example:start -->
If you don't set the call parameters or use `CallParameters::default()`, the transaction gas limit will be forwarded instead.
<!-- forwarding:example:end -->


---

### File: docs/fuels-rs/docs/src/calling-contracts/call-response.md

# Call response

<!-- This section should why you have to chain `.call().await.unwrap()` so often -->
<!-- chaining:example:start -->
You've probably noticed that you're often chaining `.call().await.unwrap()`. That's because:

1. You have to choose between `.call()` and `.simulate()` (more on this in the next section).
2. Contract calls are asynchronous, so you can choose to either `.await` it or perform concurrent tasks, making full use of Rust's async.
3. `.unwrap()` the `Result<CallResponse, Error>` returned by the contract call.
<!-- chaining:example:end -->

<!-- This section should preface what the `CallResponse` is -->
<!-- call_resp:example:start -->
Once you unwrap the `CallResponse`, you have access to this struct:
<!-- call_resp:example:end -->

```rust,ignore
pub struct CallResponse<D> {
    pub value: D,
    pub tx_status: Success,
    pub tx_id: Option<TxId>,
    pub log_decoder: LogDecoder,
}
```

<!-- This section should explain the fields of the `CallResponse` struct -->
<!-- call_resp_fields:example:start -->
Where `value` will hold the value returned by its respective contract method, represented by the exact type returned by the FuelVM, E.g., if your contract returns a FuelVM's `u64`, `value`'s `D` will be a `u64`. If it's a FuelVM's tuple `(u8,bool)`, then `D` will be a `(u8,bool)`. If it's a custom type, for instance, a Sway struct `MyStruct` containing two components, a `u64`, and a `b256`, `D` will be a struct generated at compile-time, called `MyStruct` with `u64` and a `[u8; 32]` (the equivalent of `b256` in Rust).

- `receipts` will hold all [receipts](https://docs.fuel.network/docs/specs/abi/receipts/) generated by that specific contract call.
- `gas_used` is the amount of gas consumed by the contract call.
- `tx_id` will hold the ID of the corresponding submitted transaction.
<!-- call_resp_fields:example:end -->

## Error handling

<!-- This section should explain how to use the `is_ok` and `is_err` methods for a call response -->
<!-- call_resp_ok:example:start -->
You can use the `is_ok` and `is_err` methods to check if a contract call `Result` is `Ok` or contains an error. These methods will return either `true` or `false`.
<!-- call_resp_ok:example:end -->

<!-- This section should show an example of how to use the `is_ok` and `is_err` methods for a call response -->
<!-- call_resp_ok_code:example:start -->
```rust, ignore
let is_ok = response.is_ok();
let is_error = response.is_err();
```
<!-- call_resp_ok_code:example:end -->

<!-- This section should explain how to use the `unwrap_err` method for a call response -->
<!-- call_resp_error:example:start -->
If `is_err` returns `true`, you can use the `unwrap_err` method to unwrap the error message.
<!-- call_resp_error:example:end -->

<!-- This section should show an example of how to unwrap a call response error -->
<!-- call_resp_error_code:example:start -->
```rust, ignore
if response.is_err() {
    let err = response.unwrap_err();
    println!("ERROR: {:?}", err);
};
```
<!-- call_resp_error_code:example:end -->


---

### File: docs/fuels-rs/docs/src/calling-contracts/calls-with-different-wallets.md

# Calls with different wallets

<!-- This section should explain how to call a contract with a certain wallet -->
<!-- wallet:example:start -->
You can use the `with_account()` method on an existing contract instance as a shorthand for creating a new instance connected to the provided wallet. This lets you make contracts calls with different wallets in a chain like fashion.
<!-- wallet:example:end-->

```rust,ignore
        // Create contract instance with wallet_1
        let contract_instance = MyContract::new(contract_id, wallet_1.clone());

        // Perform contract call with wallet_2
        let response = contract_instance
            .with_account(wallet_2) // Connect wallet_2
            .methods() // Get contract methods
            .get_msg_amount() // Our contract method
            .call() // Perform the contract call.
            .await?; // This is an async call, `.await` for it.
```

> **Note:** connecting a different wallet to an existing instance ignores its set provider in favor of the provider used to deploy the contract. If you have two wallets connected to separate providers (each communicating with a separate fuel-core), the one assigned to the deploying wallet will also be used for contract calls. This behavior is only relevant if multiple providers (i.e. fuel-core instances) are present and can otherwise be ignored.


---

### File: docs/fuels-rs/docs/src/calling-contracts/cost-estimation.md

# Estimating contract call cost

With the function `estimate_transaction_cost(tolerance: Option<f64>, block_horizon: Option<u32>)` provided by `CallHandler`, you can get a cost estimation for a specific call. The return type, `TransactionCost`, is a struct that contains relevant information for the estimation:

```rust,ignore
pub struct TransactionCost {
    pub gas_price: u64,
    pub metered_bytes_size: u64,
    pub total_fee: u64,
    pub script_gas: u64,
    pub total_gas: u64,
}
```

> **Note** `script_gas` refers to the part of the gas spent on the script execution.

Below are examples that show how to get the estimated transaction cost from single and multi call transactions.

```rust,ignore
        let contract_instance = MyContract::new(contract_id, wallet);

        let tolerance = Some(0.0);
        let block_horizon = Some(1);
        let transaction_cost = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .estimate_transaction_cost(tolerance, block_horizon) // Get estimated transaction cost
            .await?;
```

```rust,ignore
        let call_handler_1 = contract_methods.initialize_counter(42);
        let call_handler_2 = contract_methods.get_array([42; 2]);

        let multi_call_handler = CallHandler::new_multi_call(wallet.clone())
            .add_call(call_handler_1)
            .add_call(call_handler_2);

        let tolerance = Some(0.0);
        let block_horizon = Some(1);
        let transaction_cost = multi_call_handler
            .estimate_transaction_cost(tolerance, block_horizon) // Get estimated transaction cost
            .await?;
```

The transaction cost estimation can be used to set the gas limit for an actual call, or to show the user the estimated cost.

> **Note** The same estimation interface is available for scripts.


---

### File: docs/fuels-rs/docs/src/calling-contracts/custom-asset-transfer.md

# Custom asset transfer

<!-- This section should explain the `add_custom_asset()` method -->
<!-- transfer:example:start -->
The SDK provides the option to transfer assets within the same transaction, when making a contract call. By using `add_custom_asset()` you specify the asset ID, the amount, and the destination address:
<!-- transfer:example:end -->

```rust,ignore
        let amount = 1000;
        let _ = contract_instance
            .methods()
            .initialize_counter(42)
            .add_custom_asset(AssetId::zeroed(), amount, Some(some_addr))
            .call()
            .await?;
```


---

### File: docs/fuels-rs/docs/src/calling-contracts/custom-inputs-outputs.md

# Custom inputs and outputs

If you need to add specific inputs and outputs to contract calls, you can use the `with_inputs` and `with_outputs` methods.

```rust,ignore
        let _ = contract_instance
            .methods()
            .initialize_counter(42)
            .with_inputs(custom_inputs)
            .with_outputs(custom_outputs)
            .add_signer(wallet_2.signer().clone())
            .call()
            .await?;
```

> **Note:** if custom inputs include coins that need to be signed, use the `add_signer` method to add the appropriate signer.


---

### File: docs/fuels-rs/docs/src/calling-contracts/index.md

# Calling contracts

Once you've deployed your contract, as seen in the previous sections, you'll likely want to:

1. Call contract methods;
2. Configure call parameters and transaction policies;
3. Forward coins and gas in your contract calls;
4. Read and interpret returned values and logs.

Here's an example. Suppose your Sway contract has two ABI methods called `initialize_counter(u64)` and `increment_counter(u64)`. Once you've deployed it the contract, you can call these methods like this:

```rust,ignore
        // This will generate your contract's methods onto `MyContract`.
        // This means an instance of `MyContract` will have access to all
        // your contract's methods that are running on-chain!
        // ANCHOR: abigen_example
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        // ANCHOR_END: abigen_example

        // This is an instance of your contract which you can use to make calls to your functions
        let contract_instance = MyContract::new(contract_id_2, wallet);

        let response = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .call() // Perform the network call
            .await?;

        assert_eq!(42, response.value);

        let response = contract_instance
            .methods()
            .increment_counter(10)
            .call()
            .await?;

        assert_eq!(52, response.value);
```

The example above uses all the default configurations and performs a simple contract call.

Furthermore, if you need to separate submission from value retrieval for any reason, you can do so as follows:

```rust,ignore
        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .submit()
            .await?;

        tokio::time::sleep(Duration::from_millis(500)).await;
        let value = response.response().await?.value;

```

Next, we'll see how we can further configure the many different parameters in a contract call.


---

### File: docs/fuels-rs/docs/src/calling-contracts/logs.md

# Logs

Whenever you log a value within a contract method, the resulting log entry is added to the log receipt and the variable type is recorded in the contract's ABI. The SDK lets you parse those values into Rust types.

Consider the following contract method:

```rust,ignore
    fn produce_logs_variables() {
        let f: u64 = 64;
        let u: b256 = 0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a;
        let e: str[4] = __to_str_array("Fuel");
        let l: [u8; 3] = [1u8, 2u8, 3u8];

        log(f);
        log(u);
        log(e);
        log(l);
    }
```

You can access the logged values in Rust by calling `decode_logs_with_type::<T>` from a `CallResponse`, where `T` is the type of the logged variables you want to retrieve. The result will be a `Vec<T>`:

```rust,ignore
    let contract_methods = contract_instance.methods();
    let response = contract_methods.produce_logs_variables().call().await?;

    let log_u64 = response.decode_logs_with_type::<u64>()?;
    let log_bits256 = response.decode_logs_with_type::<Bits256>()?;
    let log_string = response.decode_logs_with_type::<SizedAsciiString<4>>()?;
    let log_array = response.decode_logs_with_type::<[u8; 3]>()?;

    let expected_bits256 = Bits256([
        239, 134, 175, 169, 105, 108, 240, 220, 99, 133, 226, 196, 7, 166, 225, 89, 161, 16, 60,
        239, 183, 226, 174, 6, 54, 251, 51, 211, 203, 42, 158, 74,
    ]);

    assert_eq!(log_u64, vec![64]);
    assert_eq!(log_bits256, vec![expected_bits256]);
    assert_eq!(log_string, vec!["Fuel"]);
    assert_eq!(log_array, vec![[1, 2, 3]]);
```

You can use the `decode_logs()` function to retrieve a `LogResult` struct containing a `results` field that is a vector of `Result<String>` values representing the success or failure of decoding each log.

```rust, ignore
    let contract_methods = contract_instance.methods();
    let response = contract_methods.produce_multiple_logs().call().await?;
    let logs = response.decode_logs();
```

Due to possible performance hits, it is not recommended to use `decode_logs()` outside of a debugging scenario.

> **Note:** String slices cannot be logged directly. Use the `__to_str_array()` function to convert it to a `str[N]` first.


---

### File: docs/fuels-rs/docs/src/calling-contracts/low-level-calls.md

# Low-level calls

<!-- This section should explain what low-level calls are and how to do them -->
With low-level calls, you can specify the parameters of your calls at runtime and make indirect calls through other contracts.

Your caller contract should call `std::low_level_call::call_with_function_selector`, providing:

- target contract ID
- function selector encoded as `Bytes`
- calldata encoded as `Bytes`
- whether the calldata contains only a single value argument (e.g. a `u64`)
- `std::low_level_call::CallParams`

```rust,ignore
    fn call_low_level_call(
        target: ContractId,
        function_selector: Bytes,
        calldata: Bytes,
    ) {
        let call_params = CallParams {
            coins: 0,
            asset_id: AssetId::from(ZERO_B256),
            gas: 10_000,
        };

        call_with_function_selector(target, function_selector, calldata, call_params);
    }
```

On the SDK side, you can construct an encoded function selector using `fuels::core::encode_fn_selector`, and encoded calldata using the `fuels::core::calldata!` macro.

E.g. to call the following function on the target contract:

```rust,ignore
    #[storage(write)]
    fn set_value_multiple_complex(a: MyStruct, b: str[4]);
```

you would construct the function selector and the calldata as such, and provide them to the caller contract (like the one above):

```rust,ignore
        let function_selector = encode_fn_selector("set_value_multiple_complex");
        let call_data = calldata!(
            MyStruct {
                a: true,
                b: [1, 2, 3],
            },
            SizedAsciiString::<4>::try_from("fuel")?
        )?;

        caller_contract_instance
            .methods()
            .call_low_level_call(
                target_contract_instance.id(),
                Bytes(function_selector),
                Bytes(call_data),
            )
            .determine_missing_contracts()
            .await?
            .call()
            .await?;
```

> Note: the `calldata!` macro uses the default `EncoderConfig` configuration under the hood.


---

### File: docs/fuels-rs/docs/src/calling-contracts/multicalls.md

# Multiple contract calls

With `CallHandler`, you can execute multiple contract calls within a single transaction. To achieve this, you first prepare all the contract calls that you want to bundle:

```rust,ignore
        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();

        let call_handler_1 = contract_methods.initialize_counter(42);
        let call_handler_2 = contract_methods.get_array([42; 2]);
```

You can also set call parameters, variable outputs, or external contracts for every contract call, as long as you don't execute it with `call()` or `simulate()`.

> **Note:** if custom inputs or outputs have been added to the separate calls, the input and output order will follow the order how the calls are added to the multi-call.

Next, you provide the prepared calls to your `CallHandler` and optionally configure transaction policies:

```rust,ignore
        let multi_call_handler = CallHandler::new_multi_call(wallet.clone())
            .add_call(call_handler_1)
            .add_call(call_handler_2)
            .with_tx_policies(TxPolicies::default());
```

> **Note:** any transaction policies configured on separate contract calls are disregarded in favor of the parameters provided to the multi-call `CallHandler`.

Furthermore, if you need to separate submission from value retrieval for any reason, you can do so as follows:

```rust,ignore
        let submitted_tx = multi_call_handler.submit().await?;
        tokio::time::sleep(Duration::from_millis(500)).await;
        let (counter, array): (u64, [u64; 2]) = submitted_tx.response().await?.value;
```

## Output values

To get the output values of the bundled calls, you need to provide explicit type annotations when saving the result of `call()` or `simulate()` to a variable:

```rust,ignore
        let (counter, array): (u64, [u64; 2]) = multi_call_handler.call().await?.value;
```

You can also interact with the `CallResponse` by moving the type annotation to the invoked method:

```rust,ignore
        let response = multi_call_handler.call::<(u64, [u64; 2])>().await?;
```


---

### File: docs/fuels-rs/docs/src/calling-contracts/other-contracts.md

# Calling other contracts

If your contract method is calling other contracts you will have to add the appropriate `Inputs` and `Outputs` to your transaction. For your convenience, the `CallHandler` provides methods that prepare those inputs and outputs for you. You have two methods that you can use: `with_contracts(&[&contract_instance, ...])` and `with_contract_ids(&[&contract_id, ...])`.

`with_contracts(&[&contract_instance, ...])` requires contract instances that were created using the `abigen` macro. When setting the external contracts with this method, logs and require revert errors originating from the external contract can be propagated and decoded by the calling contract.

```rust,ignore
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contracts(&[&lib_contract_instance])
        .call()
        .await?;
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contract_ids(&[lib_contract_id])
        .call()
        .await?;
```

 If however, you do not need to decode logs or you do not have a contract instance that was generated using the `abigen` macro you can use `with_contract_ids(&[&contract_id, ...])` and provide the required contract ids.

```rust,ignore
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contract_ids(&[lib_contract_id])
        .call()
        .await?;
```


---

### File: docs/fuels-rs/docs/src/calling-contracts/simulation.md

# Simulating calls

Sometimes you want to simulate a call to a contract without changing the state of the blockchain. This can be achieved by calling `.simulate` instead of `.call` and passing in the desired execution context:

* `.simulate(Execution::realistic())` simulates the transaction in a manner that closely resembles a real call. You need a wallet with base assets to cover the transaction cost, even though no funds will be consumed. This is useful for validating that a real call would succeed if made at that moment. It allows you to debug issues with your contract without spending gas.

```rust,ignore
        // you would mint 100 coins if the transaction wasn't simulated
        let counter = contract_methods
            .mint_coins(100)
            .simulate(Execution::realistic())
            .await?;
            // you don't need any funds to read state
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only())
                .await?
                .value;
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only().at_height(block_height))
                .await?
                .value;
```

* `.simulate(Execution::state_read_only())` disables many validations, adds fake gas, extra variable outputs, blank witnesses, etc., enabling you to read state even with an account that has no funds.

```rust,ignore
            // you don't need any funds to read state
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only())
                .await?
                .value;
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only().at_height(block_height))
                .await?
                .value;
```

If the node supports historical execution (the node is using `rocksdb` and the `historical_execution` flag has been set), then both execution types can be chained with `at_height` to simulate the call at a specific block height.

```rust,ignore
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only().at_height(block_height))
                .await?
                .value;
```


---

### File: docs/fuels-rs/docs/src/calling-contracts/tx-dependency-estimation.md

# Transaction dependency estimation

Previously, we mentioned that a contract call might require you to manually specify external contracts, variable outputs, or output messages. The SDK can also attempt to estimate and set these dependencies for you at the cost of running multiple simulated calls in the background.

The following example uses a contract call that calls an external contract and later mints assets to a specified address. Calling it without including the dependencies will result in a revert:

```rust,ignore
        let address = wallet.address();
        let amount = 100;

        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .call()
            .await;

        assert!(matches!(
            response,
            Err(Error::Transaction(Reason::Failure { .. }))
        ));
```

As mentioned in previous chapters, you can specify the external contract and add an output variable to resolve this:

```rust,ignore
        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .with_contract_ids(&[called_contract_id])
            .call()
            .await?;
```

But this requires you to know the contract ID of the external contract and the needed number of output variables. Alternatively, by chaining

- `.with_variable_output_policy(VariableOutputPolicy::EstimateMinimum)` and
- `.determine_missing_contracts()`

the dependencies will be estimated by the SDK and set automatically.

```rust,ignore
        let address = wallet.address();
        let amount = 100;

        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .call()
            .await;

        assert!(matches!(
            response,
            Err(Error::Transaction(Reason::Failure { .. }))
        ));
        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .with_contract_ids(&[called_contract_id])
            .call()
            .await?;
        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .with_variable_output_policy(VariableOutputPolicy::EstimateMinimum)
            .determine_missing_contracts()
            .await?
            .call()
            .await?;
```

> **Note:** Both `with_variable_output_policy` and `determine_missing_contracts` can also be used when working with script calls or multi calls. `determine_missing_contracts()` will not enable logging from an external contract. For more information, see [here](./other-contracts.md).


---

### File: docs/fuels-rs/docs/src/calling-contracts/tx-policies.md

# Transaction policies

<!-- This section should explain what tx policies are and how to configure them -->
<!-- tx_policies:example:start -->
Transaction policies are defined as follows:

```rust,ignore
pub struct TxPolicies {
    tip: Option<u64>,
    witness_limit: Option<u64>,
    maturity: Option<u64>,
    expiration: Option<u64>,
    max_fee: Option<u64>,
    script_gas_limit: Option<u64>,
}
```

Where:

1. **Tip** - amount to pay the block producer to prioritize the transaction.
2. **Witness Limit** - The maximum amount of witness data allowed for the transaction.
3. **Maturity** - Block until which the transaction cannot be included.
4. **Expiration** - Block after which the transaction cannot be included.
5. **Max Fee** - The maximum fee payable by this transaction.
6. **Script Gas Limit** - The maximum amount of gas the transaction may consume for executing its script code.

When the **Script Gas Limit** is not set, the Rust SDK will estimate the consumed gas in the background and set it as the limit.

If the **Witness Limit** is not set, the SDK will set it to the size of all witnesses and signatures defined in the transaction builder.

You can configure these parameters by creating an instance of `TxPolicies` and passing it to a chain method called `with_tx_policies`:
<!-- tx_policies:example:end-->

```rust,ignore
        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();

        let tx_policies = TxPolicies::default()
            .with_tip(1)
            .with_script_gas_limit(1_000_000)
            .with_maturity(0)
            .with_expiration(10_000);

        let response = contract_methods
            .initialize_counter(42) // Our contract method
            .with_tx_policies(tx_policies) // Chain the tx policies
            .call() // Perform the contract call
            .await?; // This is an async call, `.await` it.
        let response = contract_methods
            .initialize_counter(42)
            .with_tx_policies(TxPolicies::default())
            .call()
            .await?;
```

<!-- This section should explain how to use the default tx policy -->
<!-- tx_policies_default:example:start -->
You can also use `TxPolicies::default()` to use the default values.
<!-- tx_policies_default:example:end -->

This way:

```rust,ignore
        let response = contract_methods
            .initialize_counter(42)
            .with_tx_policies(TxPolicies::default())
            .call()
            .await?;
```

As you might have noticed, `TxPolicies` can also be specified when deploying contracts or transferring assets by passing it to the respective methods.


---

### File: docs/fuels-rs/docs/src/calling-contracts/variable-outputs.md

# Output variables

<!-- This section should explain variable outputs  -->
<!-- variable_outputs:example:start -->
Sometimes, the contract you call might transfer funds to a specific address, depending on its execution. The underlying transaction for such a contract call has to have the appropriate number of [variable outputs](https://docs.fuel.network/docs/specs/tx-format/output/#outputvariable) to succeed.
<!-- variable_outputs:example:end -->

Let's say you deployed a contract with the following method:

```rust,ignore
    fn transfer(coins: u64, asset_id: AssetId, recipient: Identity) {
        transfer(recipient, asset_id, coins);
    }
```

When calling `transfer_coins_to_output` with the SDK, you can specify the number of variable outputs:

```rust,ignore
        let address = wallet.address();
        let asset_id = contract_id.asset_id(&SubAssetId::zeroed());

        // withdraw some tokens to wallet
        let response = contract_methods
            .transfer(1_000_000, asset_id, address.into())
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .call()
            .await?;
```

<!-- This section should explain what the `with_variable_output_policy` method does -->
<!-- with_variable_output_policy:example:start -->
`with_variable_output_policy` sets the policy regarding variable outputs. You can either set the number of variable outputs yourself by providing `VariableOutputPolicy::Exactly(n)` or let the SDK estimate it for you with `VariableOutputPolicy::EstimateMinimum`. A variable output indicates that the amount and the owner may vary based on transaction execution.
<!-- with_variable_output_policy:example:end -->

> **Note:** that the Sway `lib-std` function `mint_to_address` calls `transfer_to_address` under the hood, so you need to call `with_variable_output_policy` in the Rust SDK tests like you would for `transfer_to_address`.


---

### File: docs/fuels-rs/docs/src/cli/fuels-abi-cli.md

# `fuels-abi-cli`

Simple CLI program to encode Sway function calls and decode their output. The ABI being encoded and decoded is specified [here](https://docs.fuel.network/docs/specs/abi/).

## Usage

```plaintext
sway-abi-cli 0.1.0
FuelVM ABI coder

USAGE:
    sway-abi-cli <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    codegen   Output Rust types file
    decode    Decode ABI call result
    encode    Encode ABI call
    help      Prints this message or the help of the given subcommand(s)
```

## Examples

You can choose to encode only the given params or you can go a step further and have a full JSON ABI file and encode the whole input to a certain function call defined in the JSON file.

### Encoding params only

```console
$ cargo run -- encode params -v bool true
0000000000000001
```

```console
$ cargo run -- encode params -v bool true -v u32 42 -v u32 100
0000000000000001000000000000002a0000000000000064
```

Note that for every parameter you want to encode, you must pass a `-v` flag followed by the type, and then the value: `-v <type_1> <value_1> -v <type_2> <value_2> -v <type_n> <value_n>`

### Encoding function call

`example/simple.json`:

```json
[
  {
    "type":"function",
    "inputs":[
      {
        "name":"arg",
        "type":"u32"
      }
    ],
    "name":"takes_u32_returns_bool",
    "outputs":[
      {
        "name":"",
        "type":"bool"
      }
    ]
  }
]
```

```console
$ cargo run -- encode function examples/simple.json takes_u32_returns_bool -p 4
000000006355e6ee0000000000000004
```

`example/array.json`

```json
[
  {
    "type":"function",
    "inputs":[
      {
        "name":"arg",
        "type":"u16[3]"
      }
    ],
    "name":"takes_array",
    "outputs":[
      {
        "name":"",
        "type":"u16[2]"
      }
    ]
  }
]
```

```console
$ cargo run -- encode function examples/array.json takes_array -p '[1,2]'
00000000f0b8786400000000000000010000000000000002
```

Note that the first word (8 bytes) of the output is reserved for the function selector, which is captured in the last 4 bytes, which is simply the 256hash of the function signature.

Example with nested struct:

```json
[
  {
    "type":"contract",
    "inputs":[
      {
        "name":"MyNestedStruct",
        "type":"struct",
        "components":[
          {
            "name":"x",
            "type":"u16"
          },
          {
            "name":"y",
            "type":"struct",
            "components":[
              {
                "name":"a",
                "type":"bool"
              },
              {
                "name":"b",
                "type":"u8[2]"
              }
            ]
          }
        ]
      }
    ],
    "name":"takes_nested_struct",
    "outputs":[

    ]
  }
]
```

```console
$ cargo run -- encode function examples/nested_struct.json takes_nested_struct -p '(10, (true, [1,2]))'
00000000e8a04d9c000000000000000a000000000000000100000000000000010000000000000002
```

### Decoding params only

Similar to encoding parameters only:

```console
$ cargo run -- decode params -t bool -t u32 -t u32 0000000000000001000000000000002a0000000000000064
Bool(true)
U32(42)
U32(100)
```

### Decoding function output

```console
$ cargo run -- decode function examples/simple.json takes_u32_returns_bool 0000000000000001
Bool(true)
```


---

### File: docs/fuels-rs/docs/src/cli/index.md

# `fuels-rs` Rust Workspaces

This section gives you a little overview of the role and function of every workspace in the `fuels-rs` repository.

- [`fuels-abi-cli`](./fuels-abi-cli.md)


---

### File: docs/fuels-rs/docs/src/codec/decoding.md

# Decoding

Be sure to read the [prerequisites](./index.md#prerequisites-for-decodingencoding) to decoding.

Decoding is done via the [`ABIDecoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIDecoder.html):

```rust,ignore
        use fuels::{
            core::{
                codec::ABIDecoder,
                traits::{Parameterize, Tokenizable},
            },
            macros::{Parameterize, Tokenizable},
            types::Token,
        };

        #[derive(Parameterize, Tokenizable)]
        struct MyStruct {
            field: u64,
        }

        let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];

        let token: Token = ABIDecoder::default().decode(&MyStruct::param_type(), bytes)?;

        let _: MyStruct = MyStruct::from_token(token)?;
        use fuels::macros::{Parameterize, Tokenizable, TryFrom};

        #[derive(Parameterize, Tokenizable, TryFrom)]
        struct MyStruct {
            field: u64,
        }

        let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];

        let _: MyStruct = bytes.try_into()?;
```

First into a [`Token`](https://docs.rs/fuels/latest/fuels/types/enum.Token.html), then via the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) trait, into the desired type.

If the type came from [`abigen!`](../abigen/index.md) (or uses the [`::fuels::macros::TryFrom`](https://docs.rs/fuels/latest/fuels/macros/derive.TryFrom.html) derivation) then you can also use `try_into` to convert bytes into a type that implements both [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) and [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html):

```rust,ignore
        use fuels::macros::{Parameterize, Tokenizable, TryFrom};

        #[derive(Parameterize, Tokenizable, TryFrom)]
        struct MyStruct {
            field: u64,
        }

        let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];

        let _: MyStruct = bytes.try_into()?;
```

Under the hood, [`try_from_bytes`](https://docs.rs/fuels/latest/fuels/core/codec/fn.try_from_bytes.html) is being called, which does what the preceding example did.

## Configuring the decoder

The decoder can be configured to limit its resource expenditure:

```rust,ignore

        use fuels::core::codec::ABIDecoder;

        ABIDecoder::new(DecoderConfig {
            max_depth: 5,
            max_tokens: 100,
        });
```

<!-- TODO: Add a link once a release is made -->
<!-- https://docs.rs/fuels/latest/fuels/core/codec/struct.DecoderConfig.html -->
For an explanation of each configuration value visit the `DecoderConfig`.

<!-- TODO: add a link once a release is made -->
<!-- https://docs.rs/fuels/latest/fuels/core/codec/struct.DecoderConfig.html -->
The default values for the `DecoderConfig` are:

```rust,ignore
impl Default for DecoderConfig {
    fn default() -> Self {
        Self {
            max_depth: 45,
            max_tokens: 10_000,
        }
    }
}
```

## Configuring the decoder for contract/script calls

You can also configure the decoder used to decode the return value of the contract method:

```rust,ignore
        let _ = contract_instance
            .methods()
            .initialize_counter(42)
            .with_decoder_config(DecoderConfig {
                max_depth: 10,
                max_tokens: 2_000,
            })
            .call()
            .await?;
```

The same method is available for script calls.


---

### File: docs/fuels-rs/docs/src/codec/encoding.md

# Encoding

Be sure to read the [prerequisites](./index.md#prerequisites-for-decodingencoding) to encoding.

Encoding is done via the [`ABIEncoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIEncoder.html):

```rust,ignore
        use fuels::{
            core::{codec::ABIEncoder, traits::Tokenizable},
            macros::Tokenizable,
        };

        #[derive(Tokenizable)]
        struct MyStruct {
            field: u64,
        }

        let instance = MyStruct { field: 101 };
        let _encoded: Vec<u8> = ABIEncoder::default().encode(&[instance.into_token()])?;
        use fuels::{core::codec::calldata, macros::Tokenizable};

        #[derive(Tokenizable)]
        struct MyStruct {
            field: u64,
        }
        let _: Vec<u8> = calldata!(MyStruct { field: 101 }, MyStruct { field: 102 })?;
```

There is also a shortcut-macro that can encode multiple types which implement [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html):

```rust,ignore
        use fuels::{core::codec::calldata, macros::Tokenizable};

        #[derive(Tokenizable)]
        struct MyStruct {
            field: u64,
        }
        let _: Vec<u8> = calldata!(MyStruct { field: 101 }, MyStruct { field: 102 })?;
```

## Configuring the encoder

The encoder can be configured to limit its resource expenditure:

```rust,ignore
        use fuels::core::codec::ABIEncoder;

        ABIEncoder::new(EncoderConfig {
            max_depth: 5,
            max_tokens: 100,
        });
```

The default values for the `EncoderConfig` are:

```rust,ignore
impl Default for EncoderConfig {
    fn default() -> Self {
        Self {
            max_depth: 45,
            max_tokens: 10_000,
        }
    }
}
```

## Configuring the encoder for contract/script calls

You can also configure the encoder used to encode the arguments of the contract method:

```rust,ignore
        let _ = contract_instance
            .with_encoder_config(EncoderConfig {
                max_depth: 10,
                max_tokens: 2_000,
            })
            .methods()
            .initialize_counter(42)
            .call()
            .await?;
```

The same method is available for script calls.


---

### File: docs/fuels-rs/docs/src/codec/index.md

# Codec

Encoding and decoding are done as per [the fuel spec](https://docs.fuel.network/docs/specs/abi/argument-encoding/). To this end, `fuels` makes use of the [`ABIEncoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIEncoder.html) and the [`ABIDecoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIDecoder.html).

## Prerequisites for decoding/encoding

To encode a type, you must first convert it into a [`Token`](https://docs.rs/fuels/latest/fuels/types/enum.Token.html). This is commonly done by implementing the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) trait.

To decode, you also need to provide a [`ParamType`](https://docs.rs/fuels/latest/fuels/types/param_types/enum.ParamType.html) describing the schema of the type in question. This is commonly done by implementing the [Parameterize](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) trait.

All types generated by the [`abigen!`](../abigen/index.md) macro implement both the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) and [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) traits.

`fuels` also contains implementations for:

- [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) for the `fuels`-owned types listed [here](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html#implementors) as well as [for some foreign types](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html#foreign-impls) (such as `u8`, `u16`, `std::vec::Vec<T: Tokenizable>`, etc.).
- [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) for the `fuels`-owned types listed [here](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html#implementors) as well as [for some foreign types](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html#foreign-impls) (such as `u8`, `u16`, `std::vec::Vec<T: Parameterize>`, etc.).

## Deriving the traits

Both [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) and [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) can be derived for `struct`s and `enum`s if all inner types implement the derived traits:

```rust,ignore
        use fuels::macros::{Parameterize, Tokenizable};

        #[derive(Parameterize, Tokenizable)]
        struct MyStruct {
            field_a: u8,
        }

        #[derive(Parameterize, Tokenizable)]
        enum SomeEnum {
            A(MyStruct),
            B(Vec<u64>),
        }
            #[derive(Parameterize, Tokenizable)]
            #[FuelsCorePath = "fuels_core_elsewhere"]
            #[FuelsTypesPath = "fuels_types_elsewhere"]
            pub struct SomeStruct {
                field_a: u64,
            }
            use fuels::macros::{Parameterize, Tokenizable};
            #[derive(Parameterize, Tokenizable)]
            #[NoStd]
            pub struct SomeStruct {
                field_a: u64,
            }
```

> Note:
> Deriving [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) on `enum`s requires that all variants also implement [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html).

### Tweaking the derivation

#### Changing the location of imports

The derived code expects that the `fuels` package is accessible through `::fuels`. If this is not the case then the derivation macro needs to be given the locations of `fuels::types` and `fuels::core`.

```rust,ignore
            #[derive(Parameterize, Tokenizable)]
            #[FuelsCorePath = "fuels_core_elsewhere"]
            #[FuelsTypesPath = "fuels_types_elsewhere"]
            pub struct SomeStruct {
                field_a: u64,
            }
```

#### Generating no-std code

If you want `no-std` generated code:

```rust,ignore
            use fuels::macros::{Parameterize, Tokenizable};
            #[derive(Parameterize, Tokenizable)]
            #[NoStd]
            pub struct SomeStruct {
                field_a: u64,
            }
```


---

### File: docs/fuels-rs/docs/src/connecting/external-node.md

# Connecting to the Testnet or an external node

We can interact with the `Testnet` node by using the following example.

```rust,ignore
        use std::str::FromStr;

        use fuels::{crypto::SecretKey, prelude::*};

        // Create a provider pointing to the testnet.
        let provider = Provider::connect("testnet.fuel.network").await.unwrap();

        // Setup a private key
        let secret = SecretKey::from_str(
            "a1447cd75accc6b71a976fd3401a1f6ce318d27ba660b0315ee6ac347bf39568",
        )?;

        // Create the wallet
        let wallet = Wallet::new(PrivateKeySigner::new(secret), provider);

        // Get the wallet address. Used later with the faucet
        dbg!(wallet.address().to_string());
```
>
> For detailed information about various testnet networks and their optimal toolchain configurations for your project, please visit the following link:
>
> [networks](https://fuelbook.fuel.network/master/networks/networks.html)

In the code example, we connected a new provider to the Testnet node and created a new wallet from a private key.

> **Note:** New wallets on the Testnet will not have any assets! They can be obtained by providing the wallet address to the faucet at
>
>[faucet-testnet.fuel.network](https://faucet-testnet.fuel.network)
>
> Once the assets have been transferred to the wallet, you can reuse it in other tests by providing the private key!
>
> In addition to the faucet, there is a block explorer for the Testnet at
>
> [block-explorer](https://fuellabs.github.io/block-explorer-v2)

If you want to connect to another node just change the URL or IP and port. For example, to connect to a local node that was created with `fuel-core` you can use:

```rust,ignore
        let _provider = Provider::connect(format!("127.0.0.1:{port}")).await?;
```


---

### File: docs/fuels-rs/docs/src/connecting/index.md

# Connecting to a Fuel node

<!-- This section should explain at a high level the main ways to connect to a node with the Rust SDK and when they are appropriate to use-->
<!-- rs_node:example:start -->
At a high level, you can use the Fuel Rust SDK to build Rust-based applications that can run computations on the Fuel Virtual Machine through interactions with smart contracts written in Sway.

For this interaction to work, the SDK must be able to communicate with a `fuel-core` node; you have two options at your disposal:

1. Use the testnet or run a Fuel node (using `fuel-core`) and instantiate a provider that points to that node's IP and port.
2. Use the SDK's native `launch_provider_and_get_wallet()` that runs a short-lived test Fuel node;

The second option is ideal for smart contract testing, as you can quickly spin up and tear down nodes between specific test cases.

For application building, you should use the first option.
<!-- rs_node:example:end -->


---

### File: docs/fuels-rs/docs/src/connecting/querying.md

# Querying the blockchain

Once you set up a provider, you can interact with the Fuel blockchain. Here are a few examples of what you can do with a provider; for a more in-depth overview of the API, check the [official provider API documentation](https://docs.rs/fuels/latest/fuels/accounts/provider/struct.Provider.html).

- [Set up](#set-up)
- [Get all coins from an address](#get-all-coins-from-an-address)
- [Get spendable resources owned by an address](#get-spendable-resources-owned-by-an-address)
- [Get balances from an address](#get-balances-from-an-address)

## Set up

You might need to set up a test blockchain first. You can skip this step if you're connecting to an external blockchain.

```rust,ignore
        use fuels::prelude::*;

        // Set up our test blockchain.

        // Create a random signer
        // ANCHOR: setup_single_asset
        let wallet_signer = PrivateKeySigner::random(&mut rand::thread_rng());

        // How many coins in our wallet.
        let number_of_coins = 1;

        // The amount/value in each coin in our wallet.
        let amount_per_coin = 3;

        let coins = setup_single_asset_coins(
            wallet_signer.address(),
            AssetId::zeroed(),
            number_of_coins,
            amount_per_coin,
        );
        // ANCHOR_END: setup_single_asset

        // ANCHOR: configure_retry
        let retry_config = RetryConfig::new(3, Backoff::Fixed(Duration::from_secs(2)))?;
        let provider = setup_test_provider(coins.clone(), vec![], None, None)
            .await?
            .with_retry_config(retry_config);
        // ANCHOR_END: configure_retry
```

## Get all coins from an address

This method returns all unspent coins (of a given asset ID) from a wallet.

```rust,ignore
        let consensus_parameters = provider.consensus_parameters().await?;
        let coins = provider
            .get_coins(
                &wallet_signer.address(),
                *consensus_parameters.base_asset_id(),
            )
            .await?;
        assert_eq!(coins.len(), 1);
```

## Get spendable resources owned by an address

The following example shows how to fetch resources owned by an address. First, you create a  `ResourceFilter` which specifies the target address, asset ID, and amount. You can also define UTXO IDs and message IDs that should be excluded when retrieving the resources:

```rust,ignore
pub struct ResourceFilter {
    pub from: Address,
    pub asset_id: Option<AssetId>,
    pub amount: u128,
    pub excluded_utxos: Vec<UtxoId>,
    pub excluded_message_nonces: Vec<Nonce>,
}
```

The example uses default values for the asset ID and the exclusion lists. This resolves to the base asset ID and empty vectors for the ID lists respectively:

```rust,ignore
        let filter = ResourceFilter {
            from: wallet_signer.address(),
            amount: 1,
            ..Default::default()
        };
        let spendable_resources = provider.get_spendable_resources(filter).await?;
        assert_eq!(spendable_resources.len(), 1);
```

## Get balances from an address

Get all the spendable balances of all assets for an address. This is different from getting the coins because we only return the numbers (the sum of UTXOs coins amount for each asset ID) and not the UTXOs coins themselves.

```rust,ignore
        let _balances = provider.get_balances(&wallet_signer.address()).await?;
```


---

### File: docs/fuels-rs/docs/src/connecting/retrying.md

# Retrying requests

The [`Provider`](https://docs.rs/fuels/0.62.0/fuels/accounts/provider/struct.Provider.html) can be configured to retry a request upon receiving a `io::Error`.

> Note: Currently all node errors are received as `io::Error`s. So, if configured, a retry will happen even if, for example, a transaction failed to verify.

We can configure the number of retry attempts and the retry strategy as detailed below.

## `RetryConfig`

The retry behavior can be altered by giving a custom `RetryConfig`. It allows for configuring the maximum number of attempts and the interval strategy used.

```rust, ignore
#[derive(Clone, Debug)]
pub struct RetryConfig {
    max_attempts: NonZeroU32,
    interval: Backoff,
}
```

```rust, ignore
        let retry_config = RetryConfig::new(3, Backoff::Fixed(Duration::from_secs(2)))?;
        let provider = setup_test_provider(coins.clone(), vec![], None, None)
            .await?
            .with_retry_config(retry_config);
```

## Interval strategy - `Backoff`

`Backoff` defines different strategies for managing intervals between retry attempts.
Each strategy allows you to customize the waiting time before a new attempt based on the number of attempts made.

### Variants

- `Linear(Duration)`: `Default` Increases the waiting time linearly with each attempt.
- `Exponential(Duration)`: Doubles the waiting time with each attempt.
- `Fixed(Duration)`: Uses a constant waiting time between attempts.

```rust, ignore
#[derive(Debug, Clone)]
pub enum Backoff {
    Linear(Duration),
    Exponential(Duration),
    Fixed(Duration),
}
```


---

### File: docs/fuels-rs/docs/src/connecting/rocksdb.md

# RocksDB

RocksDB enables the preservation of the blockchain's state locally, facilitating its future utilization.

To create or use a local database, follow these instructions:

```rust,ignore
        let provider_config = NodeConfig {
            database_type: DbType::RocksDb(Some(PathBuf::from("/tmp/.spider/db"))),
            ..NodeConfig::default()
        };
```

> Note: If the specified database does not exist, a new database will be created at that path. To utilize the code snippets above, either the `fuel-core` binary must be present, or both the `fuel-core-lib` and `rocksdb` features need to be enabled.


---

### File: docs/fuels-rs/docs/src/connecting/short-lived.md

# Running a short-lived Fuel node with the SDK

You can use the SDK to spin up a local, ideally short-lived Fuel node. Then, you can instantiate a Fuel client, pointing to this node.

```rust,ignore
        use fuels::prelude::{FuelService, Provider};

        // Run the fuel node.
        let server = FuelService::start(
            NodeConfig::default(),
            ChainConfig::default(),
            StateConfig::default(),
        )
        .await?;

        // Create a client that will talk to the node created above.
        let client = Provider::from(server.bound_address()).await?;
        assert!(client.healthy().await?);
```

This approach is ideal for contract testing.

You can also use the test helper `setup_test_provider()` for this:

```rust,ignore
        use fuels::prelude::*;

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Create the wallet.
        let _wallet = Wallet::random(&mut thread_rng(), provider);
```

You can also use `launch_provider_and_get_wallet()`, which abstracts away the `setup_test_provider()` and the wallet creation, all in one single method:

```rust,ignore
let wallet = launch_provider_and_get_wallet().await?;
```

## Features

### Fuel-core lib

The `fuel-core-lib` feature allows us to run a `fuel-core` node without installing the `fuel-core` binary on the local machine. Using the `fuel-core-lib` feature flag entails downloading all the dependencies needed to run the fuel-core node.

```rust,ignore
fuels = { version = "0.74.0", features = ["fuel-core-lib"] }
```

### RocksDB

The `rocksdb` is an additional feature that, when combined with `fuel-core-lib`, provides persistent storage capabilities while using `fuel-core` as a library.

```rust,ignore
fuels = { version = "0.74.0", features = ["rocksdb"] }
```


---

### File: docs/fuels-rs/docs/src/contributing/CONTRIBUTING.md

# Contributing to the Fuel Rust SDK

Thanks for your interest in contributing to the Fuel Rust SDK!

This document outlines the process for installing dependencies, setting up for development, and conventions for contributing.`

If you run into any difficulties getting started, you can always ask questions on our [Discourse](https://forum.fuel.network/).

## Finding something to work on

You may contribute to the project in many ways, some of which involve coding knowledge and some which do not. A few examples include:

- Reporting bugs
- Adding new features or bug fixes for which there is already an open issue
- Making feature requests

Check out our [Help Wanted](https://github.com/FuelLabs/fuels-rs/labels/help%20wanted) or [Good First Issues](https://github.com/FuelLabs/fuels-rs/labels/good%20first%20issue) to find a suitable task.

If you are planning something big, for example, changes related to multiple components or changes to current behaviors, make sure to [open an issue](https://github.com/FuelLabs/fuels-rs/issues/new) to discuss with us before starting on the implementation.

## Contribution flow

This is a rough outline of what a contributor's workflow looks like:

- Make sure what you want to contribute is already tracked as an issue.
  - We may discuss the problem and solution in the issue.
- Create a Git branch from where you want to base your work. This is usually master.
- Write code, add test cases, and commit your work.
- Run tests and make sure all tests pass.
- Add the breaking label to your PR if the PR contains any breaking changes.
- Push your changes to a branch in your fork of the repository and submit a pull request.
  - Make sure to mention the issue created in step 1 in the commit message.
- Your PR will be reviewed, and some changes may be requested.
  - Your PR must be re-reviewed and approved once you've made changes.
  - Use GitHub's 'update branch' button if the PR becomes outdated.
  - If there are conflicts, you can merge and resolve them locally. Then push to your PR branch. Any changes to the branch will require a re-review.
- Our CI system (Github Actions) automatically tests all authorized pull requests.
- Use GitHub to merge the PR once approved.

Thanks for your contributions!

## Linking issues

Pull requests should be linked to at least one issue in the same repo.

If the pull request resolves the relevant issues, and you want GitHub to close these issues automatically after it merged into the default branch, you can use the syntax (`KEYWORD #ISSUE-NUMBER`) like this:

```sh
close #123
```

If the pull request links an issue but does not close it, you can use the keyword `ref` like this:

```sh
ref #456
```

Multiple issues should use full syntax for each issue and be separated by a comma, like:

```sh
close #123, ref #456
```


---

### File: docs/fuels-rs/docs/src/contributing/tests-structure.md

# Integration tests structure in `fuels-rs`

The integration tests of `fuels-rs` cover almost all aspects of the SDK and have grown significantly as more functionality was added. To make the tests and associated `Sway` projects more manageable they were split into several categories. A category consist of a `.rs` file for the tests and, if needed, a separate directory for the `Sway` projects.

Currently have the following structure:

```shell
  .
  ├─  bindings/
  ├─  contracts/
  ├─  logs/
  ├─  predicates/
  ├─  storage/
  ├─  types/
  ├─  bindings.rs
  ├─  contracts.rs
  ├─  from_token.rs
  ├─  logs.rs
  ├─  predicates.rs
  ├─  providers.rs
  ├─  scripts.rs
  ├─  storage.rs
  ├─  types.rs
  └─  wallets.rs
```

Even though test organization is subjective, please consider these guidelines before adding a new category:

- Add a new category when creating a new section in the `Fuels Rust SDK` book - e.g. `Types`
- Add a new category if there are more than 3 test and more than 100 lines of code and they form a group of tests - e.g. `storage.rs`

 Otherwise, we recommend putting the integration test inside the existing categories above.


---

### File: docs/fuels-rs/docs/src/cookbook/custom-chain.md

# Custom chain

This example demonstrates how to start a short-lived Fuel node with custom consensus parameters for the underlying chain.

First, we have to import `ConsensusParameters` and `ChainConfig`:

```rust,ignore
        use fuels::{
            prelude::*,
            tx::{ConsensusParameters, FeeParameters, TxParameters},
        };
```

Next, we can define some values for the consensus parameters:

```rust,ignore
        let tx_params = TxParameters::default()
            .with_max_gas_per_tx(1_000)
            .with_max_inputs(2);
        let fee_params = FeeParameters::default().with_gas_price_factor(10);

        let mut consensus_parameters = ConsensusParameters::default();
        consensus_parameters.set_tx_params(tx_params);
        consensus_parameters.set_fee_params(fee_params);

        let chain_config = ChainConfig {
            consensus_parameters,
            ..ChainConfig::default()
        };
```

Before we can start a node, we probably also want to define some genesis coins and assign them to an address:

```rust,ignore
        let signer = PrivateKeySigner::random(&mut thread_rng());
        let coins = setup_single_asset_coins(
            signer.address(),
            Default::default(),
            DEFAULT_NUM_COINS,
            DEFAULT_COIN_AMOUNT,
        );
```

Finally, we call `setup_test_provider()`, which starts a node with the given configurations and returns a
provider attached to that node:

```rust,ignore
        let node_config = NodeConfig::default();
        let _provider =
            setup_test_provider(coins, vec![], Some(node_config), Some(chain_config)).await?;
```


---

### File: docs/fuels-rs/docs/src/cookbook/deposit-and-withdraw.md

# Deposit and withdraw

Consider the following contract:

```rust,ignore
contract;

use std::{asset::{mint_to, transfer}, call_frames::msg_asset_id, context::msg_amount};
abi LiquidityPool {
    #[payable]
    fn deposit(recipient: Identity);
    #[payable]
    fn withdraw(recipient: Identity);
}
const BASE_TOKEN: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);
impl LiquidityPool for Contract {
    #[payable]
    fn deposit(recipient: Identity) {
        assert(BASE_TOKEN == msg_asset_id());
        assert(0 < msg_amount());
        // Mint two times the amount.
        let amount_to_mint = msg_amount() * 2;
        // Mint some LP token based upon the amount of the base token.
        mint_to(recipient, b256::zero(), amount_to_mint);
    }
    #[payable]
    fn withdraw(recipient: Identity) {
        assert(0 < msg_amount());
        // Amount to withdraw.
        let amount_to_transfer = msg_amount() / 2;
        // Transfer base token to recipient.
        transfer(recipient, BASE_TOKEN, amount_to_transfer);
    }
}

```

As its name suggests, it represents a simplified example of a liquidity pool contract. The method `deposit()` expects you to supply an arbitrary amount of the `BASE_TOKEN`. As a result, it mints double the amount of the liquidity asset to the calling address. Analogously, if you call `withdraw()` supplying it with the liquidity asset, it will transfer half that amount of the `BASE_TOKEN` back to the calling address except for deducting it from the contract balance instead of minting it.

The first step towards interacting with any contract in the Rust SDK is calling the `abigen!` macro to generate type-safe Rust bindings for the contract methods:

```rust,ignore
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/liquidity_pool/out/release/liquidity_pool-abi.json"
        ));
```

Next, we set up a wallet with custom-defined assets. We give our wallet some of the contracts `BASE_TOKEN` and the default asset (required for contract deployment):

```rust,ignore
        let base_asset_id: AssetId =
            "0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c".parse()?;

        let asset_ids = [AssetId::zeroed(), base_asset_id];
        let asset_configs = asset_ids
            .map(|id| AssetConfig {
                id,
                num_coins: 1,
                coin_amount: 1_000_000,
            })
            .into();

        let wallet_config = WalletsConfig::new_multiple_assets(1, asset_configs);
        let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?;
        let wallet = &wallets[0];
```

Having launched a provider and created the wallet, we can deploy our contract and create an instance of its methods:

```rust,ignore
        let contract_id = Contract::load_from(
            "../../e2e/sway/contracts/liquidity_pool/out/release/liquidity_pool.bin",
            LoadConfiguration::default(),
        )?
        .deploy(wallet, TxPolicies::default())
        .await?
        .contract_id;

        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();
```

With the preparations out of the way, we can finally deposit to the liquidity pool by calling `deposit()` via the contract instance. Since we have to transfer assets to the contract, we create the appropriate `CallParameters` and chain them to the method call. To receive the minted liquidity pool asset, we have to append a variable output to our contract call.

```rust,ignore
        let deposit_amount = 1_000_000;
        let call_params = CallParameters::default()
            .with_amount(deposit_amount)
            .with_asset_id(base_asset_id);

        contract_methods
            .deposit(wallet.address().into())
            .call_params(call_params)?
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .call()
            .await?;
```

As a final demonstration, let's use all our liquidity asset balance to withdraw from the pool and confirm we retrieved the initial amount. For this, we get our liquidity asset balance and supply it to the `withdraw()` call via `CallParameters`.

```rust,ignore
        let lp_asset_id = contract_id.asset_id(&SubAssetId::zeroed());
        let lp_token_balance = wallet.get_asset_balance(&lp_asset_id).await?;

        let call_params = CallParameters::default()
            .with_amount(lp_token_balance.try_into().unwrap())
            .with_asset_id(lp_asset_id);

        contract_methods
            .withdraw(wallet.address().into())
            .call_params(call_params)?
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .call()
            .await?;

        let base_balance = wallet.get_asset_balance(&base_asset_id).await?;
        assert_eq!(base_balance, deposit_amount as u128);
```


---

### File: docs/fuels-rs/docs/src/cookbook/index.md

# Cookbook

This section covers more advanced use cases that can be satisfied by combining various features of the Rust SDK. As such, it assumes that you have already made yourself familiar with the previous chapters of this book.

> **Note** This section is still a work in progress and more recipes may be added in the future.


---

### File: docs/fuels-rs/docs/src/cookbook/transfer-all-assets.md

# Transfer all assets

The `transfer()` method lets you transfer a single asset, but what if you needed to move all of your assets to a different wallet? You could repeatably call `transfer()`, initiating a transaction each time, or you bundle all the transfers into a single transaction. This chapter guides you through crafting your custom transaction for transferring all assets owned by a wallet.

Lets quickly go over the setup:

```rust,ignore
        let wallet_1_signer = PrivateKeySigner::random(&mut thread_rng());

        const NUM_ASSETS: u64 = 5;
        const AMOUNT: u64 = 100_000;
        const NUM_COINS: u64 = 1;
        let (coins, _) =
            setup_multiple_assets_coins(wallet_1_signer.address(), NUM_ASSETS, NUM_COINS, AMOUNT);

        let provider = setup_test_provider(coins, vec![], None, None).await?;

        let wallet_1 = Wallet::new(wallet_1_signer, provider.clone());
        let wallet_2 = Wallet::random(&mut thread_rng(), provider.clone());
```

We prepare two wallets with randomized addresses. Next, we want one of our wallets to have some random assets, so we set them up with `setup_multiple_assets_coins()`.

Transactions require us to define input and output coins. Let's assume we do not know the assets owned by `wallet_1`. We retrieve its balances, i.e. tuples consisting of a string representing the asset ID and the respective amount. This lets us use the helpers `get_asset_inputs_for_amount()`, `get_asset_outputs_for_amount()` to create the appropriate inputs and outputs.

We transfer only a part of the base asset balance so that the rest can cover transaction fees:

```rust,ignore
        let balances = wallet_1.get_balances().await?;

        let consensus_parameters = provider.consensus_parameters().await?;
        let mut inputs = vec![];
        let mut outputs = vec![];
        for (id_string, amount) in balances {
            let id = AssetId::from_str(&id_string)?;

            let input = wallet_1
                .get_asset_inputs_for_amount(id, amount, None)
                .await?;
            inputs.extend(input);

            // we don't transfer the full base asset so we can cover fees
            let output = if id == *consensus_parameters.base_asset_id() {
                wallet_1.get_asset_outputs_for_amount(wallet_2.address(), id, (amount / 2) as u64)
            } else {
                wallet_1.get_asset_outputs_for_amount(wallet_2.address(), id, amount as u64)
            };

            outputs.extend(output);
        }
```

All that is left is to build the transaction via `ScriptTransactionBuilder`, have `wallet_1` add a witness to it and we can send it. We confirm this by checking the number of balances present in the receiving wallet and their amount:

```rust,ignore
        let mut tb =
            ScriptTransactionBuilder::prepare_transfer(inputs, outputs, TxPolicies::default());
        wallet_1.add_witnesses(&mut tb)?;

        let tx = tb.build(&provider).await?;

        provider.send_transaction_and_await_commit(tx).await?;

        let balances = wallet_2.get_balances().await?;

        assert_eq!(balances.len(), NUM_ASSETS as usize);
        for (id, balance) in balances {
            if id == *consensus_parameters.base_asset_id().to_string() {
                assert_eq!(balance, (AMOUNT / 2) as u128);
            } else {
                assert_eq!(balance, AMOUNT as u128);
            }
        }
```


---

### File: docs/fuels-rs/docs/src/custom-transactions/custom-calls.md

# Custom contract and script calls

When preparing a contract call via `CallHandler`, the Rust SDK uses a transaction builder in the background. You can fetch this builder and customize it before submitting it to the network. After the transaction is executed successfully, you can use the corresponding `CallHandler` to generate a [call response](../calling-contracts/call-response.md). The call response can be used to decode return values and logs. Below are examples for both contract and script calls.

## Custom contract call

```rust,ignore
        let call_handler = contract_instance.methods().initialize_counter(counter);

        let mut tb = call_handler.transaction_builder().await?;

        // customize the builder...

        wallet.adjust_for_fee(&mut tb, 0).await?;
        wallet.add_witnesses(&mut tb)?;

        let tx = tb.build(provider).await?;

        let tx_id = provider.send_transaction(tx).await?;
        tokio::time::sleep(Duration::from_millis(500)).await;

        let tx_status = provider.tx_status(&tx_id).await?;

        let response = call_handler.get_response(tx_status)?;

        assert_eq!(counter, response.value);
```

## Custom script call

```rust,ignore
    let script_call_handler = script_instance.main(1, 2);

    let mut tb = script_call_handler.transaction_builder().await?;

    // customize the builder...

    wallet.adjust_for_fee(&mut tb, 0).await?;
    wallet.add_witnesses(&mut tb)?;

    let tx = tb.build(provider).await?;

    let tx_id = provider.send_transaction(tx).await?;
    tokio::time::sleep(Duration::from_millis(500)).await;
    let tx_status = provider.tx_status(&tx_id).await?;

    let response = script_call_handler.get_response(tx_status)?;

    assert_eq!(response.value, "hello");
```


---

### File: docs/fuels-rs/docs/src/custom-transactions/index.md

# Custom transactions

Until now, we have used helpers to create transactions, send them with a provider, and parse the results. However, sometimes we must make custom transactions with specific inputs, outputs, witnesses, etc. In the next chapter, we will show how to use the Rust SDKs transaction builders to accomplish this.


---

### File: docs/fuels-rs/docs/src/custom-transactions/transaction-builders.md

# Transaction Builders

The Rust SDK simplifies the creation of **Create** and **Script** transactions through two handy builder structs `CreateTransactionBuilder`, `ScriptTransactionBuilder`, and the `TransactionBuilder` trait.

Calling `build(&provider)` on a builder will result in the corresponding `CreateTransaction` or `ScriptTransaction` that can be submitted to the network.

## Role of the transaction builders

> **Note** This section contains additional information about the inner workings of the builders. If you are just interested in how to use them, you can skip to the next section.

The builders take on the heavy lifting behind the scenes, offering two standout advantages: handling predicate data offsets and managing witness indexing.

When your transaction involves predicates with dynamic data as inputs, like vectors, the dynamic data contains a pointer pointing to the beginning of the raw data. This pointer's validity hinges on the order of transaction inputs, and any shifting could render it invalid. However, the transaction builders conveniently postpone the resolution of these pointers until you finalize the build process.

Similarly, adding signatures for signed coins requires the signed coin input to hold an index corresponding to the signature in the witnesses array. These indexes can also become invalid if the witness order changes. The Rust SDK again defers the resolution of these indexes until the transaction is finalized. It handles the assignment of correct index witnesses behind the scenes, sparing you the hassle of dealing with indexing intricacies during input definition.

Another added benefit of the builder pattern is that it guards against changes once the transaction is finalized. The transactions resulting from a builder don't permit any changes to the struct that could cause the transaction ID to be modified. This eliminates the headache of calculating and storing a transaction ID for future use, only to accidentally modify the transaction later, resulting in a different transaction ID.

## Creating a custom transaction

Here is an example outlining some of the features of the transaction builders.

In this scenario, we have a predicate that holds some bridged asset with ID **bridged_asset_id**. It releases it's locked assets if the transaction sends **ask_amount** of the base asset to the **receiver** address:

```rust,ignore
        let ask_amount = 100;
        let locked_amount = 500;
        let bridged_asset_id = AssetId::from([1u8; 32]);
        let receiver =
            Address::from_str("09c0b2d1a486c439a87bcba6b46a7a1a23f3897cc83a94521a96da5c23bc58db")?;
```

Our goal is to create a transaction that will use our hot wallet to transfer the **ask_amount** to the **receiver** and then send the unlocked predicate assets to a second wallet that acts as our cold storage.

Let's start by instantiating a builder. Since we don't plan to deploy a contract, the `ScriptTransactionBuilder` is the appropriate choice:

```rust,ignore
        let ask_amount = 100;
        let locked_amount = 500;
        let bridged_asset_id = AssetId::from([1u8; 32]);
        let receiver =
            Address::from_str("09c0b2d1a486c439a87bcba6b46a7a1a23f3897cc83a94521a96da5c23bc58db")?;
        let tb = ScriptTransactionBuilder::default();
        let consensus_parameters = provider.consensus_parameters().await?;
        let base_inputs = hot_wallet
            .get_asset_inputs_for_amount(*consensus_parameters.base_asset_id(), ask_amount, None)
            .await?;
        let base_outputs = hot_wallet.get_asset_outputs_for_amount(
            receiver,
            *consensus_parameters.base_asset_id(),
            ask_amount as u64,
        );
        let other_asset_inputs = predicate
            .get_asset_inputs_for_amount(bridged_asset_id, locked_amount, None)
            .await?;
        let other_asset_outputs =
            predicate.get_asset_outputs_for_amount(cold_wallet.address(), bridged_asset_id, 500);
        let inputs = base_inputs
            .into_iter()
            .chain(other_asset_inputs.into_iter())
            .collect();
        let outputs = base_outputs
            .into_iter()
            .chain(other_asset_outputs.into_iter())
            .collect();

        let mut tb = tb.with_inputs(inputs).with_outputs(outputs);
        tb.add_signer(hot_wallet.signer().clone())?;
        hot_wallet.adjust_for_fee(&mut tb, 100).await?;
        let tx_policies = TxPolicies::default().with_maturity(64).with_expiration(128);
        let tb = tb.with_tx_policies(tx_policies);
        let tx = tb.build(&provider).await?;
        let tx_id = provider.send_transaction(tx).await?;
        let status = provider.tx_status(&tx_id).await?;
        assert!(matches!(status, TxStatus::Success { .. }));

        let balance: u128 = cold_wallet.get_asset_balance(&bridged_asset_id).await?;
        assert_eq!(balance, locked_amount);
```

Next, we need to define transaction inputs of the base asset that sum up to **ask_amount**. We also need transaction outputs that will assign those assets to the predicate address and thereby unlock it. The methods `get_asset_inputs_for_amount` and `get_asset_outputs_for_amount` can help with that. We need to specify the asset ID, the target amount, and the target address:

```rust,ignore
        let consensus_parameters = provider.consensus_parameters().await?;
        let base_inputs = hot_wallet
            .get_asset_inputs_for_amount(*consensus_parameters.base_asset_id(), ask_amount, None)
            .await?;
        let base_outputs = hot_wallet.get_asset_outputs_for_amount(
            receiver,
            *consensus_parameters.base_asset_id(),
            ask_amount as u64,
        );
```

Let's repeat the same process but this time for transferring the assets held by the predicate to our cold storage:

```rust,ignore
        let other_asset_inputs = predicate
            .get_asset_inputs_for_amount(bridged_asset_id, locked_amount, None)
            .await?;
        let other_asset_outputs =
            predicate.get_asset_outputs_for_amount(cold_wallet.address(), bridged_asset_id, 500);
```

We combine all of the inputs and outputs and set them on the builder:

```rust,ignore
        let consensus_parameters = provider.consensus_parameters().await?;
        let base_inputs = hot_wallet
            .get_asset_inputs_for_amount(*consensus_parameters.base_asset_id(), ask_amount, None)
            .await?;
        let base_outputs = hot_wallet.get_asset_outputs_for_amount(
            receiver,
            *consensus_parameters.base_asset_id(),
            ask_amount as u64,
        );
        let other_asset_inputs = predicate
            .get_asset_inputs_for_amount(bridged_asset_id, locked_amount, None)
            .await?;
        let other_asset_outputs =
            predicate.get_asset_outputs_for_amount(cold_wallet.address(), bridged_asset_id, 500);
        let inputs = base_inputs
            .into_iter()
            .chain(other_asset_inputs.into_iter())
            .collect();
        let outputs = base_outputs
            .into_iter()
            .chain(other_asset_outputs.into_iter())
            .collect();

        let mut tb = tb.with_inputs(inputs).with_outputs(outputs);
```

As we have used coins that require a signature, we have to add the signer to the transaction builder with:

```rust,ignore
        tb.add_signer(hot_wallet.signer().clone())?;
```

> **Note** The signature is not created until the transaction is finalized with `build(&provider)`

We need to do one more thing before we stop thinking about transaction inputs. Executing the transaction also incurs a fee that is paid with the base asset. Our base asset inputs need to be large enough so that the total amount covers the transaction fee and any other operations we are doing. The `ViewOnlyAccount` trait lets us use `adjust_for_fee()` for adjusting the transaction inputs if needed to cover the fee. The second argument to `adjust_for_fee()` is the total amount of the base asset that we expect our transaction to spend regardless of fees. In our case, this is the **ask_amount** we are transferring to the predicate.

```rust,ignore
        hot_wallet.adjust_for_fee(&mut tb, 100).await?;
```

> **Note** It is recommended to add signers before calling `adjust_for_fee()` as the estimation will include the size of the witnesses.

We can also define transaction policies. For example, we can set the maturity and expiration with:

```rust,ignore
        let tx_policies = TxPolicies::default().with_maturity(64).with_expiration(128);
        let tb = tb.with_tx_policies(tx_policies);
```

Our builder needs a signature from the hot wallet to unlock its coins before we call `build()` and submit the resulting transaction through the provider:

```rust,ignore
        let tx = tb.build(&provider).await?;
        let tx_id = provider.send_transaction(tx).await?;
```

Finally, we verify the transaction succeeded and that the cold storage indeed holds the bridged asset now:

```rust,ignore
        let status = provider.tx_status(&tx_id).await?;
        assert!(matches!(status, TxStatus::Success { .. }));

        let balance: u128 = cold_wallet.get_asset_balance(&bridged_asset_id).await?;
        assert_eq!(balance, locked_amount);
```

## Building a transaction without signatures

If you need to build the transaction without signatures, which is useful when estimating transaction costs or simulations, you can change the build strategy used:

```rust,ignore
    let mut tx = tb
        .with_build_strategy(ScriptBuildStrategy::NoSignatures)
        .build(provider)
        .await?;
    // ANCHOR: tx_sign_with
    tx.sign_with(wallet.signer(), consensus_parameters.chain_id())
        .await?;
    // ANCHOR_END: tx_sign_with
```

> **Note** In contrast to adding signers to a transaction builder, when signing a built transaction, you must ensure that the order of signatures matches the order of signed inputs. Multiple signed inputs with the same owner will have the same witness index.


---

### File: docs/fuels-rs/docs/src/debugging/decoding-script-transactions.md

# Decoding script transactions

The SDK offers some tools that can help you make fuel script transactions more
human readable. You can determine whether the script transaction is:

* calling a contract method(s),
* is a loader script and you can see the blob id
* is neither of the above

In the case of contract call(s), if you have the ABI file, you can also decode
the arguments to the function by making use of the `AbiFormatter`:

```rust,ignore
        let TransactionType::Script(tx) = provider
            .get_transaction_by_id(&tx_id)
            .await?
            .unwrap()
            .transaction
        else {
            panic!("Transaction is not a script transaction");
        };

        let ScriptType::ContractCall(calls) = ScriptType::detect(tx.script(), tx.script_data())?
        else {
            panic!("Script is not a contract call");
        };

        let json_abi = std::fs::read_to_string(
            "../../e2e/sway/contracts/contract_test/out/release/contract_test-abi.json",
        )?;
        let abi_formatter = ABIFormatter::from_json_abi(json_abi)?;

        let call = &calls[0];
        let fn_selector = call.decode_fn_selector()?;
        let decoded_args =
            abi_formatter.decode_fn_args(&fn_selector, call.encoded_args.as_slice())?;

        eprintln!(
            "The script called: {fn_selector}({})",
            decoded_args.join(", ")
        );

```

prints:

```text
The script called: initialize_counter(42)
```

The `AbiFormatter` can also decode configurables, refer to the rust docs for
more information.


---

### File: docs/fuels-rs/docs/src/debugging/function-selector.md

# Function selector

Whenever you call a contract method the SDK will generate a function selector according to the fuel specs which will be
used by the node to identify which method we wish to execute.

If, for whatever reason, you wish to generate the function selector yourself you can do so:

```rust,ignore
        // fn some_fn_name(arg1: Vec<str[3]>, arg2: u8)
        let fn_name = "some_fn_name";

        let selector = encode_fn_selector(fn_name);

        assert_eq!(
            selector,
            [
                0, 0, 0, 0, 0, 0, 0, 12, 115, 111, 109, 101, 95, 102, 110, 95, 110, 97, 109, 101
            ]
        );
```


---

### File: docs/fuels-rs/docs/src/debugging/index.md

# Debugging

> **note** This section is still a work in progress.

- [The Function Selector](./function-selector.md)


---

### File: docs/fuels-rs/docs/src/deploying/configurable-constants.md

# Configurable constants

In Sway, you can define `configurable` constants which can be changed during the contract deployment in the SDK. Here is an example how the constants are defined.

```rust,ignore
contract;

#[allow(dead_code)]
enum EnumWithGeneric<D> {
    VariantOne: D,
    VariantTwo: (),
}

struct StructWithGeneric<D> {
    field_1: D,
    field_2: u64,
}

configurable {
    BOOL: bool = true,
    U8: u8 = 8,
    U16: u16 = 16,
    U32: u32 = 32,
    U64: u64 = 63,
    U256: u256 = 0x0000000000000000000000000000000000000000000000000000000000000008u256,
    B256: b256 = 0x0101010101010101010101010101010101010101010101010101010101010101,
    STR_4: str[4] = __to_str_array("fuel"),
    TUPLE: (u8, bool) = (8, true),
    ARRAY: [u32; 3] = [253, 254, 255],
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}
//U128: u128 = 128, //TODO: add once https://github.com/FuelLabs/sway/issues/5356 is done

abi TestContract {
    fn return_configurables() -> (bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric<u8>, EnumWithGeneric<bool>);
}

impl TestContract for Contract {
    fn return_configurables() -> (bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric<u8>, EnumWithGeneric<bool>) {
        (BOOL, U8, U16, U32, U64, U256, B256, STR_4, TUPLE, ARRAY, STRUCT, ENUM)
    }
}

```

Each of the configurable constants will get a dedicated `with` method in the SDK. For example, the constant `STR_4` will get the `with_STR_4` method which accepts the same type as defined in the contract code. Below is an example where we chain several `with` methods and deploy the contract with the new constants.

```rust,ignore
    abigen!(Contract(
        name = "MyContract",
        abi = "e2e/sway/contracts/configurables/out/release/configurables-abi.json"
    ));

    let wallet = launch_provider_and_get_wallet().await?;

    let str_4: SizedAsciiString<4> = "FUEL".try_into()?;
    let new_struct = StructWithGeneric {
        field_1: 16u8,
        field_2: 32,
    };
    let new_enum = EnumWithGeneric::VariantTwo;

    let configurables = MyContractConfigurables::default()
        .with_BOOL(false)?
        .with_U8(7)?
        .with_U16(15)?
        .with_U32(31)?
        .with_U64(63)?
        .with_U256(U256::from(8))?
        .with_B256(Bits256([2; 32]))?
        .with_STR_4(str_4.clone())?
        .with_TUPLE((7, false))?
        .with_ARRAY([252, 253, 254])?
        .with_STRUCT(new_struct.clone())?
        .with_ENUM(new_enum.clone())?;

    let contract_id = Contract::load_from(
        "sway/contracts/configurables/out/release/configurables.bin",
        LoadConfiguration::default().with_configurables(configurables),
    )?
    .deploy_if_not_exists(&wallet, TxPolicies::default())
    .await?
    .contract_id;

    let contract_instance = MyContract::new(contract_id, wallet.clone());
```


---

### File: docs/fuels-rs/docs/src/deploying/index.md

# Deploying contracts

There are two main ways of working with contracts in the SDK: deploying a contract with SDK or using the SDK to interact with existing contracts.

## Deploying a contract binary

<!-- This section should explain the artifacts produced by `forc build`  -->
<!-- build:example:start -->
Once you've written a contract in Sway and compiled it with `forc build`, you'll have in your hands two important artifacts: the compiled binary file and the JSON ABI file.
<!-- build:example:end -->
> Note: Read [here](https://docs.fuel.network/guides/quickstart/) for more on how to work with Sway.

Below is how you can deploy your contracts using the SDK. For more details about each component in this process, read [The abigen macro](../abigen/the-abigen-macro.md), [The FuelVM binary file](./the-fuelvm-binary-file.md), and [The JSON ABI file](../abigen/the-json-abi-file.md).

<!-- This section should explain how to load and deploy a contract  -->
<!-- deploy:example:start -->
First, the `Contract::load_from` function is used to load a contract binary with a `LoadConfiguration`. If you are only interested in a single instance of your contract, use the default configuration: `LoadConfiguration::default()`. After the contract binary is loaded, you can use the `deploy()` method to deploy the contract to the blockchain.
<!-- deploy:example:end -->

```rust,ignore
        // This helper will launch a local node and provide a test wallet linked to it
        let wallet = launch_provider_and_get_wallet().await?;

        // This will load and deploy your contract binary to the chain so that its ID can
        // be used to initialize the instance
        let contract_id = Contract::load_from(
            "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin",
            LoadConfiguration::default(),
        )?
        .deploy(&wallet, TxPolicies::default())
        .await?
        .contract_id;

        println!("Contract deployed @ {contract_id}");
        setup_program_test!(
            Wallets("wallet"),
            Abigen(Contract(
                name = "TestContract",
                project = "e2e/sway/contracts/contract_test"
            )),
            Deploy(
                name = "contract_instance",
                contract = "TestContract",
                wallet = "wallet"
            ),
        );

        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .call()
            .await?;

        assert_eq!(42, response.value);
```

Alternatively, you can use `LoadConfiguration` to configure how the contract is loaded. `LoadConfiguration` let's you:

- Load the same contract binary with `Salt` to get a new `contract_id`
- Change the contract's storage slots
- Update the contract's configurables

> Note: The next section will give more information on how `configurables` can be used.

Additionally, you can set custom `TxParameters` when deploying the loaded contract.

```rust,ignore
        // Optional: Add `Salt`
        let rng = &mut StdRng::seed_from_u64(2322u64);
        let salt: [u8; 32] = rng.r#gen();

        // Optional: Configure storage
        let key = Bytes32::from([1u8; 32]);
        let value = Bytes32::from([2u8; 32]);
        let storage_slot = StorageSlot::new(key, value);
        let storage_configuration =
            StorageConfiguration::default().add_slot_overrides([storage_slot]);
        let configuration = LoadConfiguration::default()
            .with_storage_configuration(storage_configuration)
            .with_salt(salt);

        // Optional: Configure deployment parameters
        let tx_policies = TxPolicies::default()
            .with_tip(1)
            .with_script_gas_limit(1_000_000)
            .with_maturity(0)
            .with_expiration(10_000);

        let contract_id_2 = Contract::load_from(
            "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin",
            configuration,
        )?
        .deploy(&wallet, tx_policies)
        .await?
        .contract_id;

        println!("Contract deployed @ {contract_id_2}");
```

After the contract is deployed, you can use the contract's methods like this:

```rust,ignore
        // This will generate your contract's methods onto `MyContract`.
        // This means an instance of `MyContract` will have access to all
        // your contract's methods that are running on-chain!
        // ANCHOR: abigen_example
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        // ANCHOR_END: abigen_example

        // This is an instance of your contract which you can use to make calls to your functions
        let contract_instance = MyContract::new(contract_id_2, wallet);

        let response = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .call() // Perform the network call
            .await?;

        assert_eq!(42, response.value);

        let response = contract_instance
            .methods()
            .increment_counter(10)
            .call()
            .await?;

        assert_eq!(52, response.value);
```

> Note: When redeploying an existing `Contract`, ensure that you initialize it with a unique salt to prevent deployment failures caused by a contract ID collision. To accomplish this, utilize the `with_salt` method to clone the existing `Contract` with a new salt.


---

### File: docs/fuels-rs/docs/src/deploying/interacting-with-contracts.md

# Interacting with contracts

If you already have a deployed contract and want to call its methods using the SDK, but without deploying it again, all you need is the contract ID of your deployed contract. You can skip the whole deployment setup and call `::new(contract_id, wallet)` directly. For example:

```rust,ignore
        abigen!(Contract(
            name = "MyContract",
            // Replace with your contract ABI.json path
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        let wallet_original = launch_provider_and_get_wallet().await?;

        let wallet = wallet_original.clone();
        let contract_id: ContractId =
            "0x65b6a3d081966040bbccbb7f79ac91b48c635729c59a4c02f15ae7da999b32d3".parse()?;

        let connected_contract_instance = MyContract::new(contract_id, wallet);
```


---

### File: docs/fuels-rs/docs/src/deploying/large_contracts.md

# Deploying Large Contracts

If your contract exceeds the size limit for a single deployment:

```rust,ignore
        let contract = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?;
        let max_allowed = provider
            .consensus_parameters()
            .await?
            .contract_params()
            .contract_max_size();

        assert!(contract.code().len() as u64 > max_allowed);
```

you can deploy it in segments using a partitioned approach:

```rust,ignore
        let max_words_per_blob = 10_000;
        let contract_id = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .convert_to_loader(max_words_per_blob)?
        .deploy(&wallet, TxPolicies::default())
        .await?
        .contract_id;
```

When you convert a standard contract into a loader contract, the following changes occur:

* The original contract code is replaced with the loader contract code.
* The original contract code is split into blobs, which will be deployed via blob transactions before deploying the contract itself.
* The new loader code, when invoked, loads these blobs into memory and executes your original contract.

After deploying the loader contract, you can interact with it just as you would with a standard contract:

```rust,ignore
        let contract_instance = MyContract::new(contract_id, wallet);
        let response = contract_instance.methods().something().call().await?.value;
        assert_eq!(response, 1001);
```

A helper function is available to deploy your contract normally if it is within the size limit, or as a loader contract if it exceeds the limit:

```rust,ignore
        let max_words_per_blob = 10_000;
        let contract_id = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .smart_deploy(&wallet, TxPolicies::default(), max_words_per_blob)
        .await?
        .contract_id;
```

You also have the option to separate the blob upload from the contract deployment for more granular control:

```rust,ignore
        let contract_id = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .convert_to_loader(max_words_per_blob)?
        .upload_blobs(&wallet, TxPolicies::default())
        .await?
        .deploy(&wallet, TxPolicies::default())
        .await?
        .contract_id;
```

Alternatively, you can manually split your contract code into blobs and then create and deploy a loader:

```rust,ignore
        let chunk_size = 100_000;
        assert!(
            chunk_size % 8 == 0,
            "all chunks, except the last, must be word-aligned"
        );
        let blobs = contract
            .code()
            .chunks(chunk_size)
            .map(|chunk| Blob::new(chunk.to_vec()))
            .collect();

        let contract_id = Contract::loader_from_blobs(blobs, random_salt(), vec![])?
            .deploy(&wallet, TxPolicies::default())
            .await?
            .contract_id;
```

Or you can upload the blobs yourself and proceed with just the loader deployment:

```rust,ignore
        let max_words_per_blob = 10_000;
        let blobs = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .convert_to_loader(max_words_per_blob)?
        .blobs()
        .to_vec();

        let mut all_blob_ids = vec![];
        let mut already_uploaded_blobs = HashSet::new();
        for blob in blobs {
            let blob_id = blob.id();
            all_blob_ids.push(blob_id);

            // uploading the same blob twice is not allowed
            if already_uploaded_blobs.contains(&blob_id) {
                continue;
            }

            let mut tb = BlobTransactionBuilder::default().with_blob(blob);
            wallet.adjust_for_fee(&mut tb, 0).await?;
            wallet.add_witnesses(&mut tb)?;

            let tx = tb.build(&provider).await?;
            provider
                .send_transaction_and_await_commit(tx)
                .await?
                .check(None)?;

            already_uploaded_blobs.insert(blob_id);
        }

        let contract_id = Contract::loader_from_blob_ids(all_blob_ids, random_salt(), vec![])?
            .deploy(&wallet, TxPolicies::default())
            .await?
            .contract_id;
```

## Blob Size Considerations

The size of a Blob transaction is constrained by three factors:

<!--Needed to disable lints because the multiline ordered list is messing with the linter. It keeps suggesting that each item is a start of a new list.-->
<!-- markdownlint-disable -->
1. The maximum size of a single transaction:

```rust,ignore
        provider
            .consensus_parameters()
            .await?
            .tx_params()
            .max_size();
```

2. The maximum gas usage for a single transaction:

```rust,ignore
        provider
            .consensus_parameters()
            .await?
            .tx_params()
            .max_gas_per_tx();
```

3. The maximum HTTP body size accepted by the Fuel node.

To estimate an appropriate size for your blobs, you can run:

```rust,ignore
        let max_blob_size = BlobTransactionBuilder::default()
            .estimate_max_blob_size(&provider)
            .await?;
```
<!-- markdownlint-restore -->

However, keep in mind the following limitations:

* The estimation only considers the maximum transaction size, not the max gas usage or HTTP body limit.
* It does not account for any size increase that may occur after the transaction is funded.

Therefore, it is advisable to make your blobs a few percent smaller than the estimated maximum size.


---

### File: docs/fuels-rs/docs/src/deploying/storage-slots.md

# Overriding storage slots

If you use storage in your contract, the default storage values will be generated in a JSON file (e.g. `my_contract-storage_slots.json`) by the Sway compiler. These are loaded automatically for you when you load a contract binary. If you wish to override some of the defaults, you need to provide the corresponding storage slots manually:

```rust,ignore
            use fuels::{programs::contract::Contract, tx::StorageSlot};
            let slot_override = StorageSlot::new([1; 32].into(), [2; 32].into());
            let storage_config =
                StorageConfiguration::default().add_slot_overrides([slot_override]);

            let load_config =
                LoadConfiguration::default().with_storage_configuration(storage_config);
            let _: Result<_> = Contract::load_from("...", load_config);
```

If you don't have the slot storage file (`my_contract-storage_slots.json` example from above) for some reason, or you don't wish to load any of the default values, you can disable the auto-loading of storage slots:

```rust,ignore
            use fuels::programs::contract::Contract;
            let storage_config = StorageConfiguration::default().with_autoload(false);

            let load_config =
                LoadConfiguration::default().with_storage_configuration(storage_config);
            let _: Result<_> = Contract::load_from("...", load_config);
```


---

### File: docs/fuels-rs/docs/src/deploying/the-fuelvm-binary-file.md

# The FuelVM binary file

The command `forc build` compiles your Sway code and generates the bytecode: the binary code that the Fuel Virtual Machine will interpret. For instance, the smart contract below:

```Rust
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

After `forc build`, will have a binary file that contains:

```terminal
$ cat out/release/my-test.bin
G4]�]D`I]C�As@
           6]C�$@!QK%
```

This seems very unreadable! But, `forc` has a nice interpreter for this bytecode: `forc parse-bytecode`, which will interpret that binary data and output the equivalent FuelVM assembly:

```terminal
$ forc parse-bytecode out/release/my-test.bin
half-word   byte   op                raw           notes
        0   0      JI(4)             90 00 00 04   jump to byte 16
        1   4      NOOP              47 00 00 00
        2   8      Undefined         00 00 00 00   data section offset lo (0)
        3   12     Undefined         00 00 00 34   data section offset hi (52)
        4   16     LW(63, 12, 1)     5d fc c0 01
        5   20     ADD(63, 63, 12)   10 ff f3 00
        6   24     LW(17, 6, 73)     5d 44 60 49
        7   28     LW(16, 63, 1)     5d 43 f0 01
        8   32     EQ(16, 17, 16)    13 41 14 00
        9   36     JNZI(16, 11)      73 40 00 0b   conditionally jump to byte 44
       10   40     RVRT(0)           36 00 00 00
       11   44     LW(16, 63, 0)     5d 43 f0 00
       12   48     RET(16)           24 40 00 00
       13   52     Undefined         00 00 00 00
       14   56     Undefined         00 00 00 01
       15   60     Undefined         00 00 00 00
       16   64     XOR(20, 27, 53)   21 51 bd 4b
```

If you want to deploy your smart contract using the SDK, this binary file is important; it's what we'll be sending to the FuelVM in a transaction.


---

### File: docs/fuels-rs/docs/src/getting-started.md

# Getting Started

## Installation Guide

Please visit the Fuel [installation guide](https://docs.fuel.network/guides/installation) to install the Fuel toolchain binaries and prerequisites.

`forc` is Sway equivalent of Rust's `cargo`. `fuel-core` is a Fuel full node implementation.

There are two main ways you can use the Fuel Rust SDK:

1. Creating a new Sway project with `forc` and running the tests
2. Creating a standalone project and importing the `fuels-rs` crate

## Creating a new project with Forc

You can create a new Sway project with

```shell
forc new <Project name>
```

Or you can initialize a project within an existing folder with

```shell
forc init
```

### Adding a Rust integration test to the Sway project

Now that we have a new project, we can add a Rust integration test using a `cargo generate` template.
If `cargo generate` is not already installed, you can install it with:

<!-- This section should have the command to install cargo generate -->
<!-- cargo_gen_install:example:start -->
```shell
cargo install cargo-generate
```
<!-- cargo_gen_install:example:end -->

> **Note** You can learn more about cargo generate by visiting its [repository](https://github.com/cargo-generate/cargo-generate).

Let's generate the default test harness with the following command:

<!-- This section should have the command to cargo generate a test harness -->
<!-- cargo_gen:example:start -->
```shell
cargo generate --init fuellabs/sway templates/sway-test-rs --name <Project name> --force
```
<!-- cargo_gen:example:end -->

<!-- This section should explain the `--force` flag -->
<!-- force_flag:example:start -->
`--force` forces your `--name` input to retain your desired casing for the `{{project-name}}` placeholder in the template. Otherwise, `cargo-generate` automatically converts it to kebab-case. With `--force`, this means that both `my_fuel_project` and `my-fuel-project` are valid project names, depending on your needs.
<!-- force_flag:example:end -->

Before running test, we need to build the Sway project with:

```shell
forc build
```

Afterwards, we can run the test with:

<!-- This section should have the command to run a test -->
<!-- run_test:example:start -->
```shell
cargo test
```
<!-- run_test:example:end -->

> **Note** If you need to capture output from the tests, use one of the following commands:

<!-- This section should have the command to run a test with no capture -->
<!-- run_test_nocap:example:start -->
```shell
cargo test -- --nocapture
```
<!-- run_test_nocap:example:end -->

## Importing the Fuel Rust SDK

Add these dependencies on your `Cargo.toml`:

```toml
fuels = "0.66.0"
```

> **Note** We're using version `0.66.0` of the SDK, which is the latest version at the time of this writing.

And then, in your Rust file that's going to make use of the SDK:

```rust,ignore
use fuels::prelude::*;
```

## The Fuel Rust SDK source code

Another way to experience the SDK is to look at the source code. The `e2e/tests/` folder is full of integration tests that go through almost all aspects of the SDK.

> **Note** Before running the tests, we need to build all the Sway test projects. The file `packages/fuels/Forc.toml` contains a `[workspace], which members are the paths to all integration tests.
> To build these tests, run the following command:

```shell
forc build --release --path e2e
```

> `forc` can also be used to clean and format the test projects. Check the `help` output for more info.

After building the projects, we can run the tests with

```shell
cargo test
```

If you need all targets and all features, you can run

```shell
cargo test --all-targets --all-features
```

> **Note** If you need to capture output from the tests, you can run

```shell
cargo test -- --nocapture
```

## More in-depth Fuel and Sway knowledge

Read [The Sway Book](https://docs.fuel.network/docs/sway/) for more in-depth knowledge about Sway, the official smart contract language for the Fuel Virtual Machine.


---

### File: docs/fuels-rs/docs/src/glossary.md

# Glossary

## Contract

<!-- This section should define a contract -->
<!-- rs_contract:example:start -->

A contract, in the SDK, is an abstraction that represents a connection to a specific smart contract deployed on the Fuel Network. This contract instance can be used as a regular Rust object, with methods attached to it that reflect those in its smart contract equivalent.

<!-- rs_contract:example:end -->

## Provider

<!-- This section should define a provider -->
<!-- rs_provider:example:start -->

A Provider is a struct that provides an abstraction for a connection to a Fuel node. It provides read-only access to the node. You can use this provider as-is or through the wallet.

<!-- rs_provider:example:end -->


---

### File: docs/fuels-rs/docs/src/index.md

# The Fuel Rust SDK

<!-- This section should explain what the Fuel Rust SDK can be used for -->
<!-- fuels_rs:example:start -->
The Fuel Rust SDK can be used for a variety of things, including:

- Compiling, deploying, and testing [Sway](https://github.com/FuelLabs/sway) contracts
- Using the testnet or running a local Fuel node
- Crafting and signing transactions with hand-crafted scripts or contract calls
- Generating type-safe Rust bindings of contract ABI methods
<!-- fuels_rs:example:end -->

This book is an overview of the different things one can achieve using the Rust SDK, and how to implement them. Keep in mind that both the SDK and the documentation are works-in-progress!


---

### File: docs/fuels-rs/docs/src/predicates/index.md

# Predicates

Predicates, in Sway, are programs that return a Boolean value and do not have any side effects (they are pure). A predicate address can own assets. The predicate address is generated from the compiled byte code and is the same as the `P2SH` address used in Bitcoin. Users can seamlessly send assets to the predicate address as they do for any other address. To spend the predicate funds, the user has to provide the original `byte code` of the predicate together with the `predicate data`. The `predicate data` will be used when executing the `byte code`, and the funds can be transferred if the predicate is validated successfully.

## Instantiating predicates

Let's consider the following predicate example:

```rust,ignore
predicate;

fn main(a: u32, b: u64) -> bool {
    b == a.as_u64()
}

```

We will look at a complete example of using the SDK to send and receive funds from a predicate.

First, we set up the wallets and a node instance. The call to the `abigen!` macro will generate all the types specified in the predicate plus two custom structs:

- an encoder with an `encode_data`  function that will conveniently encode all the arguments of the main function for us.
- a configurables struct which holds methods for setting all the configurables mentioned in the predicate

> Note: The `abigen!` macro will append `Encoder` and `Configurables` to the predicate's `name` field. Fox example, `name="MyPredicate"` will result in two structs called `MyPredicateEncoder` and `MyPredicateConfigurables`.

```rust,ignore
        let asset_id = AssetId::zeroed();
        let wallets_config = WalletsConfig::new_multiple_assets(
            2,
            vec![AssetConfig {
                id: asset_id,
                num_coins: 1,
                coin_amount: 1_000,
            }],
        );

        let wallets = &launch_custom_provider_and_get_wallets(wallets_config, None, None).await?;

        let first_wallet = &wallets[0];
        let second_wallet = &wallets[1];

        abigen!(Predicate(
            name = "MyPredicate",
            abi = "e2e/sway/predicates/basic_predicate/out/release/basic_predicate-abi.json"
        ));
```

Once we've compiled our predicate with `forc build`, we can create a `Predicate` instance via `Predicate::load_from`. The resulting data from `encode_data` can then be set on the loaded predicate.

```rust,ignore
        let predicate_data = MyPredicateEncoder::default().encode_data(4096, 4096)?;
        let code_path = "../../e2e/sway/predicates/basic_predicate/out/release/basic_predicate.bin";

        let predicate: Predicate = Predicate::load_from(code_path)?
            .with_provider(first_wallet.provider().clone())
            .with_data(predicate_data);
```

Next, we lock some assets in this predicate using the first wallet:

```rust,ignore
        // First wallet transfers amount to predicate.
        first_wallet
            .transfer(predicate.address(), 500, asset_id, TxPolicies::default())
            .await?;

        // Check predicate balance.
        let balance = predicate.get_asset_balance(&AssetId::zeroed()).await?;

        assert_eq!(balance, 500);
```

Then we can transfer assets owned by the predicate via the [Account](../accounts.md) trait:

```rust,ignore
        let amount_to_unlock = 300;

        predicate
            .transfer(
                second_wallet.address(),
                amount_to_unlock,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        // Second wallet balance is updated.
        let balance = second_wallet.get_asset_balance(&AssetId::zeroed()).await?;
        assert_eq!(balance, 1300);
```

## Configurable constants

Same as contracts and scripts, you can define configurable constants in `predicates`, which can be changed during the predicate execution. Here is an example of how the constants are defined.

```rust,ignore
#[allow(dead_code)]
enum EnumWithGeneric<D> {
    VariantOne: D,
    VariantTwo: (),
}

struct StructWithGeneric<D> {
    field_1: D,
    field_2: u64,
}

configurable {
    BOOL: bool = true,
    U8: u8 = 8,
    TUPLE: (u8, bool) = (8, true),
    ARRAY: [u32; 3] = [253, 254, 255],
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}

fn main(
    switch: bool,
    u_8: u8,
    some_tuple: (u8, bool),
    some_array: [u32; 3],
    some_struct: StructWithGeneric<u8>,
    some_enum: EnumWithGeneric<bool>,
) -> bool {
    switch == BOOL && u_8 == U8 && some_tuple.0 == TUPLE.0 && some_tuple.1 == TUPLE.1 && some_array[0] == ARRAY[0] && some_array[1] == ARRAY[1] && some_array[2] == ARRAY[2] && some_struct == STRUCT && some_enum == ENUM
}
```

Each configurable constant will get a dedicated `with` method in the SDK. For example, the constant `U8` will get the `with_U8` method which accepts the same type defined in sway. Below is an example where we chain several `with` methods and update the predicate with the new constants.

```rust,ignore
    abigen!(Predicate(
        name = "MyPredicate",
        abi = "e2e/sway/predicates/predicate_configurables/out/release/predicate_configurables-abi.json"
    ));

    let new_tuple = (16, false);
    let new_array = [123, 124, 125];
    let new_struct = StructWithGeneric {
        field_1: 32u8,
        field_2: 64,
    };
    let new_enum = EnumWithGeneric::VariantTwo;

    let configurables = MyPredicateConfigurables::default()
        .with_U8(8)?
        .with_TUPLE(new_tuple)?
        .with_ARRAY(new_array)?
        .with_STRUCT(new_struct.clone())?
        .with_ENUM(new_enum.clone())?;

    let predicate_data = MyPredicateEncoder::default()
        .encode_data(true, 8u8, new_tuple, new_array, new_struct, new_enum)?;

    let mut predicate: Predicate = Predicate::load_from(
        "sway/predicates/predicate_configurables/out/release/predicate_configurables.bin",
    )?
    .with_data(predicate_data)
    .with_configurables(configurables);
```


---

### File: docs/fuels-rs/docs/src/predicates/send-spend-predicate.md

# Signatures in predicates example

This is a more involved example where the predicate accepts three signatures and matches them to three predefined public keys. The `ec_recover_address` function is used to recover the public key from the signatures. If two of the three extracted public keys match the predefined public keys, the funds can be spent. Note that the signature order has to match the order of the predefined public keys.

```rust,ignore
predicate;

use std::{
    b512::B512,
    crypto::{
        message::Message,
        secp256k1::Secp256k1,
    },
    inputs::input_predicate_data,
};

fn extract_public_key_and_match(signature: B512, expected_public_key: b256) -> u64 {
    let signature = Secp256k1::from(signature);

    if let Result::Ok(pub_key_sig) = signature.address(Message::from(b256::zero()))
    {
        if pub_key_sig == Address::from(expected_public_key) {
            return 1;
        }
    }

    0
}

fn main(signatures: [B512; 3]) -> bool {
    let public_keys = [
        0xd58573593432a30a800f97ad32f877425c223a9e427ab557aab5d5bb89156db0,
        0x14df7c7e4e662db31fe2763b1734a3d680e7b743516319a49baaa22b2032a857,
        0x3ff494fb136978c3125844625dad6baf6e87cdb1328c8a51f35bda5afe72425c,
    ];

    let mut matched_keys = 0;

    matched_keys = extract_public_key_and_match(signatures[0], public_keys[0]);
    matched_keys = matched_keys + extract_public_key_and_match(signatures[1], public_keys[1]);
    matched_keys = matched_keys + extract_public_key_and_match(signatures[2], public_keys[2]);

    matched_keys > 1
}

```

Let's use the SDK to interact with the predicate. First, let's create three signers with specific keys. Their hashed public keys are already hard-coded in the predicate. Then we create the receiver signer, which we will use to spend the predicate funds.

```rust,ignore
        let wallet_signer = PrivateKeySigner::new(
            "0x862512a2363db2b3a375c0d4bbbd27172180d89f23f2e259bac850ab02619301".parse()?,
        );
        let wallet2_signer = PrivateKeySigner::new(
            "0x37fa81c84ccd547c30c176b118d5cb892bdb113e8e80141f266519422ef9eefd".parse()?,
        );
        let wallet3_signer = PrivateKeySigner::new(
            "0x976e5c3fa620092c718d852ca703b6da9e3075b9f2ecb8ed42d9f746bf26aafb".parse()?,
        );
        let receiver_signer = PrivateKeySigner::random(&mut thread_rng());
```

Next, let's add some coins, start a provider and create the wallets.

```rust,ignore
        let asset_id = AssetId::zeroed();
        let num_coins = 32;
        let amount = 64;
        let initial_balance = amount * num_coins;
        let all_coins = [
            &wallet_signer,
            &wallet2_signer,
            &wallet3_signer,
            &receiver_signer,
        ]
        .iter()
        .flat_map(|signer| setup_single_asset_coins(signer.address(), asset_id, num_coins, amount))
        .collect::<Vec<_>>();

        let provider = setup_test_provider(all_coins, vec![], None, None).await?;

        let wallet = Wallet::new(wallet_signer, provider.clone());
        let wallet2 = Wallet::new(wallet2_signer, provider.clone());
        let wallet3 = Wallet::new(wallet3_signer, provider.clone());
        let receiver = Wallet::new(receiver_signer, provider.clone());
```

Now we can use the predicate abigen to create a predicate encoder instance for us. To spend the funds now locked in the predicate, we must provide two out of three signatures whose public keys match the ones we defined in the predicate. In this example, the signatures are generated from an array of zeros.

```rust,ignore
        abigen!(Predicate(
            name = "MyPredicate",
            abi = "e2e/sway/predicates/signatures/out/release/signatures-abi.json"
        ));

        let predicate_data = MyPredicateEncoder::default().encode_data(signatures)?;
        let code_path = "../../e2e/sway/predicates/signatures/out/release/signatures.bin";

        let predicate: Predicate = Predicate::load_from(code_path)?
            .with_provider(provider)
            .with_data(predicate_data);
```

Next, we transfer some assets from a wallet to the created predicate. We also confirm that the funds are indeed transferred.

```rust,ignore
        let amount_to_predicate = 500;

        wallet
            .transfer(
                predicate.address(),
                amount_to_predicate,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        let predicate_balance = predicate.get_asset_balance(&asset_id).await?;
        assert_eq!(predicate_balance, amount_to_predicate as u128);
```

We can use the `transfer` method from the [Account](../accounts.md) trait to transfer the assets. If the predicate data is correct, the `receiver` wallet will get the funds, and we will verify that the amount is correct.

```rust,ignore
        let amount_to_receiver = 300;
        predicate
            .transfer(
                receiver.address(),
                amount_to_receiver,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        let receiver_balance_after = receiver.get_asset_balance(&asset_id).await?;
        assert_eq!(
            (initial_balance + amount_to_receiver) as u128,
            receiver_balance_after
        );
```


---

### File: docs/fuels-rs/docs/src/preuploading-code.md

# Pre-uploading code

If you have a script or predicate that is larger than normal or which you plan
on calling often, you can pre-upload its code as a blob to the network and run a
loader script/predicate instead. The loader can be configured with the
script/predicate configurables, so you can change how the script/predicate is
configured on each run without having large transactions due to the code
duplication.

## Scripts

A high level pre-upload:

```rust,ignore
    my_script.convert_into_loader().await?.main().call().await?;
```

The upload of the blob is handled inside of the `convert_into_loader` method. If you
want more fine-grained control over it, you can create the script transaction
manually:

```rust,ignore
    let regular = Executable::load_from(binary_path)?;

    let configurables = MyScriptConfigurables::default().with_SECRET_NUMBER(10001)?;
    let loader = regular
        .convert_to_loader()?
        .with_configurables(configurables);

    // The Blob must be uploaded manually, otherwise the script code will revert.
    loader.upload_blob(wallet.clone()).await?;

    let encoder = fuels::core::codec::ABIEncoder::default();
    let token = MyStruct {
        field_a: MyEnum::B(99),
        field_b: Bits256([17; 32]),
    }
    .into_token();
    let data = encoder.encode(&[token])?;

    let mut tb = ScriptTransactionBuilder::default()
        .with_script(loader.code())
        .with_script_data(data);

    wallet.adjust_for_fee(&mut tb, 0).await?;

    wallet.add_witnesses(&mut tb)?;

    let tx = tb.build(&provider).await?;

    let response = provider.send_transaction_and_await_commit(tx).await?;

    response.check(None)?;
```

## Predicates

You can prepare a predicate for pre-uploading without doing network requests:

```rust,ignore
    let configurables = MyPredicateConfigurables::default().with_SECRET_NUMBER(10001)?;

    let predicate_data = MyPredicateEncoder::default().encode_data(1, 19)?;

    let executable =
        Executable::load_from("sway/predicates/predicate_blobs/out/release/predicate_blobs.bin")?;

    let loader = executable
        .convert_to_loader()?
        .with_configurables(configurables);

    let mut predicate: Predicate = Predicate::from_code(loader.code()).with_data(predicate_data);
```

Once you want to execute the predicate, you must beforehand upload the blob
containing its code:

```rust,ignore
    loader.upload_blob(extra_wallet).await?;
    predicate.set_provider(provider.clone());

    let amount_to_send = 42;
    let response = predicate
        .transfer(
            receiver.address(),
            amount_to_send,
            asset_id,
            TxPolicies::default(),
        )
        .await?;
```

By pre-uploading the predicate code, you allow for cheaper calls to the predicate
from subsequent callers.


---

### File: docs/fuels-rs/docs/src/reference.md

# API Reference

For a more in-depth look at the APIs provided by the Fuel Rust SDK, head over to the [official documentation](https://docs.rs/fuels/latest/fuels/). In the actual Rust docs, you can see the most up-to-date information about the API, which is synced with the code as it changes.


---

### File: docs/fuels-rs/docs/src/running-scripts.md

# Running scripts

You can run a script using its JSON-ABI and the path to its binary file. You can run the scripts with arguments. For this, you have to use the `abigen!` macro seen [previously](./abigen/the-abigen-macro.md).

```rust,ignore
    // The abigen is used for the same purpose as with contracts (Rust bindings)
    abigen!(Script(
        name = "MyScript",
        abi = "e2e/sway/scripts/arguments/out/release/arguments-abi.json"
    ));
    let wallet = launch_provider_and_get_wallet().await?;
    let bin_path = "sway/scripts/arguments/out/release/arguments.bin";
    let script_instance = MyScript::new(wallet, bin_path);

    let bim = Bimbam { val: 90 };
    let bam = SugarySnack {
        twix: 100,
        mars: 1000,
    };

    let result = script_instance.main(bim, bam).call().await?;

    let expected = Bimbam { val: 2190 };
    assert_eq!(result.value, expected);
```

Furthermore, if you need to separate submission from value retrieval for any reason, you can do so as follows:

```rust,ignore
    let submitted_tx = script_instance.main(my_struct).submit().await?;
    tokio::time::sleep(Duration::from_millis(500)).await;
    let value = submitted_tx.response().await?.value;
```

## Running scripts with transaction policies

The method for passing transaction policies is the same as [with contracts](./calling-contracts/tx-policies.md). As a reminder, the workflow would look like this:

```rust,ignore
    let tx_policies = TxPolicies::default().with_script_gas_limit(1_000_000);
    let result = script_instance
        .main(a, b)
        .with_tx_policies(tx_policies)
        .call()
        .await?;
```

## Custom inputs and outputs

If you need to add specific inputs and outputs to script calls, you can use the `with_inputs` and `with_outputs` methods.

```rust,ignore
        let _ = script_instance
            .main(0, 0)
            .with_inputs(custom_inputs)
            .with_outputs(custom_output)
            .add_signer(wallet_1.signer().clone())
            .call()
            .await?;
```

> **Note:** if custom inputs include coins that need to be signed, use the `add_signer` method to add the appropriate signer.

## Logs

Script calls provide the same logging functions, `decode_logs()` and `decode_logs_with_type<T>()`, as contract calls. As a reminder, the workflow looks like this:

```rust,ignore
    abigen!(Script(
        name = "LogScript",
        abi = "e2e/sway/logs/script_logs/out/release/script_logs-abi.json"
    ));

    let wallet = launch_provider_and_get_wallet().await?;
    let bin_path = "sway/logs/script_logs/out/release/script_logs.bin";
    let instance = LogScript::new(wallet.clone(), bin_path);

    let response = instance.main().call().await?;

    let logs = response.decode_logs();
    let log_u64 = response.decode_logs_with_type::<u64>()?;
```

## Calling contracts from scripts

Scripts use the same interfaces for setting external contracts as [contract methods](./calling-contracts/other-contracts.md).

Below is an example that uses `with_contracts(&[&contract_instance, ...])`.

```rust,ignore
    let response = script_instance
        .main(contract_id, MatchEnum::Logs)
        .with_contract_ids(&[contract_id])
        .call()
        .await?;
    let response = script_instance
        .main(contract_id, MatchEnum::Logs)
        .with_contracts(&[&contract_instance])
        .call()
        .await?;
```

And this is an example that uses `with_contract_ids(&[&contract_id, ...])`.

```rust,ignore
    let response = script_instance
        .main(contract_id, MatchEnum::Logs)
        .with_contract_ids(&[contract_id])
        .call()
        .await?;
```

## Configurable constants

Same as contracts, you can define `configurable` constants in `scripts` which can be changed during the script execution. Here is an example how the constants are defined.

```rust,ignore
script;

#[allow(dead_code)]
enum EnumWithGeneric<D> {
    VariantOne: D,
    VariantTwo: (),
}

struct StructWithGeneric<D> {
    field_1: D,
    field_2: u64,
}

configurable {
    BOOL: bool = true,
    U8: u8 = 8,
    U16: u16 = 16,
    U32: u32 = 32,
    U64: u64 = 63,
    U256: u256 = 0x0000000000000000000000000000000000000000000000000000000000000008u256,
    B256: b256 = 0x0101010101010101010101010101010101010101010101010101010101010101,
    STR_4: str[4] = __to_str_array("fuel"),
    TUPLE: (u8, bool) = (8, true),
    ARRAY: [u32; 3] = [253, 254, 255],
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}
//U128: u128 = 128, //TODO: add once https://github.com/FuelLabs/sway/issues/5356 is done

fn main() -> (bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric<u8>, EnumWithGeneric<bool>) {
    (BOOL, U8, U16, U32, U64, U256, B256, STR_4, TUPLE, ARRAY, STRUCT, ENUM)
}

```

Each configurable constant will get a dedicated `with` method in the SDK. For example, the constant `STR_4` will get the `with_STR_4` method which accepts the same type defined in sway. Below is an example where we chain several `with` methods and execute the script with the new constants.

```rust,ignore
    abigen!(Script(
        name = "MyScript",
        abi = "e2e/sway/scripts/script_configurables/out/release/script_configurables-abi.json"
    ));

    let wallet = launch_provider_and_get_wallet().await?;
    let bin_path = "sway/scripts/script_configurables/out/release/script_configurables.bin";
    let instance = MyScript::new(wallet, bin_path);

    let str_4: SizedAsciiString<4> = "FUEL".try_into()?;
    let new_struct = StructWithGeneric {
        field_1: 16u8,
        field_2: 32,
    };
    let new_enum = EnumWithGeneric::VariantTwo;

    let configurables = MyScriptConfigurables::new(EncoderConfig {
        max_tokens: 5,
        ..Default::default()
    })
    .with_BOOL(false)?
    .with_U8(7)?
    .with_U16(15)?
    .with_U32(31)?
    .with_U64(63)?
    .with_U256(U256::from(8))?
    .with_B256(Bits256([2; 32]))?
    .with_STR_4(str_4.clone())?
    .with_TUPLE((7, false))?
    .with_ARRAY([252, 253, 254])?
    .with_STRUCT(new_struct.clone())?
    .with_ENUM(new_enum.clone())?;

    let response = instance
        .with_configurables(configurables)
        .main()
        .call()
        .await?;
```


---

### File: docs/fuels-rs/docs/src/testing/basics.md

# Testing Basics

If you're new to Rust, you'll want to review these important tools to help you build tests.

## The `assert!` macro

<!-- This section should explain the `assert!` macro -->
<!-- assert:example:start -->

You can use the `assert!` macro to assert certain conditions in your test. This macro invokes `panic!()` and fails the test if the expression inside evaluates to `false`.

<!-- assert:example:end -->

<!-- This section should show an example of the `assert!` macro -->
<!-- assert_code:example:start -->

```rust, ignore
assert!(value == 5);
```

<!-- assert_code:example:end -->

## The `assert_eq!` macro

<!-- This section should show an example of the `assert_eq!` macro -->
<!-- assert_eq:example:start -->

The `assert_eq!` macro works a lot like the `assert` macro, however instead it accepts two values, and panics if those values are not equal.

<!-- assert_eq:example:end -->

<!-- This section should show an example of the `assert_eq!` macro -->
<!-- assert_eq_code:example:start -->

```rust, ignore
assert_eq!(balance, 100);
```

<!-- assert_eq_code:example:end -->

## The `assert_ne!` macro

<!-- This section should show an example of the `assert_ne!` macro -->
<!-- assert_ne:example:start -->

The `assert_ne!` macro works just like the `assert_eq!` macro, but it will panic if the two values are equal.

<!-- assert_ne:example:end -->

<!-- This section should show an example of the `assert_ne!` macro -->
<!-- assert_ne_code:example:start -->

```rust, ignore
assert_ne!(address, 0);
```

<!-- assert_ne_code:example:end -->

## The `println!` macro

<!-- This section should explain how the `println!` macro can be used in tests -->
<!--print_ln:example:start -->

You can use the `println!` macro to print values to the console.

<!--print_ln:example:end -->

<!-- This section should show an example of the `println!` macro -->
<!--print_ln_code:example:start -->

```rust, ignore
println!("WALLET 1 ADDRESS {}", wallet_1.address());
println!("WALLET 1 ADDRESS {:?}", wallet_1.address());
```

<!--print_ln_code:example:end -->

<!-- This section should explain how `{}` and `{:?}` are used in the `println!` macro -->
<!--print_ln_2:example:start -->

Using `{}` will print the value, and using `{:?}` will print the value plus its type.

Using `{:?}` will also allow you to print values that do not have the `Display` trait implemented but do have the `Debug` trait. Alternatively you can use the `dbg!` macro to print these types of variables.

<!--print_ln_2:example:end -->

<!-- This section should show an example of the `println!` and `dbg` macros -->
<!--print_ln_dbg_code:example:start -->

```rust, ignore
println!("WALLET 1 PROVIDER {:?}", wallet_1.provider());
dbg!("WALLET 1 PROVIDER {}", wallet_1.provider());
```

<!--print_ln_dbg_code:example:end -->

<!-- This section should explain how implement custom fmt -->
<!--fmt:example:start -->

To print more complex types that don't have it already, you can implement your own formatted display method with the `fmt` module from the Rust standard library.

<!--fmt:example:end -->

<!-- This section should show a code example of how implement custom fmt -->
<!--fmt_code:example:start -->

```rust, ignore
use std::fmt;

struct Point {
    x: u64,
    y: u64,
}

// add print functionality with the fmt module
impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "value of x: {}, value of y: {}", self.x, self.y)
    }
}

let p = Point {x: 1, y: 2};
println!("POINT: {}", p);
```

<!--fmt_code:example:end -->

## Run Commands

You can run your tests to see if they pass or fail with

```shell
cargo test
```

<!-- This section should when outputs are hidden and what the `nocapture` flag does -->
<!--outputs:example:start -->

Outputs will be hidden if the test passes. If you want to see outputs printed from your tests regardless of whether they pass or fail, use the `nocapture` flag.

<!--outputs:example:end -->

```shell
cargo test -- --nocapture
```


---

### File: docs/fuels-rs/docs/src/testing/chains.md

# Increasing the block height

You can use `produce_blocks` to help achieve an arbitrary block height; this is useful when you want to do any testing regarding transaction maturity.

> **Note**: For the `produce_blocks` API to work, it is imperative to have `manual_blocks_enabled = true` in the config for the running node. See example below.

```rust,ignore
    let wallets =
        launch_custom_provider_and_get_wallets(WalletsConfig::default(), None, None).await?;
    let wallet = &wallets[0];
    let provider = wallet.provider();

    assert_eq!(provider.latest_block_height().await?, 0u32);

    provider.produce_blocks(3, None).await?;

    assert_eq!(provider.latest_block_height().await?, 3u32);
```

You can also set a custom block time as the second, optional argument. Here is an example:

```rust,ignore
    let block_time = 20u32; // seconds
    let config = NodeConfig {
        // This is how you specify the time between blocks
        block_production: Trigger::Interval {
            block_time: std::time::Duration::from_secs(block_time.into()),
        },
        ..NodeConfig::default()
    };
    let wallets =
        launch_custom_provider_and_get_wallets(WalletsConfig::default(), Some(config), None)
            .await?;
    let wallet = &wallets[0];
    let provider = wallet.provider();

    assert_eq!(provider.latest_block_height().await?, 0u32);
    let origin_block_time = provider.latest_block_time().await?.unwrap();
    let blocks_to_produce = 3;

    provider.produce_blocks(blocks_to_produce, None).await?;
    assert_eq!(provider.latest_block_height().await?, blocks_to_produce);
    let expected_latest_block_time = origin_block_time
        .checked_add_signed(Duration::try_seconds((blocks_to_produce * block_time) as i64).unwrap())
        .unwrap();
    assert_eq!(
        provider.latest_block_time().await?.unwrap(),
        expected_latest_block_time
    );
```


---

### File: docs/fuels-rs/docs/src/testing/index.md

# `fuels-rs` Testing

> **note** This section is still a work in progress.

- [Testing Basics](./basics.md)
- [`setup_program_test!` Macro](./the-setup-program-test-macro.md)
- [Tweaking the Blockchain](./chains.md)


---

### File: docs/fuels-rs/docs/src/testing/the-setup-program-test-macro.md

# The setup_program_test! macro

When deploying contracts with the `abigen!` macro, as shown in the previous sections, the user can:

- change the default configuration parameters
- launch several providers
- create multiple wallets
- create specific assets, etc.

However, it is often the case that we want to quickly set up a test with default values and work directly with contract or script instances. The `setup_program_test!` can do exactly that.

---

Used to reduce boilerplate in integration tests. Accepts input in the form
of `COMMAND(ARG...)...`

`COMMAND` is either `Wallets`, `Abigen`, `LoadScript` or `Deploy`.

`ARG` is either a:

- name-value (e.g. `name="MyContract"`), or,
- a literal (e.g. `"some_str_literal"`, `true`, `5`, ...)
- a sub-command (e.g. `Abigen(Contract(name="MyContract", project="some_project"))`)

Available `COMMAND`s:

## Options

Example: `Options(profile="debug")`

Description: Sets options from `ARG`s to be used by other `COMMAND`s.

Available options:

- `profile`: sets the `cargo` build profile. Variants: `"release"` (default),  `"debug"`

Cardinality: 0 or 1.

## Wallets

Example: `Wallets("a_wallet", "another_wallet"...)`

Description: Launches a local provider and generates wallets with names taken from the provided `ARG`s.

Cardinality: 0 or 1.

## Abigen

Example:

```rust,ignore
Abigen(
    Contract(
        name = "MyContract",
        project = "some_folder"
    ),
    Script(
        name = "MyScript",
        project = "some_folder"
    ),
    Predicate(
        name = "MyPredicate",
        project = "some_folder"
    ),
)
```

Description: Generates the program bindings under the name `name`. `project` should point to root of the `forc` project. The project must be compiled in `release` mode (`--release` flag) for `Abigen` command to work.

Cardinality: 0 or N.

## Deploy

Example: `Deploy(name="instance_name", contract="MyContract", wallet="a_wallet")`

Description: Deploys the `contract` (with salt) using `wallet`. Will create a contract instance accessible via `name`. Due to salt usage, the same contract can be deployed multiple times. Requires that an `Abigen` command be present with `name` equal to `contract`. `wallet` can either be one of the wallets in the `Wallets` `COMMAND` or the name of a wallet you've previously generated yourself.

Cardinality: 0 or N.

## `LoadScript`

Example: `LoadScript(name = "script_instance", script = "MyScript", wallet = "wallet")`

Description: Creates a script instance of `script` under `name` using `wallet`.

Cardinality: 0 or N.

---

The setup code that you have seen in previous sections gets reduced to:

```rust,ignore
        setup_program_test!(
            Wallets("wallet"),
            Abigen(Contract(
                name = "TestContract",
                project = "e2e/sway/contracts/contract_test"
            )),
            Deploy(
                name = "contract_instance",
                contract = "TestContract",
                wallet = "wallet"
            ),
        );

        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .call()
            .await?;

        assert_eq!(42, response.value);
```

> **Note** The same contract can be deployed several times as the macro deploys the contracts with salt. You can also deploy different contracts to the same provider by referencing the same wallet in the `Deploy` command.

```rust,ignore
    setup_program_test!(
        Wallets("wallet"),
        Abigen(
            Contract(
                name = "LibContract",
                project = "e2e/sway/contracts/lib_contract"
            ),
            Contract(
                name = "LibContractCaller",
                project = "e2e/sway/contracts/lib_contract_caller"
            ),
        ),
        Deploy(
            name = "lib_contract_instance",
            contract = "LibContract",
            wallet = "wallet",
            random_salt = false,
        ),
        Deploy(
            name = "contract_caller_instance",
            contract = "LibContractCaller",
            wallet = "wallet",
        ),
        Deploy(
            name = "contract_caller_instance2",
            contract = "LibContractCaller",
            wallet = "wallet",
        ),
    );
    let lib_contract_id = lib_contract_instance.contract_id();

    let contract_caller_id = contract_caller_instance.contract_id();

    let contract_caller_id2 = contract_caller_instance2.contract_id();

    // Because we deploy with salt, we can deploy the same contract multiple times
    assert_ne!(contract_caller_id, contract_caller_id2);

    // The first contract can be called because they were deployed on the same provider
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contracts(&[&lib_contract_instance])
        .call()
        .await?;

    assert_eq!(43, response.value);

    let response = contract_caller_instance2
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contracts(&[&lib_contract_instance])
        .call()
        .await?;

    assert_eq!(43, response.value);
```

In this example, three contracts are deployed on the same provider using the `wallet` generated by the `Wallets` command. The second and third macros use the same contract but have different IDs because of the deployment with salt. Both of them can call the first contract by using their ID.

In addition, you can manually create the `wallet` variable and then use it inside the macro. This is useful if you want to create custom wallets or providers but still want to use the macro to reduce boilerplate code. Below is an example of this approach.

```rust,ignore
    let config = WalletsConfig::new(Some(2), Some(1), Some(DEFAULT_COIN_AMOUNT));

    let mut wallets = launch_custom_provider_and_get_wallets(config, None, None).await?;
    let wallet = wallets.pop().unwrap();
    let wallet_2 = wallets.pop().unwrap();

    setup_program_test!(
        Abigen(Contract(
            name = "TestContract",
            project = "e2e/sway/contracts/contract_test"
        )),
        Deploy(
            name = "contract_instance",
            contract = "TestContract",
            wallet = "wallet",
            random_salt = false,
        ),
    );
```


---

### File: docs/fuels-rs/docs/src/types/B512.md

# `B512`

In the Rust SDK, the `B512` definition matches the Sway standard library type with the same name and will be converted accordingly when interacting with contracts:

```rust,ignore
pub struct B512 {
    pub bytes: [Bits256; 2],
}
```

Here's an example:

```rust,ignore
    let hi_bits = Bits256::from_hex_str(
        "0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c",
    )?;
    let lo_bits = Bits256::from_hex_str(
        "0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d",
    )?;
    let b512 = B512::from((hi_bits, lo_bits));
```


---

### File: docs/fuels-rs/docs/src/types/address.md

# `Address`

Like `Bytes32`, `Address` is a wrapper on `[u8; 32]` with similar methods and implements the same traits (see [fuel-types documentation](https://docs.rs/fuel-types/latest/fuel_types/struct.Address.html)).

These are the main ways of creating an `Address`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::Address;

        // Zeroed Bytes32
        let address = Address::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *address);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_address
        let my_slice = [1u8; 32];
        let address = Address::new(my_slice);
        // ANCHOR_END: array_to_address
        assert_eq!([1u8; 32], *address);

        // From a string.
        // ANCHOR: hex_string_to_address
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let address = Address::from_str(hex_str)?;
        // ANCHOR_END: hex_string_to_address
        assert_eq!([0u8; 32], *address);
        let _identity_from_address = Identity::Address(address);
        let _str_from_address: &str = address.to_string().as_str();
        let bits_256 = Bits256(address.into());
```


---

### File: docs/fuels-rs/docs/src/types/asset-id.md

# `AssetId`

Like `Bytes32`, `AssetId` is a wrapper on `[u8; 32]` with similar methods and implements the same traits (see [fuel-types documentation](https://docs.rs/fuel-types/0.49.0/fuel_types/struct.AssetId.html)).

These are the main ways of creating an `AssetId`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::AssetId;

        // Zeroed Bytes32
        let asset_id = AssetId::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *asset_id);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_asset_id
        let my_slice = [1u8; 32];
        let asset_id = AssetId::new(my_slice);
        // ANCHOR_END: array_to_asset_id
        assert_eq!([1u8; 32], *asset_id);

        // From a string.
        // ANCHOR: string_to_asset_id
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let asset_id = AssetId::from_str(hex_str)?;
        // ANCHOR_END: string_to_asset_id
        assert_eq!([0u8; 32], *asset_id);
        let _str_from_asset_id: &str = asset_id.to_string().as_str();
        let _asset_id_to_bits_256 = Bits256(asset_id.into());
```


---

### File: docs/fuels-rs/docs/src/types/bits256.md

# `Bits256`

In Fuel, a type called `b256` represents hashes and holds a 256-bit value. The Rust SDK represents `b256` as `Bits256(value)` where `value` is a `[u8; 32]`. If your contract method takes a `b256` as input, you must pass a `Bits256([u8; 32])` when calling it from the SDK.

Here's an example:

```rust,ignore
        let b256 = Bits256([1; 32]);

        let call_handler = contract_instance.methods().b256_as_input(b256);
```

If you have a hexadecimal value as a string and wish to convert it to `Bits256`, you may do so with `from_hex_str`:

```rust,ignore
        let hex_str = "0101010101010101010101010101010101010101010101010101010101010101";

        let bits256 = Bits256::from_hex_str(hex_str)?;

        assert_eq!(bits256.0, [1u8; 32]);

        // With the `0x0` prefix
        // ANCHOR: hex_str_to_bits256
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bits256 = Bits256::from_hex_str(hex_str)?;
        // ANCHOR_END: hex_str_to_bits256

        assert_eq!(bits256.0, [1u8; 32]);
```


---

### File: docs/fuels-rs/docs/src/types/bytes.md

# `Bytes`

In Fuel, a type called `Bytes` represents a collection of tightly-packed bytes. The Rust SDK represents `Bytes` as `Bytes(Vec<u8>)`. Here's an example of using `Bytes` in a contract call:

```rust,ignore
        let bytes = Bytes(vec![40, 41, 42]);

        contract_methods.accept_bytes(bytes).call().await?;
```

If you have a hexadecimal value as a string and wish to convert it to `Bytes`, you may do so with `from_hex_str`:

```rust,ignore
        let hex_str = "0101010101010101010101010101010101010101010101010101010101010101";

        let bytes = Bytes::from_hex_str(hex_str)?;

        assert_eq!(bytes.0, vec![1u8; 32]);

        // With the `0x0` prefix
        // ANCHOR: hex_string_to_bytes32
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bytes = Bytes::from_hex_str(hex_str)?;
        // ANCHOR_END: hex_string_to_bytes32

        assert_eq!(bytes.0, vec![1u8; 32]);
```


---

### File: docs/fuels-rs/docs/src/types/bytes32.md

# `Bytes32`

In Sway and the FuelVM, `Bytes32` represents hashes. They hold a 256-bit (32-byte) value. `Bytes32` is a wrapper on a 32-sized slice of `u8`: `pub struct Bytes32([u8; 32]);`.

These are the main ways of creating a `Bytes32`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::Bytes32;

        // Zeroed Bytes32
        let b256 = Bytes32::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *b256);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_bytes32
        let my_slice = [1u8; 32];
        let b256 = Bytes32::new(my_slice);
        // ANCHOR_END: array_to_bytes32
        assert_eq!([1u8; 32], *b256);

        // From a hex string.
        // ANCHOR: hex_string_to_bytes32
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let b256 = Bytes32::from_str(hex_str)?;
        // ANCHOR_END: hex_string_to_bytes32
        assert_eq!([0u8; 32], *b256);
        let b256_string = b256.to_string();
        let b256_hex_string = format!("{b256:#x}");
        let _str_from_bytes32: &str = b256.to_string().as_str();
```

`Bytes32` also implements the `fmt` module's `Debug`, `Display`, `LowerHex` and `UpperHex` traits. For example, you can get the display and hex representations with:

```rust,ignore
        let b256_string = b256.to_string();
        let b256_hex_string = format!("{b256:#x}");
```

For a full list of implemented methods and traits, see the [fuel-types documentation](https://docs.rs/fuel-types/latest/fuel_types/struct.Bytes32.html).

> **Note:** In Fuel, there's a special type called `b256`, which is similar to `Bytes32`; also used to represent hashes, and it holds a 256-bit value. In Rust, through the SDK, this is represented as `Bits256(value)` where `value` is a `[u8; 32]`. If your contract method takes a `b256` as input, all you need to do is pass a `Bits256([u8; 32])` when calling it from the SDK.


---

### File: docs/fuels-rs/docs/src/types/contract-id.md

# `ContractId`

Like `Bytes32`, `ContractId` is a wrapper on `[u8; 32]` with similar methods and implements the same traits (see [fuel-types documentation](https://docs.rs/fuel-types/0.49.0/fuel_types/struct.ContractId.html)).

These are the main ways of creating a `ContractId`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::ContractId;

        // Zeroed Bytes32
        let contract_id = ContractId::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *contract_id);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_contract_id
        let my_slice = [1u8; 32];
        let contract_id = ContractId::new(my_slice);
        // ANCHOR_END: array_to_contract_id
        assert_eq!([1u8; 32], *contract_id);

        // From a string.
        // ANCHOR: string_to_contract_id
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let contract_id = ContractId::from_str(hex_str)?;
        // ANCHOR_END: string_to_contract_id
        assert_eq!([0u8; 32], *contract_id);
        let _identity_from_contract_id = Identity::ContractId(contract_id);
        let _str_from_contract_id: &str = contract_id.to_string().as_str();
        let _contract_id_to_bits_256 = Bits256(contract_id.into());
```


---

### File: docs/fuels-rs/docs/src/types/conversion.md

# Converting Types

Below you can find examples for common type conversions:

- [Convert Between Native Types](#convert-between-native-types)
- [Convert to `Bytes32`](#convert-to-bytes32)
- [Convert to `Address`](#convert-to-address)
- [Convert to `ContractId`](#convert-to-contractid)
- [Convert to `Identity`](#convert-to-identity)
- [Convert to `AssetId`](#convert-to-assetid)
- [Convert to `str`](#convert-to-str)
- [Convert to `Bits256`](#convert-to-bits256)
- [Convert to `Bytes`](#convert-to-bytes)
- [Convert to `B512`](#convert-to-b512)
- [Convert to `EvmAddress`](#convert-to-evmaddress)

## Convert Between Native Types

You might want to convert between the native types (`Bytes32`, `Address`, `ContractId`, and `AssetId`). Because these types are wrappers on `[u8; 32]`, converting is a matter of dereferencing one and instantiating the other using the dereferenced value. Here's an example:

```rust,ignore
        use fuels::types::{AssetId, ContractId};

        let contract_id = ContractId::new([1u8; 32]);

        let asset_id: AssetId = AssetId::new(*contract_id);

        assert_eq!([1u8; 32], *asset_id);
```

## Convert to `Bytes32`

Convert a `[u8; 32]` array to `Bytes32`:

```rust,ignore
        let my_slice = [1u8; 32];
        let b256 = Bytes32::new(my_slice);
```

Convert a hex string to `Bytes32`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let b256 = Bytes32::from_str(hex_str)?;
```

## Convert to `Address`

Convert a `[u8; 32]` array to an `Address`:

```rust,ignore
        let my_slice = [1u8; 32];
        let address = Address::new(my_slice);
```

Convert a wallet to an `Address`:

```rust,ignore
        let wallet = Wallet::random(&mut rng, provider);
        let address: Address = wallet.address();
```

Convert a hex string to an `Address`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let address = Address::from_str(hex_str)?;
```

## Convert to `ContractId`

Convert a `[u8; 32]` array to `ContractId`:

```rust,ignore
        let my_slice = [1u8; 32];
        let contract_id = ContractId::new(my_slice);
```

Convert a hex string to a `ContractId`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let contract_id = ContractId::from_str(hex_str)?;
```

Convert a contract instance to a `ContractId`:

```rust,ignore
    let contract_id: ContractId = contract_instance.contract_id();
```

## Convert to `Identity`

Convert an `Address` to an `Identity`:

```rust,ignore
        let _identity_from_address = Identity::Address(address);
```

Convert a `ContractId` to an `Identity`:

```rust,ignore
        let _identity_from_contract_id = Identity::ContractId(contract_id);
```

## Convert to `AssetId`

Convert a `[u8; 32]` array to an `AssetId`:

```rust,ignore
        let my_slice = [1u8; 32];
        let asset_id = AssetId::new(my_slice);
```

Convert a hex string to an `AssetId`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let asset_id = AssetId::from_str(hex_str)?;
```

## Convert to `str`

Convert a `ContractId` to a `str`:

```rust,ignore
        let _str_from_contract_id: &str = contract_id.to_string().as_str();
```

Convert an `Address` to a `str`:

```rust,ignore
        let _str_from_address: &str = address.to_string().as_str();
```

Convert an `AssetId` to a `str`:

```rust,ignore
        let _str_from_asset_id: &str = asset_id.to_string().as_str();
```

Convert `Bytes32` to a `str`:

```rust,ignore
        let _str_from_bytes32: &str = b256.to_string().as_str();
```

## Convert to `Bits256`

Convert a hex string to `Bits256`:

```rust,ignore
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bits256 = Bits256::from_hex_str(hex_str)?;
```

Convert a `ContractId` to `Bits256`:

```rust,ignore
        let _contract_id_to_bits_256 = Bits256(contract_id.into());
```

Convert an `Address` to `Bits256`:

```rust,ignore
        let bits_256 = Bits256(address.into());
```

Convert an `AssetId` to `Bits256`:

```rust,ignore
        let _asset_id_to_bits_256 = Bits256(asset_id.into());
```

## Convert to `Bytes`

Convert a string to `Bytes`:

```rust,ignore
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bytes = Bytes::from_hex_str(hex_str)?;
```

## Convert to `B512`

Convert two hex strings to `B512`:

```rust,ignore
    let hi_bits = Bits256::from_hex_str(
        "0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c",
    )?;
    let lo_bits = Bits256::from_hex_str(
        "0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d",
    )?;
    let b512 = B512::from((hi_bits, lo_bits));
```

## Convert to `EvmAddress`

Convert a `Bits256` address to an `EvmAddress`:

```rust,ignore
        let _evm_address = EvmAddress::from(bits_256);
```


---

### File: docs/fuels-rs/docs/src/types/custom_types.md

# Structs and enums

<!-- This section should explain how to get the custom types from a Sway program -->
<!-- custom_types:example:start -->
The structs and enums you define in your Sway code have equivalents automatically generated by the SDK's `abigen!` macro.
<!-- custom_types:example:end -->

For instance, if in your Sway code you have a struct called `CounterConfig` that looks like this:

```rust,ignore
struct CounterConfig {
  dummy: bool,
  initial_value: u64,
}
```

After using the `abigen!` macro, `CounterConfig` will be accessible in your Rust file! Here's an example:

```rust,ignore
    abigen!(Contract(
        name = "MyContract",
        abi = "e2e/sway/types/contracts/complex_types_contract/out/release/complex_types_contract-abi.json"
    ));

    // Here we can use `CounterConfig`, a struct originally
    // defined in the contract.
    let counter_config = CounterConfig {
        dummy: true,
        initial_value: 42,
    };
```

You can freely use your custom types (structs or enums) within this scope. That also means passing custom types to functions and receiving custom types from function calls.

## Generics

The Fuel Rust SDK supports both generic enums and generic structs. If you're already familiar with Rust, it's your typical `struct MyStruct<T>` type of generics support.

For instance, your Sway contract could look like this:

```Rust
contract;

use std::hash::sha256;

struct SimpleGeneric<T> {
    single_generic_param: T,
}

abi MyContract {
  fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64>;
}

impl MyContract for Contract {
    fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64> {
        let expected = SimpleGeneric {
            single_generic_param: 123u64,
        };

        assert(arg1.single_generic_param == expected.single_generic_param);

        expected
    }
}
```

Your Rust code would look like this:

```rust,ignore
        // simple struct with a single generic param
        let arg1 = SimpleGeneric {
            single_generic_param: 123u64,
        };

        let result = contract_methods
            .struct_w_generic(arg1.clone())
            .call()
            .await?
            .value;

        assert_eq!(result, arg1);
```

### Unused generic type parameters

Sway supports unused generic type parameters when declaring structs/enums:

```Rust
struct SomeStruct<T, K> {
  field: u64
}

enum SomeEnum<T, K> {
  One: u64
}

```

If you tried the same in Rust you'd get complaints that `T` and `K` must be used or removed. When generating Rust bindings for such types we make use of the [`PhantomData`](https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters) type. The generated bindings for the above example would look something like this:

```Rust
struct SomeStruct<T, K> {
   pub field: u64,
   pub _unused_generic_0: PhantomData<T>
   pub _unused_generic_1: PhantomData<K>
}

enum SomeEnum<T, K> {
  One(u64),
  IgnoreMe(PhantomData<T>, PhantomData<K>)
}
```

To lessen the impact to developer experience you may use the `new` method to initialize a structure without bothering with the `PhantomData`s.:

```rust,ignore
        assert_eq!(
            <StructUnusedGeneric<u16, u32>>::new(15),
            StructUnusedGeneric {
                field: 15,
                _unused_generic_0: std::marker::PhantomData,
                _unused_generic_1: std::marker::PhantomData
            }
        );
```

If your struct doesn't have any fields we'll also derive `Default`. As for enums all `PhantomData`s are placed inside a new variant called `IgnoreMe` which you'll need to ignore in your matches:

```rust,ignore
        match my_enum {
            EnumUnusedGeneric::One(_value) => {}
            EnumUnusedGeneric::IgnoreMe(..) => panic!("Will never receive this variant"),
        }
```


---

### File: docs/fuels-rs/docs/src/types/evm_address.md

# `EvmAddress`

In the Rust SDK, Ethereum Virtual Machine (EVM) addresses can be represented with the `EvmAddress` type. Its definition matches with the Sway standard library type with the same name and will be converted accordingly when interacting with contracts:

```rust,ignore
pub struct EvmAddress {
    // An evm address is only 20 bytes, the first 12 bytes should be set to 0
    value: Bits256,
}
```

Here's an example:

```rust,ignore
        let b256 = Bits256::from_hex_str(
            "0x1616060606060606060606060606060606060606060606060606060606060606",
        )?;
        let evm_address = EvmAddress::from(b256);

        let call_handler = contract_instance
            .methods()
            .evm_address_as_input(evm_address);
```

> **Note:** when creating an `EvmAddress` from `Bits256`, the first 12 bytes will be cleared because an EVM address is only 20 bytes long.


---

### File: docs/fuels-rs/docs/src/types/index.md

# Types

The FuelVM and Sway have many internal types. These types have equivalents in the SDK. This section discusses these types, how to use them, and how to convert them.


---

### File: docs/fuels-rs/docs/src/types/string.md

# `String`

The Rust SDK represents Fuel's `String`s as `SizedAsciiString<LEN>`, where the generic parameter `LEN` is the length of a given string. This abstraction is necessary because all strings in Fuel and Sway are statically-sized, i.e., you must know the size of the string beforehand.

Here's how you can create a simple string using `SizedAsciiString`:

```rust,ignore
        let ascii_data = "abc".to_string();

        SizedAsciiString::<3>::new(ascii_data)
            .expect("should have succeeded since we gave ascii data of correct length!");
```

To make working with `SizedAsciiString`s easier, you can use `try_into()` to convert from Rust's `String` to `SizedAsciiString`, and you can use `into()` to convert from `SizedAsciiString` to Rust's `String`. Here are a few examples:

```rust,ignore
    #[test]
    fn can_be_constructed_from_str_ref() {
        let _: SizedAsciiString<3> = "abc".try_into().expect("should have succeeded");
    }

    #[test]
    fn can_be_constructed_from_string() {
        let _: SizedAsciiString<3> = "abc".to_string().try_into().expect("should have succeeded");
    }

    #[test]
    fn can_be_converted_into_string() {
        let sized_str = SizedAsciiString::<3>::new("abc".to_string()).unwrap();

        let str: String = sized_str.into();

        assert_eq!(str, "abc");
    }
```

If your contract's method takes and returns, for instance, a Sway's `str[23]`. When using the SDK, this method will take and return a `SizedAsciiString<23>`.


---

### File: docs/fuels-rs/docs/src/types/vectors.md

# Vectors

## Passing in vectors

You can pass a Rust `std::vec::Vec` into your contract method transparently. The following code calls a Sway contract method which accepts a `Vec<SomeStruct<u32>>`.

```rust,ignore
        let arg = vec![SomeStruct { a: 0 }, SomeStruct { a: 1 }];
        methods.struct_in_vec(arg.clone()).call().await?;
```

You can use a vector just like you would use any other type -- e.g. a `[Vec<u32>; 2]` or a `SomeStruct<Vec<Bits256>>` etc.

## Returning vectors

Returning vectors from contract methods is supported transparently, with the caveat that you cannot have them nested inside another type. This limitation is temporary.

```rust,ignore
    let response = contract_methods.u8_in_vec(10).call().await?;
    assert_eq!(response.value, (0..10).collect::<Vec<_>>());
```

> **Note: you can still interact with contracts containing methods that return vectors nested inside another type, just not interact with the methods themselves**


---

### File: docs/fuels-rs/docs/src/wallets/access.md

# Wallet Access

The kinds of operations we can perform with a `Wallet` instance depend on
whether or not the wallet has a signer attached to it.

In order to differentiate between `Wallet` instances that have a signer
and those that do not, we use the `Wallet<Unlocked<S>>` and `Wallet<Locked>` types
respectively.

## Wallet States

The `Wallet<Unlocked<S>>` type represents a wallet that has a signer. A wallet must be of type `Wallet<Unlocked<S>>` in order to perform operations that involve signing messages or transactions.

You can learn more about signing [here](./signing.md).

The `Wallet<Locked>` type represents a wallet without a signer. Instead, `Wallet<Locked>` only knows its public address. A `Wallet<Locked>` cannot be used to sign transactions, however it may still perform a whole suite of useful operations including listing transactions, assets, querying balances, and so on.

## Transitioning States

A `Wallet<Unlocked<S>>` instance can be locked using the `lock` method:

```rust,ignore
let wallet_locked = wallet_unlocked.lock();
```

## Design Guidelines

When designing APIs that accept a wallet as an input, we should think carefully
about the kind of access that we require. API developers should aim to minimise
their usage of `Wallet<Unlocked<S>>` in order to ensure signers are stored in
memory no longer than necessary to reduce the surface area for attacks and
vulnerabilities in downstream libraries and applications.


---

### File: docs/fuels-rs/docs/src/wallets/checking-balances-and-coins.md

# Checking balances and coins

<!-- This section should explain getting the balance of a wallet -->
<!-- balance:example:start -->
In the Fuel network, each UTXO corresponds to a unique _coin_, and said _coin_ has a corresponding _amount_ (the same way a dollar bill has either 10$ or 5$ face value). So, when you want to query the balance for a given asset ID, you want to query the sum of the amount in each unspent coin. This querying is done very easily with a wallet:
<!-- balance:example:end -->

```rust,ignore
        let asset_id = AssetId::zeroed();
        let balance: u128 = wallet.get_asset_balance(&asset_id).await?;
```

<!-- This section should explain getting all of the balances of a wallet -->
<!-- balances:example:start -->
If you want to query all the balances (i.e., get the balance for each asset ID in that wallet), you can use the `get_balances` method:
<!-- balances:example:end -->

```rust,ignore
        let balances: HashMap<String, u128> = wallet.get_balances().await?;
```

<!-- This section should explain the return type for `get_balances` -->
<!-- balances_return:example:start -->
The return type is a `HashMap`, where the key is the _asset ID's_ hex string, and the value is the corresponding balance. For example, we can get the base asset balance with:
<!-- balances_return:example:end -->

```rust,ignore
        let asset_balance = balances.get(&asset_id.to_string()).unwrap();
```


---

### File: docs/fuels-rs/docs/src/wallets/fake_signer.md

# Fake signer (impersonating another account)

To facilitate account impersonation, the Rust SDK provides the `FakeSigner`. We can use it to simulate ownership of assets held by an account with a given address. This also implies that we can impersonate contract calls from that address. A wallet with a `FakeSigner` will only succeed in unlocking assets if the network is set up with `utxo_validation = false`.

```rust,ignore
        let node_config = NodeConfig {
            utxo_validation: false,
            ..Default::default()
        };
        let provider = setup_test_provider(coins, vec![], Some(node_config), None).await?;
```

```rust,ignore
        let provider = setup_test_provider(coins, vec![], Some(node_config), None).await?;
```

```rust,ignore
        // create impersonator for an address
        let fake_signer = FakeSigner::new(some_address);
        let impersonator = Wallet::new(fake_signer, provider.clone());

        let contract_instance = MyContract::new(contract_id, impersonator.clone());

        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .call()
            .await?;

        assert_eq!(42, response.value);
```


---

### File: docs/fuels-rs/docs/src/wallets/index.md

# Wallets

Wallets serve as a centralized interface for all account-related behaviors. They allow you to:

- **Inspect UTXOs:** Check available coins for spending.
- **Prepare and send transactions:** Build, sign, and submit transfers.
- **Manage network fees:** Pay for transaction execution and contract deployment.

Every wallet requires a **provider** to communicate with the network.

---

## Types of Wallets

There are two primary types of wallets available in the SDK:

### [Locked Wallets](./access.md)

- **Purpose:** Used for read-only operations.
- **Interface:** Implements the [`ViewOnlyAccount`](../accounts.md) trait.
- **Use Cases:** Checking balances, viewing UTXOs, and monitoring transactions without the ability to sign or submit transactions.

### [Unlocked Wallets](./access.md)

- **Purpose:** Supports full account functionality.
- **Interface:** Implements the [`ViewOnlyAccount`](../accounts.md) and [`Account`](../accounts.md) traits.
- **Additional Requirement:** In addition to a provider, an unlocked wallet must include a **signer**.
- **Use Cases:** Transferring funds, signing messages, submitting transactions, and performing state-changing operations.

---

## Signer Options

The SDK offers multiple signing methods to suit different scenarios:

- [**Private Key Signer:**](./private_key_signer.md)  
  Use when you have direct access to your account’s private key.
- [**AWS KMS Signer:**](./kms.md)
  Delegate signing operations to AWS Key Management Service, enhancing key security by offloading cryptographic operations.

- [**Google KMS Signer:**](./kms.md)  
  Similar to AWS KMS, this option delegates signing to Google’s Key Management Service.

- [**Fake Signer:**](./fake_signer.md)  
  Generates dummy signatures, which is useful for impersonation while testing. Only possible when using a network that does not enforce signature validation.

---


---

### File: docs/fuels-rs/docs/src/wallets/keystore.md

# Encrypting and Storing Keys

The code below shows how to:

- Encrypt and store your key using a master password.
- Ensure that the key can be retrieved later with the proper credentials.

```rust,ignore
        let dir = std::env::temp_dir();
        let keystore = Keystore::new(&dir);

        let phrase =
            "oblige salon price punch saddle immune slogan rare snap desert retire surprise";

        // Create a key from the mnemonic phrase using the default derivation path.
        let key = SecretKey::new_from_mnemonic_phrase_with_path(phrase, DEFAULT_DERIVATION_PATH)?;
        let password = "my_master_password";

        // Encrypt and store the key on disk. It can be recovered using `Keystore::load_key`.
        let uuid = keystore.save_key(key, password, thread_rng())?;

        // Recover key from disk
        let recovered_key = keystore.load_key(&uuid, password)?;
```


---

### File: docs/fuels-rs/docs/src/wallets/kms.md

# Using KMS Wallets

Key Management Service (KMS) is a robust and secure solution for managing cryptographic keys for your Fuel wallets. Instead of keeping private keys on your local system, KMS Wallets leverage secure infrastructure to handle both key storage and signing operations.

The SDK provides signers for AWS and Google KMS.

Below is an example of how to initialize a wallet with a AWS KMS signer:

```rust,ignore
        let kms_signer = AwsKmsSigner::new(your_kms_key_id, aws_client).await?;
        let wallet = Wallet::new(kms_signer, provider);
```


---

### File: docs/fuels-rs/docs/src/wallets/private_key_signer.md

# Using private keys to create wallets

## Directly from a private key

An example of how to create a wallet that uses a private key signer:

```rust,ignore
        use std::str::FromStr;

        use fuels::{crypto::SecretKey, prelude::*};

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Setup the private key.
        let secret = SecretKey::from_str(
            "5f70feeff1f229e4a95e1056e8b4d80d0b24b565674860cc213bdb07127ce1b1",
        )?;

        // Create the wallet.
        let _wallet = Wallet::new(PrivateKeySigner::new(secret), provider);
```

There is also a helper for generating a wallet with a random private key signer:

```rust,ignore
        use fuels::prelude::*;

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Create the wallet.
        let _wallet = Wallet::random(&mut thread_rng(), provider);
```

## From a mnemonic phrase

A mnemonic phrase is a cryptographically generated sequence of words used to create a master seed. This master seed, when combined with a [derivation path](https://thebitcoinmanual.com/articles/btc-derivation-path/), enables the generation of one or more specific private keys. The derivation path acts as a roadmap within the [hierarchical deterministic (HD) wallet structure](https://www.ledger.com/academy/crypto/what-are-hierarchical-deterministic-hd-wallets), determining which branch of the key tree produces the desired private key.

```rust,ignore
        use fuels::prelude::*;

        let phrase =
            "oblige salon price punch saddle immune slogan rare snap desert retire surprise";

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Create first account from mnemonic phrase.
        let key =
            SecretKey::new_from_mnemonic_phrase_with_path(phrase, "m/44'/1179993420'/0'/0/0")?;
        let signer = PrivateKeySigner::new(key);
        let _wallet = Wallet::new(signer, provider.clone());

        // Or with the default derivation path.
        let key = SecretKey::new_from_mnemonic_phrase_with_path(phrase, DEFAULT_DERIVATION_PATH)?;
        let signer = PrivateKeySigner::new(key);
        let wallet = Wallet::new(signer, provider);

        let expected_address = "f18b6446deb8135544ba60333e5b7522685cd2cf64aa4e4c75df725149850b65";

        assert_eq!(wallet.address().to_string(), expected_address);
```

## Security Best Practices

- **Never Share Sensitive Information:**
  Do not disclose your private key or mnemonic phrase to anyone.

- **Secure Storage:**
  When storing keys on disk, **always encrypt** them (the SDK provides a [`Keystore`](./keystore.md). This applies to both plain private/secret keys and mnemonic phrases.


---

### File: docs/fuels-rs/docs/src/wallets/signing.md

# Signing

An example of how you might sign a message using any of the SDK signers (or your
own, custom ones, that implement `Signer`):

```rust,ignore
        let mut rng = StdRng::seed_from_u64(2322u64);
        let mut secret_seed = [0u8; 32];
        rng.fill_bytes(&mut secret_seed);

        let secret = secret_seed.as_slice().try_into()?;

        // Create a signer using the private key created above.
        let signer = PrivateKeySigner::new(secret);

        let message = Message::new("my message".as_bytes());
        let signature = signer.sign(message).await?;

        // Check if signature is what we expect it to be
        assert_eq!(
            signature,
            Signature::from_str(
                "0x8eeb238db1adea4152644f1cd827b552dfa9ab3f4939718bb45ca476d167c6512a656f4d4c7356bfb9561b14448c230c6e7e4bd781df5ee9e5999faa6495163d"
            )?
        );

        // Recover the public key that signed the message
        let recovered_pub_key: PublicKey = signature.recover(&message)?;

        assert_eq!(*signer.address, *recovered_pub_key.hash());

        // Verify signature
        signature.verify(&recovered_pub_key, &message)?;
```

## Adding `Signers` to a transaction builder

Every signed resource in the inputs needs to have a witness index that points to a valid witness. Changing the witness index inside an input will change the transaction ID. This means that we need to set all witness indexes before finally signing the transaction. We have to make sure that the witness indexes and the order of the witnesses are correct. To automate this process, the SDK will keep track of the signers in the transaction builder and resolve the final transaction automatically. This is done by storing signers until the final transaction is built.

Below is a full example of how to create a transaction builder and add signers to it.

> Note: When you add a `Signer` to a transaction builder, the signer is stored inside it and the transaction will not be resolved until you call `build()`!

```rust,ignore
        let secret = SecretKey::from_str(
            "5f70feeff1f229e4a95e1056e8b4d80d0b24b565674860cc213bdb07127ce1b1",
        )?;
        let signer = PrivateKeySigner::new(secret);

        // Set up a transaction
        let mut tb = {
            let input_coin = Input::ResourceSigned {
                resource: CoinType::Coin(Coin {
                    amount: 10000000,
                    owner: signer.address(),
                    ..Default::default()
                }),
            };

            let output_coin = Output::coin(
                Address::from_str(
                    "0xc7862855b418ba8f58878db434b21053a61a2025209889cc115989e8040ff077",
                )?,
                1,
                Default::default(),
            );
            let change = Output::change(signer.address(), 0, Default::default());

            ScriptTransactionBuilder::prepare_transfer(
                vec![input_coin],
                vec![output_coin, change],
                Default::default(),
            )
        };

        // Add `Signer` to the transaction builder
        tb.add_signer(signer.clone())?;
```

## Signing a built transaction

If you have a built transaction and want to add a signature, you can use the `sign_with` method.

```rust,ignore
    tx.sign_with(wallet.signer(), consensus_parameters.chain_id())
        .await?;
```


---

### File: docs/fuels-rs/docs/src/wallets/test-wallets.md

# Setting up test wallets

You'll often want to create one or more test wallets when testing your contracts. Here's how to do it.

## Setting up multiple test wallets

<!-- This section should explain setting up multiple test wallets -->
<!-- test_wallets:example:start -->
If you need multiple test wallets, they can be set up using the `launch_custom_provider_and_get_wallets` method.
<!-- test_wallets:example:end -->

```rust,ignore
        use fuels::prelude::*;
        // This helper launches a local node and provides 10 test wallets linked to it.
        // The initial balance defaults to 1 coin per wallet with an amount of 1_000_000_000.
        let wallets =
            launch_custom_provider_and_get_wallets(WalletsConfig::default(), None, None).await?;
```

<!-- This section should explain how to customize test wallets -->
<!-- custom_test_wallets:example:start -->
You can customize your test wallets via `WalletsConfig`.
<!-- custom_test_wallets:example:end -->

```rust,ignore
        let num_wallets = 5;
        let coins_per_wallet = 3;
        let amount_per_coin = 100;
        let config = WalletsConfig::new(
            Some(num_wallets),
            Some(coins_per_wallet),
            Some(amount_per_coin),
        );
        // Launches a local node and provides test wallets as specified by the config.
        let wallets = launch_custom_provider_and_get_wallets(config, None, None).await?;
```

<!-- This section should explain that test wallets are deterministic -->
<!-- deterministic:example:start -->
>**Note** Wallets generated with `launch_provider_and_get_wallet` or `launch_custom_provider_and_get_wallets`
will have deterministic addresses.
<!-- deterministic:example:end -->

## Setting up a test wallet with multiple random assets

You can create a test wallet containing multiple assets (including the base asset to pay for gas).

```rust,ignore
        // ANCHOR: multiple_assets_coins
        use fuels::prelude::*;
        let signer = PrivateKeySigner::random(&mut thread_rng());
        let num_assets = 5;
        let coins_per_asset = 10;
        let amount_per_coin = 15;

        let (coins, asset_ids) = setup_multiple_assets_coins(
            signer.address(),
            num_assets,
            coins_per_asset,
            amount_per_coin,
        );
        // ANCHOR_END: multiple_assets_coins
        let provider = setup_test_provider(coins.clone(), vec![], None, None).await?;
        let wallet = Wallet::new(signer, provider);
```

- coins: `Vec<(UtxoId, Coin)>` has `num_assets` * `coins_per_assets` coins (UTXOs)
- asset_ids: `Vec<AssetId>` contains the `num_assets` randomly generated `AssetId`s (always includes the base asset)

## Setting up a test wallet with multiple custom assets

You can also create assets with specific `AssetId`s, coin amounts, and number of coins.

```rust,ignore
        use fuels::prelude::*;
        use rand::Fill;

        let mut rng = rand::thread_rng();
        let signer = PrivateKeySigner::random(&mut rng);

        let asset_base = AssetConfig {
            id: AssetId::zeroed(),
            num_coins: 2,
            coin_amount: 4,
        };

        let mut asset_id_1 = AssetId::zeroed();
        asset_id_1.try_fill(&mut rng)?;
        let asset_1 = AssetConfig {
            id: asset_id_1,
            num_coins: 6,
            coin_amount: 8,
        };

        let mut asset_id_2 = AssetId::zeroed();
        asset_id_2.try_fill(&mut rng)?;
        let asset_2 = AssetConfig {
            id: asset_id_2,
            num_coins: 10,
            coin_amount: 12,
        };

        let assets = vec![asset_base, asset_1, asset_2];
        let coins = setup_custom_assets_coins(signer.address(), &assets);
        let provider = setup_test_provider(coins, vec![], None, None).await?;
        let wallet = Wallet::new(signer, provider.clone());
        let num_wallets = 1;
        let wallet_config = WalletsConfig::new_multiple_assets(num_wallets, assets);
        let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?;
```

This can also be achieved directly with the `WalletsConfig`.

```rust,ignore
        let num_wallets = 1;
        let wallet_config = WalletsConfig::new_multiple_assets(num_wallets, assets);
        let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?;
```

>**Note** In this case, you need to manually add the base asset and the corresponding number of
>coins and coin amount

## Setting up assets

The Fuel blockchain holds many different assets; you can create your asset with its unique `AssetId` or create random assets for testing purposes.

You can use only one asset to pay for transaction fees and gas: the base asset, whose `AssetId` is `0x000...0`, a 32-byte zeroed value.

For testing purposes, you can configure coins and amounts for assets. You can use `setup_multiple_assets_coins`:

```rust,ignore
        use fuels::prelude::*;
        let signer = PrivateKeySigner::random(&mut thread_rng());
        let num_assets = 5;
        let coins_per_asset = 10;
        let amount_per_coin = 15;

        let (coins, asset_ids) = setup_multiple_assets_coins(
            signer.address(),
            num_assets,
            coins_per_asset,
            amount_per_coin,
        );
```

>**Note** If setting up multiple assets, one of these assets will always be the base asset.

If you want to create coins only with the base asset, then you can use:

```rust,ignore
        let wallet_signer = PrivateKeySigner::random(&mut rand::thread_rng());

        // How many coins in our wallet.
        let number_of_coins = 1;

        // The amount/value in each coin in our wallet.
        let amount_per_coin = 3;

        let coins = setup_single_asset_coins(
            wallet_signer.address(),
            AssetId::zeroed(),
            number_of_coins,
            amount_per_coin,
        );
```

>**Note** Choosing a large number of coins and assets for `setup_multiple_assets_coins` or `setup_single_asset_coins` can lead to considerable runtime for these methods. This will be improved in the future but for now, we recommend using up to **1_000_000** coins, or **1000** coins and assets simultaneously.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/call-parameters.md.md

# Call Parameters

<!-- This section should explain call params -->
<!-- call_params:example:start -->

When interacting with contracts, you can configure specific parameters for contract calls using the `callParams` method. The available call parameters are:

1. `forward`
2. `gasLimit`
<!-- call_params:example:end -->

> **Note**: Setting transaction parameters is also available when calling contracts. More information on this can be found at [Transaction Parameters](../transactions/adding-parameters.md).

The contract in use in this section has the following implementation:

```
impl ReturnContext for Contract {
    #[payable]
    fn return_context_amount() -> u64 {
        msg_amount()
    }
}
```

## Forward Parameter

<!-- This section should explain the `forward` param -->
<!-- forward:example:start -->

The `forward` parameter allows the sending of a specific amount of coins to a contract when a function is called. This is useful when a contract function requires coins for its execution, such as transferring funds to another account or contract.

The forward parameter helps you control the resources allocated to the contract call and offers protection against potentially costly operations.

<!-- forward:example:end -->

```
const amountToForward = 10;
const baseAssetId = await provider.getBaseAssetId();

const { waitForResult } = await contract.functions
  .return_context_amount()
  .callParams({
    forward: [amountToForward, baseAssetId],
  })
  .call();

const { value } = await waitForResult();

console.log('forwarded amount:', value.toNumber());
// forwarded amount: 10
```

## Gas Limit Parameter

<!-- This section should explain the `gasLimit` param -->
<!-- gas_limit:example:start -->

The `gasLimit` refers to the maximum amount of gas that can be consumed specifically by the contract call itself, separate from the rest of the transaction.

<!-- gas_limit:example:end -->

```
try {
  await contract.functions
    .return_context_amount()
    .callParams({
      forward: [10, await provider.getBaseAssetId()],
      gasLimit: 1,
    })
    .call();
} catch (e) {
  console.log('error', e);
  // error _FuelError: The transaction reverted with reason: "OutOfGas"
}
```

## Call Parameter `gasLimit` vs Transaction Parameter `gasLimit`

The call parameter `gasLimit` sets the maximum gas allowed for the actual contract call, whereas the transaction parameter `gasLimit` _(see [Transaction Parameters](../transactions/adding-parameters.md))_ sets the maximum gas allowed for the entire transaction and constrains the `gasLimit` call parameter. If the call parameter `gasLimit` is set to a value greater than the _available_ transaction gas, then the entire available transaction gas will be allocated for the contract call execution.

If you don't set the `gasLimit` for the call, the transaction `gasLimit` will be applied.

## Setting Both Parameters

You can set both call parameters and transaction parameters within the same contract function call.

```
const contractCallGasLimit = 4_000;
const transactionGasLimit = 100_000;

const call = await contract.functions
  .return_context_amount()
  .callParams({
    forward: [10, await provider.getBaseAssetId()],
    gasLimit: contractCallGasLimit,
  })
  .txParams({
    gasLimit: transactionGasLimit,
  })
  .call();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/configurable-constants.md.md

# Configurable Constants

Sway introduces a powerful feature: configurable constants. When creating a contract, you can define constants, each assigned with a default value.

Before deploying the contract, you can then redefine the value for these constants, it can be all of them or as many as you need.

This feature provides flexibility for dynamic contract environments. It allows a high level of customization, leading to more efficient and adaptable smart contracts.

## Defining Configurable Constants

Below is an example of a contract in which we declare four configurable constants:

```
contract;

enum MyEnum {
    Checked: (),
    Pending: (),
}

struct MyStruct {
    x: u8,
    y: u8,
    state: MyEnum,
}

configurable {
    age: u8 = 25,
    tag: str[4] = __to_str_array("fuel"),
    grades: [u8; 4] = [3, 4, 3, 2],
    my_struct: MyStruct = MyStruct {
        x: 1,
        y: 2,
        state: MyEnum::Pending,
    },
}

abi EchoConfigurables {
    fn echo_configurables() -> (u8, str[4], [u8; 4], MyStruct);
}

impl EchoConfigurables for Contract {
    fn echo_configurables() -> (u8, str[4], [u8; 4], MyStruct) {
        (age, tag, grades, my_struct)
    }
}
```

In this contract, the function `echo_configurables` returns the values of the configurable constants, which we'll use for demonstrating the setting of configurables via the SDK.

## Setting New Values For Configurable Constants

During contract deployment, you can define new values for any/all of the configurable constants. The example below shows setting of one configurable constant, while the others will have default values.

```
const configurableConstants = {
  age: 10,
};

const deploy = await EchoConfigurablesFactory.deploy(wallet, {
  configurableConstants,
});
const { contract } = await deploy.waitForResult();

const {
  value: [age, tag, grades, myStruct],
} = await contract.functions.echo_configurables().get();

// age got updated
console.log('age', age); // 10
// while the rest are default values
console.log('tag', tag); // 'fuel'
console.log('grades', grades); // [3, 4, 3, 2]
console.log('myStruct', myStruct); // { x: 1, y: 2, state: 'Pending' }
```

Please note that when assigning new values for a `Struct`, all properties of the `Struct` must be defined. Failing to do so will result in an error:

```
const invalidConfigurables = {
  my_struct: {
    x: 10,
  },
};
try {
  await EchoConfigurablesFactory.deploy(wallet, {
    configurableConstants: invalidConfigurables,
  });
} catch (e) {
  console.log('error', e);
  // error: Error setting configurable constants on contract:
  // Invalid struct MyStruct. Field "y" not present.
}
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/contract-balance.md.md

# Contract Balance

When working with contracts, it's crucial to be aware of the available contract balance of an asset while paying for costly operations. This guide will explain the `getBalance` method in the [Contract](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) class, which allows you to check a contract's available balance.

## The `getBalance` Method

The [`Contract.getBalance`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html#getBalance) method retrieves the available balance of a specific asset on your contract. This method is particularly useful for determining the remaining balance after sending assets to a contract and executing contract calls.

It is important to note that this method returns the total available contract balance, regardless of how often assets have been sent to it or spent.

## Checking Contract Balance

Consider a simple contract that transfers a specified amount of a given asset to an address:

```
contract;

use std::asset::transfer;

abi TransferToAddress {
    #[payable]
    fn transfer(amount_to_transfer: u64, asset_id: AssetId, recipient: b256);
}

impl TransferToAddress for Contract {
    #[payable]
    fn transfer(amount_to_transfer: u64, asset_id: AssetId, recipient: b256) {
        let recipient_address = Address::from(recipient);

        transfer(
            Identity::Address(recipient_address),
            asset_id,
            amount_to_transfer,
        );
    }
}
```

The `transfer` function has three parameters:

1. `amount_to_transfer`: The amount that is being transferred.

2. `asset`: The address of the deployed contract token.

3. `recipient`: The address of the receiver's wallet.

The `transfer` function calls the built-in Sway function `transfer_to_address`, which does precisely what the name suggests.

Let's execute this contract and use the `getBalance` method to validate the remaining asset amount the contract has left to spend.

```
import type { AssetId } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { TransferToAddressFactory } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const { waitForResult: waitForDeploy } =
  await TransferToAddressFactory.deploy(wallet);
const { contract } = await waitForDeploy();

const amountToForward = 40;
const amountToTransfer = 10;
const baseAssetId = await provider.getBaseAssetId();

const recipient = Wallet.generate({
  provider,
});

const asset: AssetId = {
  bits: baseAssetId,
};

const { waitForResult } = await contract.functions
  .transfer(amountToTransfer, asset, recipient.address.toB256())
  .callParams({
    forward: [amountToForward, baseAssetId],
  })
  .call();

await waitForResult();

const contractBalance = await contract.getBalance(baseAssetId);
console.log(
  'contract balance reduced by amountToTransfer',
  contractBalance.toNumber() === amountToForward - amountToTransfer
);
```

In this example, we first forward an asset amount greater than the amount required for the transfer, and then we execute the contract call.

Finally, we use the `getBalance` method to confirm that the contract balance is precisely the total forwarded amount minus the transferred amount.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/custom-contract-calls.md.md

# Custom Contract Call

In certain scenarios, your use case may require more control over how contract calls are prepared and submitted.

For instance, imagine a liquidity pool contract where users can deposit a specific asset to receive some form of benefit. To enhance the experience and make it more attractive, one could use a predicate to cover the transaction fees. This way, users only need to provide the asset they wish to deposit without worrying about the fees.

There are two main ways to customize a contract call:

## Approach 1: Customize `assembleTx` Parameters

In most cases, this isn’t necessary. However, if you need precise control, you can specify the parameters passed to `assembleTx`, which is used internally to estimate and fund the transaction.

Here’s how it works:

```
// Create a new contract instance using the contract id
const liquidityPoolContract = new LiquidityPool(contractId, wallet);

// Execute the contract call manually specifying the assembleTx parameters
const { waitForResult } = await liquidityPoolContract.functions
  .deposit({ bits: wallet.address.toB256() })
  .callParams({
    forward: [1000, TestAssetId.A.value],
  })
  .assembleTxParams({
    feePayerAccount: predicate, // Using predicate as fee payer
    accountCoinQuantities: [
      {
        amount: 1000,
        assetId: TestAssetId.A.value,
        account: wallet,
        changeOutputAccount: wallet,
      },
    ],
  })
  .call();

const {
  transactionResult: { isStatusSuccess },
} = await waitForResult();
```

## Approach 2: Manually Call `assembleTx`

You can also retrieve the transaction request from the invocation scope and manually call `assembleTx` on it. Just like the approach 1 this gives you full control over how the transaction is assembled and funded.

```
// Create a new contract instance using the contract id
const liquidityPoolContract = new LiquidityPool(contractId, wallet);

// Create invocation scope to call the deposit function
const scope = liquidityPoolContract.functions
  .deposit({ bits: wallet.address.toB256() })
  .callParams({
    forward: [1000, TestAssetId.A.value],
  });

// Get the transaction request
const request = await scope.getTransactionRequest();

/**
 * Using "assembleTx" to estimate and fund the transaction.
 */
await provider.assembleTx({
  request,
  feePayerAccount: predicate, // Using predicate as fee payer
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: TestAssetId.A.value,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Use the "call" method to submit the transaction, skipping the "assembleTx" step
const response = await scope
  .fromRequest(request)
  .call({ skipAssembleTx: true });

const {
  transactionResult: { isStatusSuccess },
} = await response.waitForResult();
```

There are 2 details here that there are essential in this flow

1. `fromRequest`:
   This sets the transaction request extracted from the invocation scope. It ensures that any manual changes you’ve applied persist and are used when the transaction is executed.

1. `{ skipAssembleTx: true }` option:
   It tells the SDK to skip the automatic `assembleTx` step during the `.call()` execution, since we’ve already manually assembled and funded the transaction using `provider.assembleTx()`. Skipping this step prevents the SDK from re-estimating the transaction and ensures the custom logic remains intact, such as using a predicate as the fee payer.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/dependency-estimation.md.md

# Transaction Dependency Estimation

In [variable outputs](./variable-outputs.md), we mention that a contract call might require you to manually specify external contracts or variable outputs.

However, by default the SDK always automatically estimates these dependencies and double-checks if everything is in order whenever you invoke a contract function or attempt to send a transaction.

The SDK uses the [Provider.estimateTxDependencies](DOCS_API_URL/classes/_fuel_ts_account.Provider.html#estimateTxDependencies) method to set any missing dependencies identified during the estimation process. This requires simulating the transaction a few times in the background.

While relying on the SDK's automatic estimation is a decent default behavior, we recommend manually specifying the dependencies if they are known in advance to avoid the performance impact of the estimation process.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/deploying-contracts.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const indexUrl = `https://docs.fuel.network/docs/sway/introduction/`
  const jsonAbiUrl = `https://docs.fuel.network/docs/sway/introduction/sway_quickstart/`
</script>

# Deploying Contracts

To deploy a contract using the SDK, you can use the `ContractFactory`. This process involves collecting the contract artifacts, initializing the contract factory, and deploying the contract.

The SDK utilizes two different deployment processes, depending on the contract's size. The threshold for the contract size is dictated by the chain and can be queried:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const {
  consensusParameters: {
    contractParameters: { contractMaxSize },
  },
} = await provider.getChain();
```

It either uses a single create transaction to deploy the entire contract bytecode, or it splits the contract bytecode into multiple chunks, deploys them as blobs (on chain data accessible to the VM), and then generates a contract from the associated blob IDs. That generated contract is then deployed as a create transaction.

The `ContractFactory` offers the following methods for the different processes:

- `deploy` for deploying contacts of any size (will automatically choose the appropriate deployment process).
- `deployAsCreateTx` for deploying the entire contract bytecode in a single create transaction.
- `deployAsBlobTx` for deploying the contract in chunks as blobs, and then deploying the contract as a create transaction.

> **Note:** If the contract is deployed via blob deployments, multiple transactions will be required to deploy the contract.

## Deploying a Contract Guide

This guide will cover the process of deploying a contract using the `deploy` method, however all these methods can be used interchangeably dependent on the contract size. In the guide we use a contract factory that has been built using [Typegen](../fuels-cli/abi-typegen.md). This tool provided by the [Fuels CLI](../fuels-cli/index.md) provides a better developer experience and end to end type support for your smart contracts.

### 1. Setup

After writing a contract in Sway you can build the necessary deployment artifacts either by running `forc build` (<a :href="indexUrl" target="_blank" rel="noreferrer">read more</a> on how to work with Sway) or by using the [Fuels CLI](../fuels-cli/index.md) and running `fuels build` using your chosen package manager. We recommend using the Fuels CLI as it provides a more comprehensive usage including end to end type support.

Once you have the contract artifacts, it can be passed to the `ContractFactory` for deployment, like so:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { MyContractFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const factory = new MyContractFactory(wallet);
```

### 2. Contract Deployment

As mentioned earlier, there are two different processes for contract deployment handled by the `ContractFactory`. These can be used interchangeably, however, the `deploy` method is recommended as it will automatically choose the appropriate deployment process based on the contract size.

This call resolves as soon as the transaction to deploy the contract is submitted and returns three items: the `contractId`, a `waitForTransactionId` function and a `waitForResult` function.

```
// Deploy the contract
const { waitForResult, contractId, waitForTransactionId } =
  await factory.deploy();
// Retrieve the transactionId
const transactionId = await waitForTransactionId();
// Await it's deployment
const { contract, transactionResult } = await waitForResult();
```

The `contract` instance will be returned only after calling `waitForResult` and waiting for it to resolve. To avoid blocking the rest of your code, you can attach this promise to a hook or listener that will use the contract only after it is fully deployed. Similarly, the transaction ID is only available once the underlying transaction has been funded. To avoid blocking the code until the ID is ready, you can use the `waitForTransactionId` function to await it's retrieval.

### 3. Executing a Contract Call

Now that the contract is deployed, you can interact with it by submitting a contract call:

```
// Call the contract
const { waitForResult: waitForCallResult } = await contract.functions
  .test_function()
  .call();
// Await the result of the call
const { value } = await waitForCallResult();
```

## Deploying a Large Contract as Blobs

In the above guide we use the recommended `deploy` method. If you are working with a contract that is too large to be deployed in a single transaction, then the SDK will chunk the contract for you and submit it as blobs, to then be accessed later by a create transaction. This process is handled by the [`ContractFactory.deployAsBlobTx`](DOCS_API_URL/classes/_fuel_ts_contract.index.ContractFactory.html#deployAsBlobTx) method.

```
// Deploy the contract as blobs
const { waitForResult: waitForBlobsAndContractDeployment } =
  await factory.deployAsBlobTx({
    // setting chunk size multiplier to be 90% of the max chunk size
    chunkSizeMultiplier: 0.9,
  });

// Await its deployment
const { contract: contractFromBlobs } =
  await waitForBlobsAndContractDeployment();
```

In the above example, we also pass a `chunkSizeMultiplier` option to the deployment method. The SDK will attempt to chunk the contract to the most optimal about, however the transaction size can fluctuate and you can also be limited by request size limits against the node. By default we set a multiplier of 0.95, meaning the chunk size will be 95% of the potential maximum size, however you can adjust this to suit your needs and ensure the transaction passes. It must be set to a value between 0 and 1.

> **Note:** Deploying large contracts using blob transactions will take more time. Each transaction is dependent and has to wait for a block to be produced before it gets mined. Then a create transaction is submitted as normal. So you will need to wait longer than usual for the contract to be fully deployed and can be interacted with.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/index.md.md

# Contracts

In the Fuel Network, contracts play a crucial role in facilitating interactions between users and the decentralized applications built on top of the network. Once you've deployed a contract, you may want to perform various tasks such as:

1. Calling contract methods;
2. Configuring call and transaction parameters like gas price, byte price, and gas limit;
3. Forwarding coins and gas in your contract calls;
4. Reading and interpreting returned values and logs.

For instance, consider a Sway contract with two ABI methods called `echo_str_8(str[8])` and `echo_u8(u8)`. After deploying the contract, you can call the methods as follows:

```
const u8Value = 10;
const str8Value = 'fuel-sdk';

const res1 = await contract.functions.echo_u8(u8Value).simulate();
const res2 = await contract.functions.echo_str_8(str8Value).simulate();
```

The example above demonstrates a simple contract call using default configurations. The following sections will explore how to further configure various parameters for contract calls, allowing for more advanced interactions with your deployed contracts in the Fuel Network.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/inter-contract-calls.md.md

# Inter-Contract Calls with the SDK

This guide explains how to use the SDK to execute a contract call where one contract interacts with another contract. We will use a simple scenario involving a `SimpleToken` contract and a `TokenDepositor` contract.

## `SimpleToken` and `TokenDepositor` Contracts

In this example, we have a `SimpleToken` contract representing a basic token contract capable of holding balances for different addresses. We also have a `TokenDepositor` contract that deposits tokens into the `SimpleToken` contract.

### Contract: `SimpleToken`

Here's a simple token contract that allows holding balances:

```
contract;

use std::hash::*;
use simple_token_abi::SimpleToken;

storage {
    balances: StorageMap<b256, u64> = StorageMap {},
}

impl SimpleToken for Contract {
    #[storage(read, write)]
    fn deposit(address: b256, amount: u64) {
        let current_balance = storage.balances.get(address).try_read().unwrap_or(0);
        storage.balances.insert(address, current_balance + amount);
    }
    #[storage(read)]
    fn get_balance(address: b256) -> u64 {
        let balance = storage.balances.get(address).try_read().unwrap_or(0);
        balance
    }
}
```

### Contract: `TokenDepositor`

The `TokenDepositor` contract imports the `SimpleToken` contract and calls its `deposit` function to deposit tokens:

```
contract;

use std::auth::msg_sender;

use simple_token_abi::SimpleToken;

abi TokenDepositor {
    fn deposit_to_simple_token(contract_id: b256, amount: u64);
}

impl TokenDepositor for Contract {
    fn deposit_to_simple_token(contract_id: b256, amount: u64) {
        let simple_token_contract = abi(SimpleToken, contract_id);

        let sender = msg_sender().unwrap();

        let address: b256 = match sender {
            Identity::Address(sender_param) => sender_param.bits(),
            _ => revert(0),
        };

        simple_token_contract.deposit(address, amount);
    }
}
```

## Inter-contract calls using the SDK

Once both contracts are deployed, we can use the SDK to make the `TokenDepositor` contract to call the `SimpleToken` contract.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { SimpleTokenFactory, TokenDepositorFactory } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const { waitForResult: waitForSimpleToken } =
  await SimpleTokenFactory.deploy(wallet);

const { contract: simpleToken } = await waitForSimpleToken();

const { waitForResult: waitForTokenDepositor } =
  await TokenDepositorFactory.deploy(wallet);

const { contract: tokenDepositor } = await waitForTokenDepositor();

const amountToDeposit = 70;
const call1 = await simpleToken.functions
  .get_balance(wallet.address.toB256())
  .call();

const { value: initialBalance } = await call1.waitForResult();

const call2 = await tokenDepositor.functions
  .deposit_to_simple_token(simpleToken.id.toB256(), amountToDeposit)
  .addContracts([simpleToken])
  .call();

await call2.waitForResult();

const call3 = await simpleToken.functions
  .get_balance(wallet.address.toB256())
  .call();

const { value: finalBalance } = await call3.waitForResult();
```

Pay attention to the method `addContracts` called by the `TokenDepositor` contract. This method accepts an array of instances of deployed contracts. Without calling this method, the inter-contract call will not work.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/logs.md.md

# Working with Contract Logs

When you log a value within a contract method, you can generate a log entry that is added to the log receipt, and the variable type is recorded in the contract's ABI. The SDK enables you to parse these values into TypeScript types.

## Simple Logs

Consider the following example contract:

```
contract;

use log_simple_abi::LogSimple;

impl LogSimple for Contract {
    fn log_simple(val: str[9]) {
        log(val);
    }
}
```

To access the logged values in TypeScript, use the `logs` (typed as `Array<any>`) property from the response of a contract call.

```
const deploy = await LogSimpleFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const { waitForResult } = await contract.functions
  .log_simple('ContractA')
  .call();

const { logs } = await waitForResult();
// logs = [
//   'ContractA'
// ]
```

## Grouped Logs

We also provide a `groupedLogs` property that groups the logs by their program identifier. This is particularly useful when working with inter-contract or multi-calls.

We will use the same [`LogSimple`](#simple-logs) contract as in the previous example.

### Multi-call

We can make a multi-call to the contract

```
const deploy = await LogSimpleFactory.deploy(wallet);
const { contract: contractA } = await deploy.waitForResult();

const { waitForResult } = await contractA
  .multiCall([
    contractA.functions.log_simple('Contract1'),
    contractA.functions.log_simple('Contract2'),
  ])
  .call();

const { groupedLogs } = await waitForResult();
// groupedLogs = {
//   [contractA.id.toB256()]: ["Contract1", "Contract2"]
// }
```

### Inter-contract

Consider the following example contract:

In this example, we are making a call an inter-contract call to the [`LogSimple`](#simple-logs) contract from the previous example.

```
contract;

// Interface from the `LogSimple` contract
abi LogSimple {
    fn log_simple(val: str[9]);
}

// Interface for the contract
abi LogInterCalls {
    fn log_inter_call(contract_id: b256, simple_log_message: str[9]);
}

impl LogInterCalls for Contract {
    fn log_inter_call(contract_id: b256, simple_log_message: str[9]) {
        log("Starting inter-call");

        let logger = abi(LogSimple, contract_id);
        logger.log_simple(simple_log_message);

        log("Inter-call completed");
    }
}
```

The `log_inter_call` function makes a call to the `log_simple` function of the [`LogSimple`](#simple-logs) contract.

```
// First we make a simple contract that logs a value
const deploySimpleContract = await LogSimpleFactory.deploy(wallet);
const { contract: simpleContract } = await deploySimpleContract.waitForResult();

// Then we make an inter-contract that makes a multi-call to the simple contract
const deployInterContract = await LogInterCallsFactory.deploy(wallet);
const { contract: interContract } = await deployInterContract.waitForResult();

// We can then call the inter-contract function that makes call out to the simple contract
const { waitForResult } = await interContract.functions
  .log_inter_call(simpleContract.id.toB256(), 'ContractB')
  .call();

// We can then wait for the result and get the grouped logs
const { groupedLogs } = await waitForResult();
// groupedLogs = {
//   [simpleContract.id.toB256()]: ['ContractB'],
//   [interContract.id.toB256()]: ['Starting inter-call', 'Inter-call completed'],
// };
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/managing-deployed-contracts.md.md

# Managing Deployed Contracts

To interact with a deployed contract using the SDK without redeploying it, you only need the contract ID and its JSON ABI. This allows you to bypass the deployment setup.

## Contract ID

The `contractId` property from the [`Contract`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) class is an instance of the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class.

The [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class also provides a set of utility functions for easy manipulation and conversion between address formats along with one property; `b256Address`, which is a string encoded in [`B256`](../types/b256.md) format.

When you log the `contractId` property of an instantiated Contract using `console.log`, the output appears as follows:

```console
  Address {
    b256Address: '0xcd16d97c5c4e18ee2e8d6428447dd9c8763cb0336718b53652d049f8ec88b3ba'
  }
```

---

If you have already an instantiated and deployed contract in hands you can create another contract instance simply by using the `contractId` property and the contract JSON ABI:

```
const deployedEchoContract = new Contract(contractId, abi, wallet);

const { value: echoed10 } = await deployedEchoContract.functions
  .echo_u8(10)
  .simulate();
// value 10
```

The previous example assumes that you have a [`Contract`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) instance at hand. However, some Fuel tools and Sway use the [`B256`](../types/b256.md) type format, a hex-encoded string-like type, for contract IDs.

You might have this format instead, for example, if you have deployed your contract with `forc deploy`.

The process of instantiating a [`Contract`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) remains the same when using a contract ID of type `B256`:

```
const contract = new Contract(b256, abi, wallet);

const { value: echoed50 } = await contract.functions.echo_u8(50).simulate();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/methods.md.md

# Interacting With Contracts

There are 4 ways to interact with contracts: `get`, `dryRun`, `simulate`, `call`.

## `get`

The `get` method should be used to read data from the blockchain without using resources. It can be used with an unfunded wallet or even without a wallet at all:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Read from the blockchain
const { value } = await contract.functions.get_count().get();
// 0
```

## `dryRun`

The `dryRun` method should be used to dry-run a contract call. It does not spend resources and can be used with an unfunded wallet or even without a wallet at all:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Perform a dry-run of the transaction
const { value } = await contract.functions.increment_count(1).dryRun();
```

## `simulate`

The `simulate` method should be used to dry-run a contract call, ensuring that the wallet used has sufficient funds to cover the transaction fees, without consuming any resources.

A funded wallet it's required:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Simulate the transaction
const { value } = await contract.functions.increment_count(10).simulate();
```

## `call`

The `call` method submits a real contract call transaction to the node, resolving immediately upon submission and returning a `transactionId` along with a `waitForResult` callback to wait for transaction execution. This behavior aligns with the natural behaviour of blockchains, where transactions may take a few seconds before being recorded on the chain.

Real resources are consumed, and any operations executed by the contract function will be processed on the blockchain.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Perform the transaction
const { waitForResult } = await contract.functions.increment_count(10).call();

const { value } = await waitForResult();
```

## `isReadOnly` (utility)

If you want to figure out whether a function is read-only, you can use the `isReadOnly` method:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const isReadOnly = contract.functions.get_count.isReadOnly();

if (isReadOnly) {
  await contract.functions.get_count().get();
} else {
  const { waitForResult } = await contract.functions.get_count().call();
  await waitForResult();
}
```

If the function is read-only, you can use the `get` method to retrieve onchain data without spending gas.

If the function is not read-only you will have to use the `call` method to submit a transaction onchain which incurs a gas fee.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/minted-token-asset-id.md.md

# Minted Token Asset ID

The asset ID of a token on the Fuel network is determined by two factors:

- The ID of the contract that minted the token,
- A sub-identifier (Sub ID)

> Both of which are [B256](../types/b256.md) strings.

The process involves applying a SHA-256 hash algorithm to the combination of the Contract ID and the Sub ID, to derive an Asset ID - as explained [here](https://docs.fuel.network/docs/specs/identifiers/asset/#asset-id).

Consider the following simplified token contract:

```
contract;

use std::asset::{burn, mint, transfer};

abi Token {
    fn transfer_to_address(target: Address, asset_id: AssetId, coins: u64);
    fn transfer_to_contract(recipient: ContractId, asset_id: AssetId, coins: u64);
    fn mint_coins(sub_id: b256, mint_amount: u64);
    fn burn_coins(sub_id: b256, burn_amount: u64);
}

impl Token for Contract {
    // #region variable-outputs-1
    fn transfer_to_address(recipient: Address, asset_id: AssetId, amount: u64) {
        transfer(Identity::Address(recipient), asset_id, amount);
    }

    fn transfer_to_contract(target: ContractId, asset_id: AssetId, amount: u64) {
        transfer(Identity::ContractId(target), asset_id, amount);
    }
    // #endregion variable-outputs-1
    fn mint_coins(sub_id: b256, mint_amount: u64) {
        mint(sub_id, mint_amount);
    }

    fn burn_coins(sub_id: b256, burn_amount: u64) {
        burn(sub_id, burn_amount);
    }
}
```

Imagine that this contract is already deployed and we are about to mint some coins:

```
import { bn, getMintedAssetId, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { TokenFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await TokenFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Any valid B256 string can be used as a sub ID
const subID =
  '0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745';
const mintAmount = bn(1000);

const { waitForResult } = await contract.functions
  .mint_coins(subID, mintAmount)
  .call();
await waitForResult();

// Get the minted
const mintedAssetId = getMintedAssetId(contract.id.toB256(), subID);
```

## Obtaining the Asset ID

Since the asset ID depends on the contract ID, which is always dynamic (unlike the sub ID, which can be set to a fixed value), the helper `getMintedAssetId` can be used to easily obtain the asset ID for a given contract ID and sub ID.

## Create Asset Id

The SDK provides a helper named `createAssetId` which takes the contract ID and sub ID as parameters. This helper internally calls `getMintedAssetId` and returns the Sway native parameter [AssetId](DOCS_API_URL/types/_fuel_ts_address.AssetId.html), ready to be used in a Sway program invocation:

```
import type { AssetId, B256Address } from 'fuels';
import { createAssetId } from 'fuels';

const contractId: B256Address =
  '0x67eb6a384151a30e162c26d2f3e81ca2023dfa1041000210caed42ead32d63c0';
const subID: B256Address =
  '0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745';

const assetId: AssetId = createAssetId(contractId, subID);
// {
//   bits: '0x16c1cb95e999d0c74806f97643af158e821a0063a0c8ea61183bad2497b57478'
// }
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/multi-contract-calls.md.md

# Multiple Contract Calls

<!-- This section should explain making multiple contract calls -->
<!-- calls:example:start -->

You can execute multiple contract calls in a single transaction, either to the same contract or to different contracts. This can improve efficiency and reduce the overall transaction costs.

<!-- calls:example:end -->

## Same Contract Multi Calls

<!-- This section should explain how make multiple calls with the SDK -->
<!-- multicall:example:start -->

Use the `multiCall` method to call multiple functions on the same contract in a single transaction:

<!-- multicall:example:end -->

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractTx = await CounterFactory.deploy(deployer);
const { contract: counterContract } = await counterContractTx.waitForResult();

const { waitForResult } = await counterContract
  .multiCall([
    counterContract.functions.get_count(),
    counterContract.functions.increment_count(2),
    counterContract.functions.increment_count(4),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == 0
// results[1] == 2
// results[2] == 6
```

## Different Contracts Multi Calls

The `multiCall` method also allows you to execute multiple contract calls to distinct contracts within a single transaction:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory, EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractTx = await CounterFactory.deploy(deployer);
const { contract: counterContract } = await counterContractTx.waitForResult();
const echoContractTx = await EchoValuesFactory.deploy(deployer);
const { contract: echoContract } = await echoContractTx.waitForResult();

const { waitForResult } = await echoContract
  .multiCall([
    echoContract.functions.echo_u8(17),
    counterContract.functions.get_count(),
    counterContract.functions.increment_count(5),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == 17
// results[1] == BN <0>
// results[2] == BN <5>
```

You can also chain supported contract call methods, like `callParams`, for each contract call:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoValuesFactory, ReturnContextFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const echoContractTx = await EchoValuesFactory.deploy(deployer);
const { contract: echoContract } = await echoContractTx.waitForResult();
const returnContextTx = await ReturnContextFactory.deploy(deployer);
const { contract: returnContextContract } =
  await returnContextTx.waitForResult();

const { waitForResult } = await echoContract
  .multiCall([
    echoContract.functions.echo_u8(10),
    returnContextContract.functions.return_context_amount().callParams({
      forward: [100, await provider.getBaseAssetId()],
    }),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == 10
// results[1] == BN <100>
```

When using `multiCall`, the contract calls are queued and executed only after invoking one of the following methods: `.get`, `.simulate`, or `.call`.

## Using `multiCall` for Read-Only Contract Calls

When you need to read data from multiple contracts, the `multiCall` method can perform multiple [read-only](./methods.md#get) calls in a single transaction. This minimizes the number of requests sent to the network and consolidates data retrieval, making your dApp interactions more efficient.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory, EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractTx = await CounterFactory.deploy(deployer);
const { contract: counterContract } = await counterContractTx.waitForResult();
const echoContractTx = await EchoValuesFactory.deploy(deployer);
const { contract: echoContract } = await echoContractTx.waitForResult();

const { waitForResult } = await echoContract
  .multiCall([
    counterContract.functions.get_count(),
    echoContract.functions.echo_u8(10),
    echoContract.functions.echo_str('Fuel'),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == BN <0>
// results[1] == 10
// results[2] == 'Fuel'
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/proxy-contracts.md.md

# Proxy Contracts

Automatic deployment of proxy contracts can be enabled in `Forc.toml`.

We recommend that you use [fuels deploy](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-deploy) to deploy and upgrade your contract using a proxy as it will take care of everything for you. However, if you want to deploy a proxy contract manually, you can follow the guide below.

## Manually Deploying and Upgrading by Proxy

As mentioned above, we recommend using [fuels deploy](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-deploy) to deploy and upgrade your contract because it will handle everything automatically. However, the guide below will explain this process in detail if you want to implement it yourself.

We recommend using the [SRC14 compliant owned proxy contract](https://github.com/FuelLabs/sway-standard-implementations/tree/174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb/src14/owned_proxy/contract/out/release) as the underlying proxy as that is the one we will use in this guide and the one used by [fuels deploy](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-deploy). A TypeScript implementation of this proxy is exported from the `fuels` package as `Src14OwnedProxy` and `Src14OwnedProxyFactory`.

The overall process is as follows:

1. Deploy your contract
1. Deploy the proxy contract
1. Set the target of the proxy contract to your deployed contract
1. Make calls to the contract via the proxy contract ID
1. Upgrade the contract by deploying a new version of the contract and updating the target of the proxy contract

> **Note**: When new storage slots are added to the contract, they must be initialized in the proxy contract before they can be read from. This can be done by first writing to the new storage slot in the proxy contract. Failure to do so will result in the transaction being reverted.

For example, lets imagine we want to deploy the following counter contract:

```
contract;

abi Counter {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64;

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
}

impl Counter for Contract {
    #[storage(read)]
    fn get_count() -> u64 {
        storage.counter.try_read().unwrap_or(0)
    }

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current + amount);
        storage.counter.read()
    }

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current - amount);
        storage.counter.read()
    }
}
```

Let's deploy and interact with it by proxy. First let's setup the environment and deploy the counter contract:

```
import {
  Provider,
  Wallet,
  Src14OwnedProxy,
  Src14OwnedProxyFactory,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import {
  Counter,
  CounterFactory,
  CounterV2,
  CounterV2Factory,
} from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractFactory = new CounterFactory(wallet);
const deploy = await counterContractFactory.deploy();
const { contract: counterContract } = await deploy.waitForResult();
```

Now let's deploy the [SRC14 compliant proxy contract](https://github.com/FuelLabs/sway-standard-implementations/tree/174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb/src14/owned_proxy/contract/out/release) and initialize it by setting its target to the counter target ID.

```
/**
 * It is important to pass all storage slots to the proxy in order to
 * initialize the storage slots.
 */
const storageSlots = counterContractFactory.storageSlots.concat(
  Src14OwnedProxy.storageSlots
);
/**
 * These configurables are specific to our recommended SRC14 compliant
 * contract. They must be passed on deployment and then `initialize_proxy`
 * must be called to setup the proxy contract.
 */
const configurableConstants = {
  INITIAL_TARGET: { bits: counterContract.id.toB256() },
  INITIAL_OWNER: {
    Initialized: { Address: { bits: wallet.address.toB256() } },
  },
};

const proxyContractFactory = new Src14OwnedProxyFactory(wallet);
const proxyDeploy = await proxyContractFactory.deploy({
  storageSlots,
  configurableConstants,
});

const { contract: proxyContract } = await proxyDeploy.waitForResult();
const { waitForResult } = await proxyContract.functions
  .initialize_proxy()
  .call();

await waitForResult();
```

Finally, we can call our counter contract using the contract ID of the proxy.

```
/**
 * Make sure to use only the contract ID of the proxy when instantiating
 * the contract as this will remain static even with future upgrades.
 */
const proxiedContract = new Counter(proxyContract.id, wallet);

const incrementCall = await proxiedContract.functions.increment_count(1).call();
await incrementCall.waitForResult();

const { value: count } = await proxiedContract.functions.get_count().get();
```

Now let's make some changes to our initial counter contract by adding an additional storage slot to track the number of increments and a new get method that retrieves its value:

```
contract;

abi Counter {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(read)]
    fn get_increments() -> u64;

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64;

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
    increments: u64 = 0,
}

impl Counter for Contract {
    #[storage(read)]
    fn get_count() -> u64 {
        storage.counter.try_read().unwrap_or(0)
    }

    #[storage(read)]
    fn get_increments() -> u64 {
        storage.increments.try_read().unwrap_or(0)
    }

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current + amount);

        let current_iteration: u64 = storage.increments.try_read().unwrap_or(0);
        storage.increments.write(current_iteration + 1);

        storage.counter.read()
    }

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current - amount);
        storage.counter.read()
    }
}
```

We can deploy it and update the target of the proxy like so:

```
const deployV2 = await CounterV2Factory.deploy(wallet);
const { contract: contractV2 } = await deployV2.waitForResult();

const updateTargetCall = await proxyContract.functions
  .set_proxy_target({ bits: contractV2.id.toB256() })
  .call();

await updateTargetCall.waitForResult();
```

Then, we can instantiate our upgraded contract via the same proxy contract ID:

```
/**
 * Again, we are instantiating the contract with the same proxy ID
 * but using a new contract instance.
 */
const upgradedContract = new CounterV2(proxyContract.id, wallet);

const incrementCall2 = await upgradedContract.functions
  .increment_count(1)
  .call();

await incrementCall2.waitForResult();

const { value: increments } = await upgradedContract.functions
  .get_increments()
  .get();

const { value: count2 } = await upgradedContract.functions.get_count().get();
```

For more info, please check these docs:

- [Proxy Contracts](https://docs.fuel.network/docs/forc/plugins/forc_client/#proxy-contracts)
- [Sway Libs / Upgradability Library](https://docs.fuel.network/docs/sway-libs/upgradability/#upgradability-library)
- [Sway Standards / SRC-14 - Simple Upgradable Proxies](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/#src-14-simple-upgradeable-proxies)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/storage-slots.md.md

# Storage Slots

When deploying a contract, you can specify the custom storage slots that you want to use.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import {
  StorageTestContract,
  StorageTestContractFactory,
} from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploymentTx = await StorageTestContractFactory.deploy(deployer, {
  storageSlots: StorageTestContract.storageSlots,
});

await deploymentTx.waitForResult();
```

## Using plain JavaScript

In the above example, we directly imported the storage slots from a JSON file generated by the Sway compiler.

Instead of importing from a file, you can also specify the custom storage slots directly in your code:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { StorageTestContractFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploymentTx = await StorageTestContractFactory.deploy(deployer, {
  storageSlots: [
    {
      key: '02dac99c283f16bc91b74f6942db7f012699a2ad51272b15207b9cc14a70dbae',
      value: '0000000000000001000000000000000000000000000000000000000000000000',
    },
    {
      key: '6294951dcb0a9111a517be5cf4785670ff4e166fb5ab9c33b17e6881b48e964f',
      value: '0000000000000001000000000000003200000000000000000000000000000000',
    },
    {
      key: 'b48b753af346966d0d169c0b2e3234611f65d5cfdb57c7b6e7cd6ca93707bee0',
      value: '000000000000001e000000000000000000000000000000000000000000000000',
    },
    {
      key: 'de9090cb50e71c2588c773487d1da7066d0c719849a7e58dc8b6397a25c567c0',
      value: '0000000000000014000000000000000000000000000000000000000000000000',
    },
    {
      key: 'f383b0ce51358be57daa3b725fe44acdb2d880604e367199080b4379c41bb6ed',
      value: '000000000000000a000000000000000000000000000000000000000000000000',
    },
  ],
});

await deploymentTx.waitForResult();
```

## Auto-load of Storage Slots

Code generated using [Typegen](../fuels-cli/generating-types.md) automatically [load](../fuels-cli/using-generated-types.md#autoloading-of-storage-slots) Storage Slots for you.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/transferring-assets.md.md

# Transferring assets

Consider a scenario where you're interacting with a smart contract and need to transfer assets to a recipient's wallet. The `addTransfer` enables you to combine these actions into a single transaction seamlessly.

The `addTransfer` method allows you to append an asset transfer to your contract call transaction. You can use it is shown in the following example:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await EchoValuesFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const recipient = Wallet.generate({ provider });

const { waitForResult } = await contract.functions
  .echo_u64(100)
  .addTransfer({
    destination: recipient.address,
    amount: 100,
    assetId: await provider.getBaseAssetId(),
  })
  .call();

await waitForResult();
```

In the previous example, we first use a contract call to the `echo_u64` function. Following this, `addTransfer` is added to chain call to include a transfer of `100` units of the `BaseAssetId` in the transaction.

## Batch Transfer

You can add a batch of transfers into a single transaction by using `addBatchTransfer`:

```
import type { TransferParams } from 'fuels';
import { Provider, Wallet } from 'fuels';
import { ASSET_A, ASSET_B } from 'fuels/test-utils';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await EchoValuesFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const recipient1 = Wallet.generate({ provider });
const recipient2 = Wallet.generate({ provider });

const transferParams: TransferParams[] = [
  {
    destination: recipient1.address,
    amount: 100,
    assetId: await provider.getBaseAssetId(),
  },
  { destination: recipient1.address, amount: 400, assetId: ASSET_A },
  { destination: recipient2.address, amount: 300, assetId: ASSET_B },
];

const { waitForResult } = await contract.functions
  .echo_u64(100)
  .addBatchTransfer(transferParams)
  .call();

await waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/understanding-the-fuelvm-binary-file.md.md

# Understanding the FuelVM Binary File

When you compile your Sway code using the `forc build` command, it generates a bytecode file. This binary file contains the compiled code that the Fuel Virtual Machine (FuelVM) will interpret and execute.

For example, consider the following smart contract:

```
contract;

use std::b512::B512;

abi EchoValues {
    fn echo_u8(value: u8) -> u8;

    fn echo_str_8(value: str[8]) -> str[8];

    fn echo_str(value: str) -> str;

    fn echo_tuple(tuple: (u8, bool, u64)) -> (u8, bool, u64);

    fn echo_b512(input: B512) -> B512;

    fn echo_u64(value: u64) -> u64;

    fn echo_u64_array(u64_array: [u64; 2]) -> [u64; 2];
}

impl EchoValues for Contract {
    fn echo_u8(value: u8) -> u8 {
        value
    }

    fn echo_str(value: str) -> str {
        value
    }

    fn echo_str_8(value: str[8]) -> str[8] {
        value
    }

    // #region tuples-2
    fn echo_tuple(tuple: (u8, bool, u64)) -> (u8, bool, u64) {
        tuple
    }
    // #endregion tuples-2

    // #region b512-3
    fn echo_b512(input: B512) -> B512 {
        input
    }
    // #endregion b512-3
    fn echo_u64(value: u64) -> u64 {
        value
    }

    // #region arrays-2
    fn echo_u64_array(u64_array: [u64; 2]) -> [u64; 2] {
        u64_array
    }
    // #endregion arrays-2
}
```

After running `forc build`, a binary file will be generated with the following content:

```sh
$ cat out/debug/echo-values.bin
�GT]����]@`I]G�I@sH]G�I@sHr�{6�]D`J]C�%E]@`J$@Ͼ{RD�^�%
```

At first glance, the content appears unreadable. However, `forc` provides a helpful interpreter for this bytecode: the `forc parse-bytecode` command. This command takes the binary data and outputs the equivalent FuelVM assembly:

```sh
$ forc parse-bytecode out/debug/echo-values.bin
half-word   byte   op                raw           notes
        0   0      JI(4)             90 00 00 04   jump to byte 16
        1   4      NOOP              47 00 00 00
        2   8      Undefined         00 00 00 00   data section offset lo (0)
        3   12     Undefined         00 00 00 34   data section offset hi (52)
        4   16     LW(63, 12, 1)     5d fc c0 01
        5   20     ADD(63, 63, 12)   10 ff f3 00
        6   24     LW(17, 6, 73)     5d 44 60 49
        7   28     LW(16, 63, 1)     5d 43 f0 01
        8   32     EQ(16, 17, 16)    13 41 14 00
        9   36     JNZI(16, 11)      73 40 00 0b   conditionally jump to byte 44
       10   40     RVRT(0)           36 00 00 00
       11   44     LW(16, 63, 0)     5d 43 f0 00
       12   48     RET(16)           24 40 00 00
       13   52     Undefined         00 00 00 00
       14   56     Undefined         00 00 00 01
       15   60     Undefined         00 00 00 00
       16   64     XOR(20, 27, 53)   21 51 bd 4b
```

When deploying your smart contract using the SDK, the binary file plays a crucial role. It is sent to the FuelVM in a transaction, allowing the FuelVM to interpret and execute your smart contract.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/using-different-wallets.md.md

# Making Calls with Different Wallets or Providers

This guide demonstrates how to make contract calls using different wallets and providers by passing either an [`Account`](DOCS_API_URL/classes/_fuel_ts_account.Account.html) or a [`Provider`](DOCS_API_URL/classes/_fuel_ts_account.Provider.html) to the contract on instantiation.

## Changing Wallets

To change the wallet associated with a contract instance, assign a new wallet to the instance's `account` property. This allows you to make contract calls with different wallets in a concise manner:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnContextFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await ReturnContextFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Update the wallet
const newWallet = Wallet.generate({ provider });
contract.account = newWallet;
```

## Changing Providers

Similarly, you can assign a custom provider to a contract instance by modifying its provider property. This enables you to use a provider wrapper of your choice:

<!-- TODO: Replace with a proper snippet. We lost this snippet because this test had to be removed/changed -->

```ts
const newProvider = new Provider(NEW_URL);
deployedContract.provider = newProvider;
```

> **Note:** When connecting a different wallet to an existing contract instance, the provider used to deploy the contract takes precedence over the newly set provider. If you have two wallets connected to separate providers (each communicating with a different fuel-core instance), the provider assigned to the deploying wallet will be used for contract calls. This behavior is only relevant when multiple providers (i.e. fuel-core instances) are present and can be ignored otherwise.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/contracts/variable-outputs.md.md

# Variable Outputs

Sway includes robust functions for transferring assets to wallets and contracts.

When using these transfer functions within your Sway projects, it is important to be aware that each call will require an [Output Variable](https://docs.fuel.network/docs/specs/tx-format/output#outputvariable) within the [Outputs](https://docs.fuel.network/docs/specs/tx-format/output) of the transaction.

For instance, if a contract function calls a Sway transfer function 3 times, it will require 3 Output Variables present within the list of outputs in your transaction.

## Example: Sway functions that requires `Output Variable`

```
    fn transfer_to_address(recipient: Address, asset_id: AssetId, amount: u64) {
        transfer(Identity::Address(recipient), asset_id, amount);
    }

    fn transfer_to_contract(target: ContractId, asset_id: AssetId, amount: u64) {
        transfer(Identity::ContractId(target), asset_id, amount);
    }
```

## Adding Variable Outputs to the contract call

When your contract invokes any of these functions, or if it calls a function that leads to another contract invoking these functions, you need to add the appropriate number of Output Variables.

This can be done as shown in the following example:

```
import { Provider, Wallet, getMintedAssetId, getRandomB256 } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { TokenFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await TokenFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const subId = getRandomB256();

const call1 = await contract.functions.mint_coins(subId, 100).call();
await call1.waitForResult();

const address = { bits: Wallet.generate().address.toB256() };
const assetId = { bits: getMintedAssetId(contract.id.toB256(), subId) };

const { waitForResult } = await contract.functions
  .transfer_to_address(address, assetId, 100)
  .txParams({
    variableOutputs: 1,
  })
  .call();

await waitForResult();
```

In the TypeScript SDK, the Output Variables are automatically added to the transaction's list of outputs.

This process is done by a brute-force strategy, performing sequential dry runs until no errors are returned. This method identifies the number of Output Variables required to process the transaction.

However, this can significantly delay the transaction processing. Therefore, it is **highly recommended** to manually add the correct number of Output Variables before submitting the transaction.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/combining-utxos.md.md

# Combining UTXOs

When performing a funding operation or calling `getResourcesToSpend`, you may encounter the `INSUFFICIENT_FUNDS_OR_MAX_COINS` error if the number of coins fetched per asset exceeds the maximum limit allowed by the chain.

You may also want to do this if you want to reduce the number of inputs in your transaction, which can be useful if you are trying to reduce the size of your transaction or you are receiving the `MAX_INPUTS_EXCEEDED` error.

## Using the Account's `consolidateCoins` Method

The SDK provides a built-in method to consolidate your base asset UTXOs:

```
const baseAssetId = await provider.getBaseAssetId();

// By default, this will combine UTXOs into a single output (outputNum = 1)
const result = await wallet.consolidateCoins({
  assetId: baseAssetId,
  // Optional: 'parallel' (default) or 'sequential' execution mode
  mode: 'parallel',
  // Optional: number of output UTXOs to create (default is 1)
  outputNum: 1,
});

// Check the transaction results and any errors
console.log('Successful transactions:', result.txResponses);
console.log('Failed transactions:', result.errors);

// Verify the reduced number of UTXOs
const { coins: consolidatedCoins } = await wallet.getCoins(baseAssetId);
console.log('Consolidated Coins Length', consolidatedCoins.length);
```

### Configuration Options

The `consolidateCoins` method accepts the following parameters:

- `assetId`: The ID of the asset to consolidate

- `mode` (optional): How to submit consolidation transactions
  - `'parallel'` (default): Submit all transactions simultaneously for faster processing
  - `'sequential'`: Submit transactions one after another, waiting for each to complete
- `outputNum` (optional): Number of output UTXOs to create (default is 1)

## Max Inputs and Outputs

It's also important to note that depending on the chain configuration, you may be limited on the number of inputs and/or outputs that you can have in a transaction. These amounts can be queried via the [TxParameters](https://docs.fuel.network/docs/graphql/reference/objects/#txparameters) GraphQL query.

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const { maxInputs, maxOutputs } = (await provider.getChain())
  .consensusParameters.txParameters;
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/custom-transactions-from-contract-calls.md.md

# Custom Transactions From Contract Calls

In the previous example we demonstrated how you can instantiate a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html) to customize and build out a more complex transaction via a script. The same can be done using contracts, but this allows us to utilize functions available in the contract and access on-chain state. Allowing us to harness all of the power from an invocation scope and a transaction request.

This cookbook demonstrates how we can utilize a contract call to build out a custom transaction, allowing us to update on-chain state and transfer assets to a recipient address.

```
import { bn, buildFunctionResult, Contract, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CounterFactory } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const deploy = await CounterFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const receiverWallet = Wallet.generate({ provider });

const amountToRecipient = bn(10_000); // 0x2710
// Connect to the contract
const contractInstance = new Contract(contract.id, contract.interface, wallet);
// Create an invocation scope for the contract function you'd like to call in the transaction
const scope = contractInstance.functions.increment_count(amountToRecipient);

// Build a transaction request from the invocation scope
const request = await scope.getTransactionRequest();
// Add coin output for the recipient
request.addCoinOutput(receiverWallet.address, amountToRecipient, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: amountToRecipient,
      assetId: baseAssetId,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Submit the transaction
const response = await wallet.sendTransaction(assembledRequest);
await response.waitForResult();
// Get result of contract call
const { value } = await buildFunctionResult({
  funcScope: scope,
  isMultiCall: false,
  program: contract,
  transactionResponse: response,
});

console.log('value', value);
// <BN: 0x2710>
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/custom-transactions.md.md

# Custom Transactions

There may be scenarios where you need to build out transactions that involve multiple program types and assets; this can be done by instantiating a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html). This class allows you to a append multiple program types and assets to a single transaction.

Consider the following script that transfers multiple assets to a contract:

```
script;

use std::asset::transfer;

fn main(
    contract_address: b256,
    asset_a: AssetId,
    amount_asset_a: u64,
    asset_b: AssetId,
    amount_asset_b: u64,
) -> bool {
    let wrapped_contract = ContractId::from(contract_address);
    let contract_id = Identity::ContractId(wrapped_contract);
    transfer(contract_id, asset_a, amount_asset_a);
    transfer(contract_id, asset_b, amount_asset_b);
    true
}
```

This script can be executed by creating a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html), appending the resource and contract inputs/outputs and then sending the transaction, as follows:

```
// 1. Create a script transaction using the script binary
const request = new ScriptTransactionRequest({
  ...defaultTxParams,
  gasLimit: 3_000_000,
  script: ScriptTransferToContract.bytecode,
});

// 2. Instantiate the script main arguments
const scriptArguments = [
  contract.id.toB256(),
  { bits: ASSET_A },
  new BN(1000),
  { bits: ASSET_B },
  new BN(500),
];

// 3. Populate the script data and add the contract input and output
request
  .setData(ScriptTransferToContract.abi, scriptArguments)
  .addContractInputAndOutput(contract.id);

// 4. Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: ASSET_A,
      account: wallet,
      changeOutputAccount: wallet,
    },
    {
      amount: 500,
      assetId: ASSET_B,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// 5. Send the transaction
const tx = await wallet.sendTransaction(assembledRequest);
await tx.waitForResult();

const contractFinalBalanceAssetA = await contract.getBalance(ASSET_A);
const contractFinalBalanceAssetB = await contract.getBalance(ASSET_B);
```

## Full Example

For a full example, see below:

```
import { BN, ScriptTransactionRequest, coinQuantityfy } from 'fuels';
import { ASSET_A, ASSET_B, launchTestNode } from 'fuels/test-utils';

import { EchoValuesFactory } from '../../../typegend/contracts/EchoValuesFactory';
import { ScriptTransferToContract } from '../../../typegend/scripts/ScriptTransferToContract';

using launched = await launchTestNode({
  contractsConfigs: [{ factory: EchoValuesFactory }],
});
const {
  contracts: [contract],
  wallets: [wallet],
  provider,
} = launched;

const defaultTxParams = {
  gasLimit: 10000,
};

// #region custom-transactions-2

// 1. Create a script transaction using the script binary
const request = new ScriptTransactionRequest({
  ...defaultTxParams,
  gasLimit: 3_000_000,
  script: ScriptTransferToContract.bytecode,
});

// 2. Instantiate the script main arguments
const scriptArguments = [
  contract.id.toB256(),
  { bits: ASSET_A },
  new BN(1000),
  { bits: ASSET_B },
  new BN(500),
];

// 3. Populate the script data and add the contract input and output
request
  .setData(ScriptTransferToContract.abi, scriptArguments)
  .addContractInputAndOutput(contract.id);

// 4. Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: ASSET_A,
      account: wallet,
      changeOutputAccount: wallet,
    },
    {
      amount: 500,
      assetId: ASSET_B,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// 5. Send the transaction
const tx = await wallet.sendTransaction(assembledRequest);
await tx.waitForResult();

const contractFinalBalanceAssetA = await contract.getBalance(ASSET_A);
const contractFinalBalanceAssetB = await contract.getBalance(ASSET_B);
// #endregion custom-transactions-2
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/deposit-and-withdraw.md.md

# Deposit And Withdraw

Consider the following contract:

```
contract;

use std::{asset::{mint_to, transfer}, call_frames::msg_asset_id, context::msg_amount};
abi LiquidityPool {
    #[payable]
    fn deposit(recipient: Address);
    #[payable]
    fn withdraw(recipient: Address);
}
configurable {
    TOKEN: AssetId = AssetId::from(0x0000000000000000000000000000000000000000000000000000000000000000),
}
impl LiquidityPool for Contract {
    #[payable]
    fn deposit(recipient: Address) {
        assert(TOKEN == msg_asset_id());
        assert(0 < msg_amount());
        // Mint two times the amount.
        let amount_to_mint = msg_amount() * 2;
        // Mint some LP token based upon the amount of the base token.
        mint_to(Identity::Address(recipient), b256::zero(), amount_to_mint);
    }
    #[payable]
    fn withdraw(recipient: Address) {
        assert(0 < msg_amount());
        // Amount to withdraw.
        let amount_to_transfer = msg_amount() / 2;
        // Transfer base token to recipient.
        transfer(Identity::Address(recipient), TOKEN, amount_to_transfer);
    }
}
```

As the name implies, this contract represents a simplified version of a liquidity pool. The `deposit()` method allows you to supply an arbitrary amount of `BASE_TOKEN`. In response, it mints twice the amount of the liquidity asset to the caller's address. Similarly, the `withdraw()` method transfers half the amount of the `BASE_TOKEN` back to the caller's address.

Now, let's deposit some tokens into the liquidity pool contract. Since this requires forwarding assets to the contract, we need to pass the appropriate values to `callParams` when creating a contract call.

```
import { getMintedAssetId, Provider, Wallet, ZeroBytes32 } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { LiquidityPoolFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploy = await LiquidityPoolFactory.deploy(wallet, {
  configurableConstants: {
    TOKEN: { bits: await provider.getBaseAssetId() },
  },
});

const { contract } = await deploy.waitForResult();

const depositAmount = 100_000;
const liquidityOwner = Wallet.generate({ provider });

// the subId used to mint the new asset is a zero b256 on the contract
const subId = ZeroBytes32;
const contractId = contract.id.toB256();

const assetId = getMintedAssetId(contractId, subId);

const { waitForResult } = await contract.functions
  .deposit({ bits: liquidityOwner.address.toB256() })
  .callParams({ forward: [depositAmount, await provider.getBaseAssetId()] })
  .txParams({ variableOutputs: 1 })
  .call();

await waitForResult();

const liquidityAmount = await liquidityOwner.getBalance(assetId);
```

As a final demonstration, let's use all our liquidity asset balance to withdraw from the pool and confirm we retrieved the initial amount. For this, we get our liquidity asset balance and supply it to the `withdraw()` function via `callParams`.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { LiquidityPoolFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploy = await LiquidityPoolFactory.deploy(wallet, {
  configurableConstants: {
    TOKEN: { bits: await provider.getBaseAssetId() },
  },
});

const { contract } = await deploy.waitForResult();

const depositAmount = 100_000;
const liquidityOwner = Wallet.generate({ provider });

const { waitForResult } = await contract.functions
  .withdraw({ bits: liquidityOwner.address.toB256() })
  .callParams({ forward: [depositAmount, await provider.getBaseAssetId()] })
  .txParams({ variableOutputs: 1 })
  .call();

await waitForResult();

const baseAssetAfterWithdraw = await liquidityOwner.getBalance(
  await provider.getBaseAssetId()
);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/generate-fake-resources.md.md

# Generate Fake Resources

When working with an unfunded account, you can generate fake resources to perform a dry-run on your transactions. This is useful for testing purposes without the need for real funds.

Below is an example script that returns the value `1337`. You can use fake resources to execute a dry-run of this script and obtain the returned value.

```
script;

fn main() -> u64 {
    return 1337;
}
```

To execute a dry-run, use the `Provider.dryRun` method. Ensure you set the `utxo_validation` flag to true, as this script uses fake UTXOs:

```
import type { TransactionResultReturnDataReceipt } from 'fuels';
import {
  bn,
  Provider,
  ReceiptType,
  ScriptTransactionRequest,
  Wallet,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ReturnScript } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const baseAssetId = await provider.getBaseAssetId();

const transactionRequest = new ScriptTransactionRequest({
  gasLimit: bn(62_000),
  maxFee: bn(60_000),
  script: ReturnScript.bytecode,
});

const resources = wallet.generateFakeResources([
  {
    amount: bn(100_000),
    assetId: baseAssetId,
  },
]);

transactionRequest.addResources(resources);

const dryrunResult = await provider.dryRun(transactionRequest);

const returnReceipt = dryrunResult.receipts.find(
  (receipt) => receipt.type === ReceiptType.ReturnData
) as TransactionResultReturnDataReceipt;

const { data: returnedValue } = returnReceipt;
```

By setting `utxo_validation` to `true`, you can successfully execute the dry-run and retrieve the returned value from the script without requiring actual funds.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/graphql-integration.md.md

# GraphQL Integration

The Fuel Network provides a [GraphQL API](https://docs.fuel.network/docs/graphql/overview/) to query the blockchain. To get a better understanding of the underlying schema and other operations, you can visit the [playground](https://testnet.fuel.network/v1/playground) for an interactive deep dive.

## Operations

For its own purposes, the SDK creates custom operations based off of the API's schema and auto-generates TypeScript client code via codegen tools.
The end result of this code generation are the operations available on the [`Provider`](../provider/index.md), of which some are shown below:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// Create the provider
const provider = new Provider(LOCAL_NETWORK_URL);

const chain = await provider.operations.getChain();
const nodeInfo = await provider.operations.getNodeInfo();
```

Note that these operations primarily serve the needs of the SDK and the `Provider`'s methods which can encapsulate calls to multiple operations, parse the responses, etc.

If your querying needs exceed what the `Provider` provides, we suggest you follow this same process and write your own custom query operations, e.g.:

```gql
query getChain {
  latestBlock {
    transactions {
      id
    }
  }
}
```

### Mutations and subscriptions

For mutations and subscriptions, we strongly suggest that you communicate with the node via the `Provider` and do not write your own custom GraphQL operations because, in its methods, the `Provider` does additional processing before and after sending them to the node which might require detailed knowledge of various Fuel domain-specific topics.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/index.md.md

# Cookbook

This section covers more advanced use cases that can be satisfied by combining various features of the SDK. As such, it assumes that you have already made yourself familiar with the previous chapters of this book.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/optimized-react-example.md.md

# Optimized React Example

This example implements the strategies outlined in [Optimizing Frontend Apps](../transactions/optimizing-frontend-apps.md) and demonstrates how to improve the perceived speed of transactions in a React application.

```tsx
import { Provider, Wallet, ScriptTransactionRequest } from "fuels";
import { useEffect, useState } from "react";

import { TestContract } from "./typegend";
import contractIds from "./typegend/contract-ids.json";

function App() {
  const [request, setRequest] = useState<ScriptTransactionRequest | null>(null);

  // Initialize the provider and wallet
  const NETWORK_URL = "https://mainnet.fuel.network/v1/graphql";
  const provider = new Provider(NETWORK_URL);
  const wallet = Wallet.fromAddress("0x...", provider);

  /**
   * Here we'll prepare our transaction upfront on page load, so that
   * by the time the user interacts with your app (i.e. clicking a btn),
   * the transaction is ready to be submitted
   */
  useEffect(() => {
    const onPageLoad = async () => {
      // 1. Connect to the contract
      const contractInstance = new TestContract(
        contractIds.testContract,
        wallet,
      );

      // 2. Invoke the contract function whilst estimating and funding the
      // call, which gives us the transaction request
      const preparedRequest = await contractInstance.functions
        .increment_counter(1)
        .fundWithRequiredCoins();

      setRequest(preparedRequest);
    };

    onPageLoad();
  }, []);

  /**
   * By the time user user clicks the submit button, we only need to
   * submit the transaction to the network
   */
  const handleSubmit = async () => {
    if (!request) return;

    // 1. Submit the transaction to the network
    const response = await wallet.sendTransaction(request);

    // 2. Wait for the transaction to settle and get the result
    const result = await response.waitForResult();

    console.log("result", result);
  };

  return (
    <div>
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );
}

export default App;
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/resubmitting-failed-transactions.md.md

# Resubmitting Failed Transactions

In certain scenarios, you might need to implement a solution to resubmit failed transactions to the Fuel Network. While this approach can be effective, there are important considerations to remember.

## Submission and Processing

When submitting a transaction, you will first get a response.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const baseAssetId = await provider.getBaseAssetId();

const transferAmount = 1000;

const transactionRequest = await wallet.createTransfer(
  wallet.address,
  transferAmount,
  baseAssetId
);

const response = await wallet.sendTransaction(transactionRequest);
```

If the `sendTransaction` method resolves without an error, we know that the transaction was successfully submitted and accepted by the network. However, this does not guarantee that the transaction has been processed; it only indicates that the transaction has been accepted and placed in a queue for processing.

To determine whether the transaction has been processed, you must call `waitForResult`, which will either resolve (with the processed transaction) or reject with an error.

```
const result = await response.waitForResult();
```

In other words:

- If `sendTransaction` is rejected with an error, the transaction was not accepted by the network and is not processed.
- If `waitForResult` is rejected with an error, the transaction was accepted but reverted during processing.

## Resources Spent When a Transaction Is Processed

If a transaction is reverted during processing, the Fuel VM will still consume the funded resources to cover the gas used up to the point of failure. After deducting the gas cost, the remaining funds will be added to a new UTXO (Unspent Transaction Output) addressed to the owner.

Attempting to resubmit the same transaction request that failed during processing will likely result in an error, as the initially spent resources no longer exist.

```
const transactionRequest = await wallet.createTransfer(
  wallet.address,
  transferAmount,
  baseAssetId
);

// Set the gasLimit to 0 to force revert with OutOfGas error
transactionRequest.gasLimit = bn(0);

// Transaction will be successfully submitted
const response = await wallet.sendTransaction(transactionRequest);
// let error: FuelError | undefined;
try {
  await response.waitForResult();
} catch (error) {
  if (/OutOfGas/.test((<FuelError>error).message)) {
    transactionRequest.gasLimit = bn(1000);

    // Re-submission will fail
    await wallet.sendTransaction(transactionRequest).catch((error2) => {
      console.log('error2', error2);
    });
  }
}
```

The attempt from the above snippet will result in the error:

```console
FuelError: Transaction is not inserted. UTXO does not exist: {{utxoId}}
```

To safely retry a transaction that failed during processing, you should reassemble the request from scratch and resubmit it.

```
try {
  await response.waitForResult();
} catch (error) {
  if (/OutOfGas/.test((<FuelError>error).message)) {
    const transactionRequest2 = await wallet.createTransfer(
      wallet.address,
      transferAmount,
      baseAssetId
    );

    await wallet.sendTransaction(transactionRequest2);
  }
}
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/splitting-utxos.md.md

# Splitting UTXOs

There may be times when you want to split one large UTXO into multiple smaller UTXOs. This can be useful if you want to send multiple concurrent transactions without having to wait for them to be processed sequentially.

> **Note:** Depending on how many smaller UTXOs you want to create, you may need to fund the wallet with additional funds to cover the fees. As we see in the example below, we fund the sending wallet with 500 to cover the fees for the batch transfer.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();
// This is the wallet that will fund the sending wallet
const fundingWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// This is the wallet that will send the funds
const wallet = Wallet.generate({ provider });
// This is the wallet that will receive the funds
const destinationWallet = Wallet.generate({ provider });

// Let's fund the sending wallet with 1000 of the base asset
const fundingTx = await fundingWallet.transfer(
  wallet.address,
  1000,
  baseAssetId
);
await fundingTx.waitForResult();

// We can fetch the coins to see how many UTXOs we have and confirm it is 1
const { coins: initialCoins } = await wallet.getCoins(baseAssetId);
console.log('Initial Coins Length', initialCoins.length);
// 1

// Now we can split the large 1000 UTXO into 5 UTXOs of 200 each,
// Including the address to send the funds to and the assetId we want to send
const splitTxns = new Array(5).fill({
  amount: 200,
  assetId: baseAssetId,
  destination: destinationWallet.address,
});

// We will also need add some funds to the wallet to cover the fee
// We could have also spent less than 200 for each UTXO, but this is just an example
const fundTx = await fundingWallet.transfer(wallet.address, 500, baseAssetId);
await fundTx.waitForResult();

console.log('Split UTXOs', splitTxns);
// [
//   { amount: 200, assetId: '0x0', destination	: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' }
// ]

// Then we can send the transactions using the batchTransfer function
const batchTx = await wallet.batchTransfer(splitTxns);
await batchTx.waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/sway-script-with-signature-validation.md.md

# Sway Script With Signature Validation

This guide explains how to work with a Script that rely on in-code signature validation. This is particularly useful when you need to verify that a transaction was authorized by a specific account.

## Example Sway Script

Here's an example of a Sway script that validates signatures:

```
script;

use std::{b512::B512, ecr::ec_recover_address, tx::{tx_id, tx_witness_data}};

fn main(signer: b256, witness_index: u64) -> bool {
    let witness_data: B512 = tx_witness_data(witness_index).unwrap();
    let address: b256 = ec_recover_address(witness_data, tx_id()).unwrap().bits();
    return address == signer;
}
```

This script:

1. Takes 2 parameters; an account address and an witness index
2. Recovers the entry witness from the transaction's witnesses array using the given index
3. Validates if the signature was generated by the given account address
4. Returns `true` or `false` based on the validation result

## Understanding Signature Validation in Fuel

On Fuel, transaction signing involves using a wallet's private key to create a hash based on the transaction ID (which is the same as the [transaction hash](https://docs.fuel.network/docs/specs/identifiers/transaction-id/)). The transaction ID is generated by hashing the transaction bytes themselves.

Important considerations:

- Any modification to the transaction after signing will invalidate the signature (modification within the witnesses array do not invalidate the signature)
- This is because the transaction ID changes when the transaction is modified
- The signature is typically the last thing added to a transaction, after estimation and funding

## Special Considerations for Estimation

When working with Sway programs that have in-code signature validation, the estimation process becomes more complex because:

1. A valid signature is required during the estimation process
2. The signature must be valid for both during the transaction estimation and later when submitting the transaction
3. The transaction may be modified during the estimation and funding process, which will result in invalidating any previously added signature

## Implementation Example

Here's how to properly implement a transaction with signature validation for this specific Sway script:

```
// Instantiate the script
const script = new ScriptSigning(signer);

/**
 * Witness index in which we will add the signature, since there will only be
 * one witness in this transaction request
 */
const witnessIndex = 0;

// Creating the scope invocation to be used later
const scope = script.functions.main(signer.address.toB256(), witnessIndex);

// Creating the scope invocation to be used later
const request = await scope.getTransactionRequest();

// Signing the transaction request before estimation
let signature = await signer.signTransaction(request);

// Adding the signature to the transaction request
request.addWitness(signature);

/**
 * Uses `assembleTx` to estimate and fund the transaction request.
 * Because the transaction only requires enough to cover the fee, there's no
 * need to pass any `accountCoinQuantities` to the `assembleTx` function.
 */
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: signer,
});
// Signing the request again as the it was modified during estimation and funding
signature = await signer.signTransaction(assembledRequest);

// Updating the signature in the assembled request
assembledRequest.updateWitness(witnessIndex, signature);

// Sending the transaction request
const { waitForResult } = await scope.call({ skipAssembleTx: true });

// Getting the result of the transaction
const {
  transactionResult: { isStatusSuccess },
} = await waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/cookbook/wallet-sdk-and-react-hooks.md.md

# Wallet SDK and React Hooks

This guide will show you how you can use the [Fuel Wallet](https://wallet.fuel.network/) SDK and its [React Hooks](https://wallet.fuel.network/docs/dev/hooks-reference/) to build a simple React application that lets users connect their wallet to your application and see their balance.

## Setup

The first thing we will do is setup a Next.js project.

::: code-group

```sh [npm]
npm create next-app my-fuel-app
```

```sh [pnpm]
pnpm create next-app my-fuel-app
```

```sh [bun]
bun create next-app my-fuel-app
```

:::

Next, we will install the Fuel Wallet React SDK and the Fuel TypeScript SDK.

::: code-group

```sh [npm]
npm install fuels @fuels/connectors @fuels/react @tanstack/react-query
```

```sh [pnpm]
pnpm add fuels @fuels/connectors @fuels/react @tanstack/react-query
```

```sh [bun]
bun add fuels @fuels/connectors @fuels/react @tanstack/react-query
```

:::

## The Provider

In order to make use of the React hooks provided by the Fuel Wallet SDK, we need to wrap our application in a `FuelProvider` component. This component will provide the hooks with the necessary context to interact with the Fuel Wallet SDK. Add the following to your `pages/_app.tsx` file:

<!-- prettier-ignore -->
```
"use client";

import { defaultConnectors } from "@fuels/connectors";
import { FuelProvider } from "@fuels/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Inter } from "next/font/google";
import React from "react";

import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

const queryClient = new QueryClient();

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <React.StrictMode>
      <html>
        <QueryClientProvider client={queryClient}>
          <FuelProvider
            fuelConfig={{ connectors: defaultConnectors({ devMode: true }) }}
          >
            <body className={inter.className}>{children}</body>
          </FuelProvider>
        </QueryClientProvider>
      </html>
    </React.StrictMode>
  );
}
```

## Building the UI

Go to your `pages/index.tsx` file and replace the contents with the following:

```
"use client";

import {
  useAccount,
  useBalance,
  useConnect,
  useConnectors,
  useDisconnect,
  useIsConnected,
} from "@fuels/react";
import { useState } from "react";

export default function Home() {
  const [connector, setConnector] = useState("");
  const { connectors } = useConnectors();
  const { connect } = useConnect();
  const { disconnect } = useDisconnect();
  const { isConnected } = useIsConnected();
  const { account } = useAccount();
  const { balance } = useBalance({
    address: account as string,
  });

  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 10,
        padding: 10,
        maxWidth: 300,
      }}
    >
      <select
        onChange={(e) => {
          setConnector(e.target.value);
        }}
      >
        <option value="">Select a connector</option>
        {connectors.map((c) => (
          <option key={c.name} value={c.name}>
            {c.name}
          </option>
        ))}
      </select>
      <button disabled={!connector} onClick={() => connect(connector)}>
        Connect to {connector}
      </button>
      <button disabled={!connector} onClick={() => disconnect()}>
        Disconnect from {connector}
      </button>
      <p>{isConnected ? "Connected" : ""}</p>
      {account && <p>Account: {account}</p>}
      {balance && <p>Balance: {balance.toString()}</p>}
    </div>
  );
}
```

Let's break down what's happening here.

The `useConnectors` hook returns a list of available wallet connectors.

Once a connector has been selected by the user, the `useConnect` hook will return a `connect` function that can be used to connect the user's wallet to your application.

The `useAccount` hook returns information about the user's account, if they are connected.

The `useBalance` hook returns the user's ETH balance on the [`testnet` network](https://testnet.fuel.network/v1/playground), if they are connected.

## Further Reading

- [Wallet SDK React Hooks Reference](https://wallet.fuel.network/docs/dev/hooks-reference/)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/deploying-a-dapp-to-testnet.md.md

# Deploying a dApp to Testnet

In this guide, we will deploy a full-stack dApp bootstrapped with `npm create fuels` to the Fuel testnet.

> Make sure you have already bootstrapped a dApp using `npm create fuels`. If you haven't, please follow [this guide](./index.md).

There are mainly two steps to get our dApp live on the testnet:

1. Deploying the Contract to the Testnet
2. Deploying the Frontend to the Cloud

## Deploying the Contract

We will be using [`forc`](https://docs.fuel.network/docs/forc/) to deploy our contracts to the testnet. `forc` is a part of the Fuel Toolchain.

> If you don't have the Fuel Toolchain installed, follow [this guide](https://docs.fuel.network/guides/installation/) to install it.

The first step is to `cd` into the directory containing your contract:

```sh
cd sway-programs/contract
```

And then, run the following command and follow the instructions to deploy the contract to the testnet:

```sh
forc deploy --testnet
```

> You can check out [this guide](https://docs.fuel.network/docs/intro/quickstart-contract/#deploy-to-testnet) for more information on deploying a contract to the testnet.

You should see a message similar to this:

```md
Contract deploy-to-testnet Deployed!

Network: https://testnet.fuel.network
Contract ID: 0x8342d413de2a678245d9ee39f020795800c7e6a4ac5ff7daae275f533dc05e08
Deployed in block 0x4ea52b6652836c499e44b7e42f7c22d1ed1f03cf90a1d94cd0113b9023dfa636
```

Copy the contract ID and save it for later use.

## Deploying the Frontend

Let's now prepare our frontend so that we can deploy it to the cloud.

Go to your `.env.local` file and add a new variable named `VITE_TESTNET_CONTRACT_ID`. Set its value to the contract ID you had copied earlier after deploying your contract.

```md
VITE_TESTNET_CONTRACT_ID=0x8342d413de2a678245d9ee39f020795800c7e6a4ac5ff7daae275f533dc05e08
```

If you are curious, this environment variable is used here in the `src/lib.tsx` file to set the contract ID:

```
export const localContractId = contractIds.testContract;
export const testnetContractId = process.env.VITE_TESTNET_CONTRACT_ID as string;
export const contractId = isLocal ? localContractId : testnetContractId;
```

You will notice that this piece of code is getting the contract ID depending on the current environment. If the environment is `local`, it will use the contract ID from the auto-generated `contract-ids.json` file. Otherwise, for a testnet deployment, it will use the contract ID provided by you.

The `CURRENT_ENVIRONMENT` variable is defined in the `lib.tsx` file:

```
export const environments = { LOCAL: 'local', TESTNET: 'testnet' };
export const environment = process.env.VITE_DAPP_ENVIRONMENT || environments.LOCAL;
export const isLocal = environment === environments.LOCAL;
export const isTestnet = environment === environments.TESTNET;
```

As you can see, it depends on the `VITE_DAPP_ENVIRONMENT` environment variable. If you go to your `.env.local` file, you will see that it is set to `local` by default. If you change this value to `testnet`, the frontend will now be connected to the testnet instead of your local node.

Go ahead and change the `VITE_DAPP_ENVIRONMENT` value to `testnet` in your `.env.local` file.
If you run your frontend now, you should be able to interact with your contract on the testnet.

To deploy your frontend to the cloud, you can use any service like [Vercel](https://vercel.com/). Make sure that you setup your environment variables correctly and that your contract ID is correct. Your environment variables should look something like this:

```md
VITE_DAPP_ENVIRONMENT=testnet
VITE_TESTNET_CONTRACT_ID=0x8342d413de2a678245d9ee39f020795800c7e6a4ac5ff7daae275f533dc05e08

(the rest of the environment variables are optional)
```

## Conclusion

Congratulations! You have successfully deployed your Fuel dApp to the testnet.

To recap, to deploy your dApp to the testnet, you need to:

1. Deploy your contract to the testnet using `forc deploy --testnet`.
2. Specify this contract ID in your frontend's environment variables. (`VITE_TESTNET_CONTRACT_ID`)
3. Set the `VITE_DAPP_ENVIRONMENT` environment variable to `testnet`.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Creating a Fuel dApp

`npm create fuels` is a command line tool that helps you scaffold a new full-stack Fuel dApp. In this guide, we will create a new counter dApp using `npm create fuels` and add decrement functionality to it. The final result will look like this:

![End result of this guide](../../public/creating-a-fuel-dapp-create-fuels-end-result.png)

You can also check it live, deployed to the Testnet:

- [https://create-fuels-template.vercel.app/](https://create-fuels-template.vercel.app/)

## Initializing the project

The first step is to run the command:

::: code-group

```sh-vue [npm]
npm create fuels@{{fuels}}
```

```sh-vue [pnpm]
pnpm create fuels@{{fuels}}
```

```sh-vue [bun]
bun create fuels@{{fuels}}
```

:::

Once you run the command, you will be asked to choose a name for your project:

```md
◇ What is the name of your project?
│ my-fuel-project
└
```

The tool will scaffold the project and install the necessary dependencies for you. You will then be greeted with this message:

```md
⚡️ Success! Created a fullstack Fuel dapp at my-fuel-project

To get started:

- cd into the project directory: cd my-fuel-project
- Start a local Fuel dev server: pnpm fuels:dev
- Run the frontend: pnpm dev

-> TS SDK docs: https://docs.fuel.network/docs/fuels-ts/
-> Sway docs: https://docs.fuel.network/docs/sway/
-> If you have any questions, check the Fuel forum: https://forum.fuel.network/
```

## Directory Structure

The project scaffolded by `npm create fuels` has roughly the following directory structure:

```md
my-fuel-project
├── src
│ ├── components
│ │ └── ...
│ ├── hooks
│ │ └── ...
│ ├── lib.tsx
│ ├── App.tsx
│ └── ...
├── sway-programs
│ ├── contract
│ │ └── ...
│ └── ...
├── public
│ └── ...
├── fuels.config.ts
├── package.json
└── ...
```

It is a Vite project with a few extra files and folders. Let's take a closer look at some of the important ones:

### `./fuels.config.ts`

This is the configuration file for the [`fuels` CLI](../fuels-cli/index.md), the CLI and tooling that powers this project under the hood. It makes sure that all of your Sway programs are continuously compiled and deployed to your local Fuel node. You can read more about the `fuels.config.ts` file in the [Fuels CLI documentation](../fuels-cli/config-file.md).

### `./sway-programs/contract/src/main.sw`

This is where our Sway contract lives. Out of the box, it is a simple counter contract that can only be incremented. We will add a decrement functionality to it in the next step.

### `./src/App.tsx`

This file contains the source code for the frontend of our dApp.

### `./src/components/Contract.tsx`

This file contains the source code for the 'Contract' tab in the UI, this is where the contract calling logic is implemented.

### Dev Environment Setup

Now that we have our project scaffolded, let's set up our development environment.

Let's first start our Fuel Dev server. This will start a local Fuel node and continuously compile and deploy our Sway programs to it.

::: code-group

```sh [npm]
npm fuels:dev
```

```sh [pnpm]
pnpm fuels:dev
```

```sh [bun]
bun run fuels:dev
```

:::

Once the server is up and running, we can start our Next.js development server in another terminal.

::: code-group

```sh [npm]
pnpm dev
```

```sh [pnpm]
pnpm dev
```

```sh [bun]
bun run dev
```

:::

You should now be able to see the dApp running at `http://localhost:5173`. Go ahead and connect a wallet to the dApp. You can choose the Burner Wallet from the list if you don't want to connect a wallet.

![Available Wallet Connectors](../../public/creating-a-fuel-dapp-wallet-list.png)

Now, you can try changing the contents of the `./sway-programs/contract/src/main.sw` file and see the changes reflected in the 'Contract' tab in the UI without having to restart the server.

![Fullstack Fuel Dev Workflow](../../public/creating-a-fuel-dapp-create-fuels-split-view.png)

**Note:** You may wish to learn more about how you could create a Fuel dApp that uses predicates, check out our [Working with Predicates](./working-with-predicates.md) guide.

## Adding Decrement Functionality

To add decrement functionality to our counter, we will have to do two things: 1. Add a `decrement_counter` function to our Sway contract, and 2. Modify the `./src/components/Contract.tsx` file to add a button that calls this function.

### 1. Modifying the Sway Contract

To add a `decrement_counter` function to our Sway contract, we will modify the `./sway-programs/contract/src/main.sw` file.

There are two steps when adding a new function to a Sway program. The first step is to specify the function's ABI.

Towards the top of the file, you will find the ABI section for the contract. Let's add a new function to it:

```
// The abi defines the blueprint for the contract.
abi Counter {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(write, read)]
    fn increment_counter(amount: u64) -> u64;

    #[storage(write, read)]
    fn decrement_counter(amount: u64) -> u64;
}
```

The second step is to implement the function.

We will add the implementation of the `decrement_counter` function right below the `increment_counter` function.

```
impl Counter for Contract {
    // The `get_count` function returns the current value of the counter.
    #[storage(read)]
    fn get_count() -> u64 {
        storage.counter.read()
    }

    // The `increment_counter` function increments the counter by the given amount.
    #[storage(write, read)]
    fn increment_counter(amount: u64) -> u64 {
        let current = storage.counter.read();
        storage.counter.write(current + amount);
        storage.counter.read()
    }

    #[storage(write, read)]
    fn decrement_counter(amount: u64) -> u64 {
        let current = storage.counter.read();
        storage.counter.write(current - amount);
        storage.counter.read()
    }
}
```

### 2. Modifying the Frontend

We will now add a new button to the frontend that will call the `decrement_counter` function when clicked. To do this, we will modify the `./src/App.tsx` file.

First, we will add a function called `decrementCounter` similar to the `incrementCounter` function:

```
  async function decrementCounter() {
    if (!wallet || !contract) return;
    setIsLoading(true);

    try {
      const call = await contract.functions.decrement_counter(1).call();
      transactionSubmitNotification(call.transactionId);
      const result = await call.waitForResult();
      transactionSuccessNotification(result.transactionId);
      setCounter(result.value.toNumber());
    } catch (error) {
      console.error(error);
      errorNotification("Error decrementing counter");
    }
    setIsLoading(false);
  }
```

Second, we will add a new button to the UI that will call the `decrementCounter` function when clicked:

<!-- TODO: our docs engine currently does not detect comments in JSX -->

```tsx
<Button onClick={onDecrementPressed} className="mt-6">
  Decrement Counter
</Button>
```

Congratulations! You should now be able to see the counter dApp running at `http://localhost:5173` with our newly added decrement functionality.

You can find the complete source code of the dApp we built [here](https://github.com/FuelLabs/fuels-ts/tree/master/apps/create-fuels-counter-guide).

![End result of this guide](../../public/creating-a-fuel-dapp-create-fuels-end-result.png)

Whenever you want to add a new feature to your dApp and quickly prototype things, you can follow the same steps we followed in this guide.

### 3. Extending the contract testing suite (Optional)

Testing our smart contract is a good practice to ensure that our implementation is working as expected. It also give assurances down the line if we decide to change the implementation of our contract.

We write our test in the `#[test]` macro within our Sway contract, these can be inline within our Sway contract or in a separate file.

For the guide, we'll add a test for our new `decrement_counter` function in the `./sway-programs/contract/src/main.sw` file:

```
#[test]
fn test_decrement_counter() {
    let contract_instance = abi(Counter, CONTRACT_ID);
    let _ = contract_instance.increment_counter(5);

    let count_before = contract_instance.get_count();
    let count_after = contract_instance.decrement_counter(1);
    assert(count_after == count_before - 1);
}
```

After writing our test, we can run either using `forc test` or via PNPM using `pnpm test:forc`.

### 4. Extending the integration test suite (Optional)

Testing the integration with your smart contract isn't essential, but it's good practice to ensure that your application is working as expected. It also gives you the ability to test your application in a controlled environment against a local node.

We've provided some examples for each program type in the `./test` directory of your project. But let's also add a test for our new `decrement_counter` function in the `./test/contract.test.ts` file:

```
import { Wallet, Provider } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CounterFactory } from '../../../typegend/contracts';

// Let's create our provider from the network URL.
const provider = new Provider(LOCAL_NETWORK_URL);
// Let's create our wallet from the private key.
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Then we can deploy the contract.
const { waitForResult } = await CounterFactory.deploy(wallet);
const { contract } = await waitForResult();

// Lets setup some values to use in our example.
const initialCount = 0;
const incrementedValue = 5;
const decrementedValue = 2;

// We can now call the contract functions and test the results. Lets assert the initial value of the counter.
const { waitForResult: getCountWaitForResult } = await contract.functions
  .get_count()
  .call();
const { value: initialGetCountValue } = await getCountWaitForResult();

console.log('Initial value', initialGetCountValue);

// Next we'll increment the counter, so that we can decrement it.
const { waitForResult: incWaitForResult } = await contract.functions
  .increment_count(5)
  .call();
const { value: incValue } = await incWaitForResult();

console.log('Incremented value', incValue);

// Next, we'll decrement the counter by 3 and assert the new value.
const { waitForResult: decWaitForResult } = await contract.functions
  .decrement_count(3)
  .call();
const { value: decValue } = await decWaitForResult();

console.log('Decremented value', decValue);

// Finally, we'll test the get count function again to ensure parity.
const { waitForResult: finalWaitForResult } = await contract.functions
  .get_count()
  .call();
const { value: finalValue } = await finalWaitForResult();

console.log('Final value', finalValue);
```

The template also comes with a UI testing setup using [Playwright](https://playwright.dev/). We can add a test for our new `decrement_counter` function in the `./test/ui/ui.test.ts` file:

```
test('counter contract - decrement function call works properly', async ({ page }) => {
  await setup({ page });

  const topUpWalletButton = page.getByText('Transfer 5 ETH', { exact: true });
  await topUpWalletButton.click();

  await page.waitForTimeout(2000); // These timeouts are needed to ensure that we wait for transactions to be mined

  const contractTab = page.getByText('Contract');
  await contractTab.click();

  const initialCounterValue = +page.getByTestId('counter').textContent;

  const decrementButton = page.getByText('Decrement', { exact: true });
  await decrementButton.click();

  const counterValueAfterDecrement = +page.getByTestId('counter').textContent;
  expect(counterValueAfterDecrement).toEqual(initialCounterValue - 1);
});
```

## Next Steps

- Now that you have a basic counter dApp running and have the `npm create fuels` workflow powering you, you can start building more complex dApps using the Fuel Stack. A good place to start for ideas and reference code is the [Sway Applications Repo](https://github.com/FuelLabs/sway-applications).

- As you may have noticed, there are different types of programs in your dApp, feel free to explore [Predicates](https://docs.fuel.network/docs/fuels-ts/predicates/) and [Scripts](https://docs.fuel.network/docs/fuels-ts/scripts/), which are both important differentiators in the Fuel Stack.

- If you want to deploy your dApp to the testnet, check out our [Deploying a dApp to Testnet](./deploying-a-dapp-to-testnet.md) guide.

- If you want to further validate the functionality of your dApp and program types, check out the `test` directory in your `create fuels` project. Couple this with our [testing guide](https://docs.fuel.network/docs/fuels-ts/testing/) to get a better understanding of how to test your dApp.

- If you have any questions or need help, feel free to reach out to us on the [Official Fuel Forum](https://forum.fuel.network/).

- If you want to learn more about the Fuel Stack, check out the [Fuel Docs](https://docs.fuel.network/).


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/options.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Options

The `npm create fuels` command has several command-line options that you can use to customize your project.

::: code-group

```sh-vue [pnpm]
pnpm create fuels@{{fuels}} [project-name] [options]
```

```sh-vue [npm]
npm create fuels@{{fuels}} -- [project-name] [options]
```

```sh-vue [bun]
bun create fuels@{{fuels}} [project-name] [options]
```

:::

## `--template <template-name>`

Specifies the template to use for your project. The available templates are: `vite` and `nextjs`. The default template is `vite`.

## `--verbose`

Enables verbose logging. Useful when debugging issues with the tool.

## `-h, --help`

Displays a help message with all available options.

## `-V, --version`

Displays the version number of the `npm create fuels` command.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/working-with-predicates.md.md

# Working with Predicates

This guide builds on the [Creating a Fuel dApp](./index.md) guide. Once you've gotten the dApp there up and running, then you can continue here via clicking the Predicate Example link. We will modify the predicate we created in the previous guide. The final result will look like this:

![End result of this guide](../../public/working-with-predicates-end-result.png)

You can also check it live, deployed to the Testnet:

- [https://create-fuels-template.vercel.app/](https://create-fuels-template.vercel.app/)

## Adding a Configurable pin

The current predicate functionality we have is a simple one that checks if the user has a pin. We will modify this predicate to accept a configurable pin. This will allow the user to set their own pin.

1. Modifying the Predicate Contract

The first step is to modify the predicate contract to accept a configurable pin. We will use the [`configurable`](https://docs.fuel.network/guides/intro-to-predicates/configurables/#configurables) keyword to create an updatable constant to store the pin. We will also modify the main function to check this constant instead of a hardcoded pin.

```
predicate;

configurable {
    PIN: u64 = 1337,
}

fn main(pin: u64) -> bool {
    return PIN == pin;
}
```

2. Modifying the Frontend

We will now add new button to the frontend that will update the `pin` in the predicate when clicked. To do this, we will modify the `./src/components/Predicate.tsx` file.

We will add a function called `changePin`, which will use the current pin in state to update the pin in the predicate as well as transfer 1000 to the predicate.

```
  const changePin = async () => {
    if (!wallet || !predicate) return;
    setIsLoading(true);

    try {
      const configurableConstants = { PIN: bn(predicatePin) };
      const newPredicate = new TestPredicate({
        provider: wallet.provider,
        data: [configurableConstants.PIN],
        configurableConstants,
      });

      const tx = await wallet.transfer(newPredicate.address, bn(2_000_000));
      transactionSubmitNotification(tx.id);
      await tx.waitForResult();
      transactionSuccessNotification(tx.id);
    } catch (error) {
      console.error(error);
      errorNotification(
        "Error changing pin.",
      );
    }
    setIsLoading(false);
    refetch();
  };
```

It would also be useful to change the placeholder text.

```tsx
<input
  type="text"
  value={predicatePin}
  onChange={(e) => setPredicatePin(e.target.value)}
  className="w-1/2 bg-gray-800 rounded-md px-2 py-1 mr-3 truncate font-mono"
  placeholder="Enter current or new pin"
/>
```

Finally, we will add a button that calls the `changePin` function when clicked.

```tsx
<Button onClick={changePin} className="w-full" disabled={isLoading}>
  Change Pin
</Button>
```

Congratulations! That's all. You should now be able to see the modified predicate dApp running at `http://localhost:5173` with our newly added change pin functionality.

You can find the complete source code of the dApp we built [here](https://github.com/FuelLabs/fuels-ts/tree/master/apps/create-fuels-counter-guide).

## Next Steps

- Now that you have a predicate dApp running and have the `npm create fuels` workflow powering you, you can start building more complex dApps using the Fuel Stack. A good place to start for ideas and reference code is the [Sway Applications Repo](https://github.com/FuelLabs/sway-applications).

- If you have any questions or need help, feel free to reach out to us on the [Official Fuel Forum](https://forum.fuel.network/).

- If you want to learn more about the Fuel Stack, check out the [Fuel Docs](https://docs.fuel.network/).


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/encoding/encode-and-decode.md.md

# Encode and Decode

To interact with the FuelVM, types must be encoded and decoded per the [argument encoding specification](https://docs.fuel.network/docs/specs/abi/argument-encoding/). The SDK provides the `Interface` class to encode and decode data.

The relevant methods of `Interface` are:

- `encodeType`
- `decodeType`

The `Interface` class requires you to pass the [ABI](https://docs.fuel.network/docs/specs/abi/json-abi-format/) on initialization. Both methods accept a `concreteTypeId`, which must exist in the ABI's `concreteTypes` array. After that, a suitable coder will be assigned to encode/decode that type.

Imagine we are working with the following script that returns the sum of two `u32` integers:

```
script;

configurable {
    AMOUNT: u32 = 10,
}

fn main(inputted_amount: u32) -> u32 {
    inputted_amount + AMOUNT
}
```

When you build this script, using:

```sh
forc build
```

It will produce the following ABI:

```
{
  "programType": "script",
  "specVersion": "1",
  "encodingVersion": "1",
  "concreteTypes": [
    {
      "type": "u32",
      "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
    },
  ],
  "metadataTypes": [],
  "functions": [
    {
      "inputs": [
        {
          "name": "inputted_amount",
          "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
        },
      ],
      "name": "main",
      "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
      "attributes": null,
    },
  ],
  "loggedTypes": [],
  "messagesTypes": [],
  "configurables": [
    {
      "name": "AMOUNT",
      "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
      "offset": 968,
    },
  ],
}
```

Now, let's prepare some data to pass to the `main` function to retrieve the combined integer. The function expects and returns a `u32` integer. So here, we will encode the `u32` to pass it to the function and receive the same `u32` back, as bytes, that we'll use for decoding. We can do both of these with the `Interface`.

First, let's prepare the transaction:

```
import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ScriptSum } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// First we need to build out the transaction via the script that we want to encode.
// For that we'll need the ABI and the bytecode of the script
const abi: JsonAbi = ScriptSum.abi;
const bytecode = ScriptSum.bytecode;

// Create the invocation scope for the script call, passing the initial
// value for the configurable constant
const script = new Script(bytecode, abi, wallet);
const initialValue = 10;
script.setConfigurableConstants({ AMOUNT: initialValue });
const invocationScope = script.functions.main(0);

// Create the transaction request, this can be picked off the invocation
// scope so the script bytecode is preset on the transaction
const request = await invocationScope.getTransactionRequest();
```

Now, we can encode the script data to use in the transaction:

```
// Now we can encode the argument we want to pass to the function. The argument is required
// as a function parameter for all abi functions and we can extract it from the ABI itself
const argument = abi.functions
  .find((f) => f.name === 'main')
  ?.inputs.find((i) => i.name === 'inputted_amount')?.concreteTypeId as string;

// The `Interface` class (imported from `fuels`) is the entry point for encoding and decoding all things abi-related.
// We will use its `encodeType` method and create the encoding required for
// a u32 which takes 4 bytes up of property space.

const abiInterface = new Interface(abi);
const argumentToAdd = 10;
const encodedArguments = abiInterface.encodeType(argument, [argumentToAdd]);
// Therefore the value of 10 will be encoded to:
// Uint8Array([0, 0, 0, 10]

// The encoded value can now be set on the transaction via the script data property
request.scriptData = encodedArguments;

// Now we can use 'assembleTx' to estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: '0', // Using 0 as the only amount required will be the fee
      assetId: await provider.getBaseAssetId(),
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Finally, submit the built transaction
const response = await wallet.sendTransaction(request);
await response.waitForResult();
```

Finally, we can decode the result:

```
// Get result of the transaction, including the contract call result. For this we'll need
// the previously created invocation scope, the transaction response and the script
const invocationResult = await buildFunctionResult({
  funcScope: invocationScope,
  isMultiCall: false,
  program: script,
  transactionResponse: response,
});

// The decoded value can be destructured from the `FunctionInvocationResult`
const { value } = invocationResult;

// Or we can decode the returned bytes ourselves, by retrieving the return data
// receipt that contains the returned bytes. We can get this by filtering on
// the returned receipt types
const returnDataReceipt = invocationResult.transactionResult.receipts.find(
  (r) => r.type === ReceiptType.ReturnData
) as TransactionResultReturnDataReceipt;

// The data is in hex format so it makes sense to use arrayify so that the data
// is more human readable
const returnData = arrayify(returnDataReceipt.data);
// returnData = new Uint8Array([0, 0, 0, 20]

// And now we can decode the returned bytes in a similar fashion to how they were
// encoded, via the `Interface`
const [decodedReturnData] = abiInterface.decodeType(argument, returnData);
// 20

const totalValue = argumentToAdd + initialValue;
```

A similar approach can be taken with [Predicates](../predicates/index.md); however, you must set the encoded values to the `predicateData` property.

[Contracts](../contracts/index.md) require more care. Although you can utilize the `scriptData` property, the arguments must be encoded as part of the [contract call script](https://docs.fuel.network/docs/sway/sway-program-types/smart_contracts/#calling-a-smart-contract-from-a-script). Therefore, it is recommended to use a `FunctionInvocationScope` when working with contracts which will be instantiated for you when [submitting a contract function](../contracts/methods.md), and therefore handles all the encoding.

## Full Example

Here is the full example of the encoding and decoding methods:

```
import type { JsonAbi, TransactionResultReturnDataReceipt } from 'fuels';
import {
  buildFunctionResult,
  ReceiptType,
  arrayify,
  Script,
  Interface,
  Provider,
  Wallet,
} from 'fuels';

// #region encode-and-decode-3
import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ScriptSum } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// First we need to build out the transaction via the script that we want to encode.
// For that we'll need the ABI and the bytecode of the script
const abi: JsonAbi = ScriptSum.abi;
const bytecode = ScriptSum.bytecode;

// Create the invocation scope for the script call, passing the initial
// value for the configurable constant
const script = new Script(bytecode, abi, wallet);
const initialValue = 10;
script.setConfigurableConstants({ AMOUNT: initialValue });
const invocationScope = script.functions.main(0);

// Create the transaction request, this can be picked off the invocation
// scope so the script bytecode is preset on the transaction
const request = await invocationScope.getTransactionRequest();
// #endregion encode-and-decode-3

// #region encode-and-decode-4

// Now we can encode the argument we want to pass to the function. The argument is required
// as a function parameter for all abi functions and we can extract it from the ABI itself
const argument = abi.functions
  .find((f) => f.name === 'main')
  ?.inputs.find((i) => i.name === 'inputted_amount')?.concreteTypeId as string;

// The `Interface` class (imported from `fuels`) is the entry point for encoding and decoding all things abi-related.
// We will use its `encodeType` method and create the encoding required for
// a u32 which takes 4 bytes up of property space.

const abiInterface = new Interface(abi);
const argumentToAdd = 10;
const encodedArguments = abiInterface.encodeType(argument, [argumentToAdd]);
// Therefore the value of 10 will be encoded to:
// Uint8Array([0, 0, 0, 10]

// The encoded value can now be set on the transaction via the script data property
request.scriptData = encodedArguments;

// Now we can use 'assembleTx' to estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: '0', // Using 0 as the only amount required will be the fee
      assetId: await provider.getBaseAssetId(),
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Finally, submit the built transaction
const response = await wallet.sendTransaction(request);
await response.waitForResult();
// #endregion encode-and-decode-4

// #region encode-and-decode-5

// Get result of the transaction, including the contract call result. For this we'll need
// the previously created invocation scope, the transaction response and the script
const invocationResult = await buildFunctionResult({
  funcScope: invocationScope,
  isMultiCall: false,
  program: script,
  transactionResponse: response,
});

// The decoded value can be destructured from the `FunctionInvocationResult`
const { value } = invocationResult;

// Or we can decode the returned bytes ourselves, by retrieving the return data
// receipt that contains the returned bytes. We can get this by filtering on
// the returned receipt types
const returnDataReceipt = invocationResult.transactionResult.receipts.find(
  (r) => r.type === ReceiptType.ReturnData
) as TransactionResultReturnDataReceipt;

// The data is in hex format so it makes sense to use arrayify so that the data
// is more human readable
const returnData = arrayify(returnDataReceipt.data);
// returnData = new Uint8Array([0, 0, 0, 20]

// And now we can decode the returned bytes in a similar fashion to how they were
// encoded, via the `Interface`
const [decodedReturnData] = abiInterface.decodeType(argument, returnData);
// 20

const totalValue = argumentToAdd + initialValue;
// #endregion encode-and-decode-5
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/encoding/index.md.md

# Encoding

Encoding is the process of serializing data into a format that is suitable for transmission or storage. This is important for blockchains as it enables state minimization and efficiency, as well as for generating proofs.

Fortunately, if you are working with [program types](https://docs.fuel.network/docs/sway/sway-program-types/) on the Fuel network such as [calling contracts](https://docs.fuel.network/docs/fuels-ts/contracts/), the SDK will handle encoding for you automatically. It will adhere to the [argument encoding specification](https://docs.fuel.network/docs/specs/abi/argument-encoding/), so you can work with data in its expected format rather than as bytecode.

However, there may be scenarios where you want to manipulate call or return data yourself or even implement your own serialization specification. This guide will cover how to encode and decode data using the SDK.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/encoding/working-with-bytes.md.md

# Working with Bytes

This guide aims to give a high-level overview of how to work with bytes in the SDK and the structures we expect them to take. For a complete overview of ABI Encoding generally, within the Fuel network, we recommend you see the [ABI Encoding documentation](https://docs.fuel.network/docs/specs/abi/).

## Core Types

We know the sizes of all core types at compile time. They are the building blocks of the more complex types and are the most common types you will encounter.

### Unsigned Integer (`u8` / `u16` / `u32` / `u64` / `u128` / `u256`)

Each type will only contain the number of bits specified in the name. For example, a `u8` will contain 8 bits, and a `u256` will contain 256 bits and take up the exact property space with no additional padding.

```
const u8Coder = new NumberCoder('u8');
const encodedU8 = u8Coder.encode(255);

const u16Coder = new NumberCoder('u16');
const encodedU16 = u16Coder.encode(255);

const u32Coder = new NumberCoder('u32');
const encodedU32 = u32Coder.encode(255);

const u64Coder = new BigNumberCoder('u64');
const encodedU64 = u64Coder.encode(255);

const u256Coder = new BigNumberCoder('u256');
const encodedU256 = u256Coder.encode(255);
```

### Boolean

A boolean is encoded as a single byte like a `u8`, its value being either `0` or `1`.

```
const booleanCoder = new BooleanCoder();
const encodedTrue = booleanCoder.encode(true);

const encodedFalse = booleanCoder.encode(false);
```

### Fixed Length String

A fixed-length string's size is known at compile time due to the argument declaration of `str[n]` with `n` denoting its length. Each character in the string is encoded as a `utf-8` bit.

```
const stringCoder = new StringCoder(5);
const encoded = stringCoder.encode('hello');
```

### `B256` / `B512`

These are fixed-length byte arrays, with `B256` containing 256 bits and `B512` containing 512 bits. You can use them for address and signature formats.

```
const b256Coder = new B256Coder();
const encodedB256 = b256Coder.encode(hexlify(randomBytes(32)));
const b512Coder = new B512Coder();
const encodedB512 = b512Coder.encode(hexlify(randomBytes(64)));
```

## Automatically Encoded Types

These are the types that will contain nested types and no additional encoding is required other than the encoding of the nested types. This is relevant to `array`s, `tuple`s, and `struct`s and `enum`s. The only caveat here, is an `enum` will also contain a `u64` representing the `enum` case value. `option`s are encoded in the same way as `enum`s.

```
const tupleCoder = new TupleCoder([
  new NumberCoder('u8'),
  new NumberCoder('u16'),
]);
const encodedTuple = tupleCoder.encode([255, 255]);

const structCoder = new StructCoder('struct', {
  a: new NumberCoder('u8'),
  b: new NumberCoder('u16'),
});
const encodedStruct = structCoder.encode({ a: 255, b: 255 });

const arrayCoder = new ArrayCoder(new NumberCoder('u8'), 4);
const encodedArray = arrayCoder.encode([255, 0, 255, 0]);

const enumCoder = new EnumCoder('enum', { a: new NumberCoder('u32') });
const encodedEnum = enumCoder.encode({ a: 255 });
```

## Heap types

Heap types are types with a dynamic length that we do not know at compile time. These are `Vec`, `String`, and `raw_slice`. These types are encoded with a `u64` representing the length of the data, followed by the data itself.

```
const vecCoder = new VecCoder(new NumberCoder('u8'));
const encodedVec = vecCoder.encode([255, 0, 255]);

const stdStringCoder = new StdStringCoder();
const encodedStdString = stdStringCoder.encode('hello');

const rawSliceCoder = new RawSliceCoder();
const encodedRawSlice = rawSliceCoder.encode([1, 2, 3, 4]);
```

## Full Example

Here is the full example of the working with bytes functions:

```
import { randomBytes } from 'crypto';
import {
  ArrayCoder,
  B256Coder,
  B512Coder,
  BigNumberCoder,
  BooleanCoder,
  EnumCoder,
  NumberCoder,
  RawSliceCoder,
  StdStringCoder,
  StringCoder,
  StructCoder,
  TupleCoder,
  VecCoder,
  hexlify,
} from 'fuels';

// #region working-with-bytes-1
const u8Coder = new NumberCoder('u8');
const encodedU8 = u8Coder.encode(255);

const u16Coder = new NumberCoder('u16');
const encodedU16 = u16Coder.encode(255);

const u32Coder = new NumberCoder('u32');
const encodedU32 = u32Coder.encode(255);

const u64Coder = new BigNumberCoder('u64');
const encodedU64 = u64Coder.encode(255);

const u256Coder = new BigNumberCoder('u256');
const encodedU256 = u256Coder.encode(255);
// #endregion working-with-bytes-1

// #region working-with-bytes-2
const booleanCoder = new BooleanCoder();
const encodedTrue = booleanCoder.encode(true);

const encodedFalse = booleanCoder.encode(false);

// #endregion working-with-bytes-2

// #region working-with-bytes-3
const stringCoder = new StringCoder(5);
const encoded = stringCoder.encode('hello');
// #endregion working-with-bytes-3

// #region working-with-bytes-4
const b256Coder = new B256Coder();
const encodedB256 = b256Coder.encode(hexlify(randomBytes(32)));
const b512Coder = new B512Coder();
const encodedB512 = b512Coder.encode(hexlify(randomBytes(64)));
// #endregion working-with-bytes-4

// #region working-with-bytes-5
const tupleCoder = new TupleCoder([
  new NumberCoder('u8'),
  new NumberCoder('u16'),
]);
const encodedTuple = tupleCoder.encode([255, 255]);

const structCoder = new StructCoder('struct', {
  a: new NumberCoder('u8'),
  b: new NumberCoder('u16'),
});
const encodedStruct = structCoder.encode({ a: 255, b: 255 });

const arrayCoder = new ArrayCoder(new NumberCoder('u8'), 4);
const encodedArray = arrayCoder.encode([255, 0, 255, 0]);

const enumCoder = new EnumCoder('enum', { a: new NumberCoder('u32') });
const encodedEnum = enumCoder.encode({ a: 255 });
// #endregion working-with-bytes-5

// #region working-with-bytes-6
const vecCoder = new VecCoder(new NumberCoder('u8'));
const encodedVec = vecCoder.encode([255, 0, 255]);

const stdStringCoder = new StdStringCoder();
const encodedStdString = stdStringCoder.encode('hello');

const rawSliceCoder = new RawSliceCoder();
const encodedRawSlice = rawSliceCoder.encode([1, 2, 3, 4]);
// #endregion working-with-bytes-6
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/errors/index.md.md

# Errors

All errors thrown from the SDK are instances of the `FuelError` class which will have an accompanying `ErrorCode`.

## Error Codes

Here is a list of the expected error codes the SDK can throw. These error codes are used to help understand the error that has been thrown with potential resolutions.

### `ABI_MAIN_METHOD_MISSING`

When your ABI does not have a `main` method.

This can be resolved by adding a `main` method to your ABI. This is prevalent in scripts and predicates that must contain a `main` method.

### `ABI_TYPES_AND_VALUES_MISMATCH`

When the arguments supplied to the function do not match the minimum required input length.

Check that the arguments supplied to the function match the required type.

### `ACCOUNT_REQUIRED`

When an [`Account`](DOCS_API_URL/classes/_fuel_ts_account.Account.html) is required for an operation. This will usually be in the form of a [`Wallet`](../wallets/index.md).

It could be caused during the deployments of contracts when an account is required to sign the transaction. This can be resolved by following the deployment guide [here](../contracts/deploying-contracts.md).

### `ASSET_BURN_DETECTED`

When you are trying to send a transaction that will result in an asset burn.

Add relevant coin change outputs to the transaction, or enable asset burn in the transaction request.

### `CONFIG_FILE_NOT_FOUND`

When a configuration file is not found. This could either be a `fuels.config.[ts,js,mjs,cjs]` file or a TOML file.

Ensure that the configuration file is present in the root directory of your project.

### `CONFIG_FILE_ALREADY_EXISTS`

When a configuration file already exists in the root directory of your project.

You can not run `fuels init` more than once for a given project. Either remove the existing configuration file or update it.

### `CONVERTING_FAILED`

When converting a big number into an incompatible format.

Ensure that the value you've supplied to the big number is compatible with the value you are converting to.

### `CONTRACT_SIZE_EXCEEDS_LIMIT`

When the contract size exceeds the maximum contract size limit.

Ensure that the contract size is less than the maximum contract size limit, of 100 KB. This can be validated by checking the bytecode length of the contract.

### `DUPLICATED_POLICY`

When there are more than policies with the same type, for a transaction.

Ensure that there are no duplicate (by type) policies for a transaction.

### `ERROR_BUILDING_BLOCK_EXPLORER_URL`

When more than one of the following options is passed: `path`, `address`, `txId`, `blockNumber`.

Check that only one of the above is passed.

### `FUNCTION_NOT_FOUND`

When the function with the given name, signature or selector is not found in the ABI.

Check that the function name, signature or selector is correct and exits on the ABI.

### `FUNDS_TOO_LOW`

When the funds in the account are lower than the required amount.

Ensure that the account has enough funds to cover the transaction.

### `GAS_LIMIT_TOO_LOW`

When the gas limit is lower than the minimum gas limit.

Increase the gas limit to be greater than the minimum gas limit.

### `GAS_PRICE_TOO_LOW`

When the gas price is lower than the minimum gas price.

Increase the gas price to be greater than the minimum gas price.

### `HD_WALLET_ERROR`

A hardware wallet will throw for unsupported configurations.

The error message will determine which element of the configuration is incorrect. It could be due to the public or private key or when configuring to/from an extended key.

### `INVALID_CHECKSUM`

Checksum validation failed for the provided mnemonic.

Ensure that the mnemonic is correct.

### `INVALID_CHUNK_SIZE_MULTIPLIER`

When the chunk size multiplier is not between 0 and 1.

Ensure that the chunk size multiplier is a number that it is between 0 and 1.

### `INVALID_CONFIGURABLE_CONSTANTS`

When the program type either: does _not_ have configurable constants to be set; or the provided configurable constant does not belong to the program type, as defined by its ABI.

Ensure the configurable constants provided are correct and are defined in ABI.

### `INVALID_COMPONENT`

When an expected component is not found in the ABI or is malformed.

Ensure that you have correctly formed Sway types for [Arrays](../types/arrays.md) and [Vectors](../types/vectors.md).

### `INVALID_CREDENTIALS`

When the password provided is incorrect.

Ensure that the password is correct.

### `INVALID_DATA`

When the value being passed is not considered valid, as defined by the function.

Check the function signature and ensure that the passed value is valid.

### `INVALID_ENTROPY`

When the entropy is not: between 16 and 32 bytes; a multiple of 4.

Ensure that the entropy is between 16 and 32 bytes and a multiple of 4.

### `INVALID_EVM_ADDRESS`

When the provided EVM address is invalid.

Ensure that the [EVM address](../types/evm-address.md) is valid.

### `INVALID_INPUT_PARAMETERS`

When the provided input parameters are _not_ valid.

The error message will determine which parameter is missing. It could be that the provided program type is not one of the following `contract`, `script`, or `predicate`.

### `INVALID_MNEMONIC`

When the supplied mnemonic is invalid.

Check the message for more details. It could be that the mnemonic phrase word length is _not_ one of the following: 12, 15, 18, 21, or 24 lengths.

### `INVALID_PASSWORD`

When the provided password is incorrect.

Ensure that the password is correct.

### `INVALID_POLICY_TYPE`

When the supplied policy type is invalid for the given Script.

Check the policy type is defined in `PolicyType`.

### `INVALID_PROVIDER`

When unable to connect to the `Provider` or `Network` supplied to a method on the [`Fuel`](../wallets/connectors.md) class.

Check that the `Provider` or `Network` is supplied correctly.

### `INVALID_PUBLIC_KEY`

When the provided public key is invalid.

Ensure that the public key is valid.

### `INVALID_RECEIPT_TYPE`

When the receipt type is invalid.

Check the type is within `ReceiptType`.

### `INVALID_REQUEST`

When the request to the Fuel node fails, error messages are propagated from the Fuel node.

Check the error message from the Fuel node.

### `INVALID_SEED`

When the seed length is not between 16 and 64 bytes.

Ensure that the seed length is between 16 and 64 bytes.

### `INVALID_TRANSACTION_INPUT`

When the input type is invalid.

Check the type is within `InputType`.

### `INVALID_TRANSACTION_OUTPUT`

When the output type is invalid.

Check the type is within `OutputType`.

### `INVALID_TRANSACTION_STATUS`

When the transaction status received from the node is unexpected.

Check the status received is within `TransactionStatus`.

### `UNSUPPORTED_TRANSACTION_TYPE`

When the transaction type from the Fuel Node is _not_ supported.

The type is within [`TransactionType`](DOCS_API_URL/enums/_fuel_ts_account.TransactionType.html).

### `INVALID_TTL`

When the TTL is less than or equal to zero.

Ensure that the TTL is a number and that the TTL is greater than zero.

### `INVALID_WORD_LIST`

When the word list length is not equal to 2048.

The word list provided to the mnemonic length should be equal to 2048.

### `INVALID_URL`

When the URL provided is invalid.

Ensure that the URL is valid.

### `JSON_ABI_ERROR`

When an ABI type does not conform to the correct format.

It is usually caused by an incorrect type/s within your program, check our type [docs](../types/index.md) here for information on the types we support and their expected format.

### `LOG_TYPE_NOT_FOUND`

When the log type ID supplied can not be found in the ABI.

Check that the log type ID is correct and exists in the ABI.

### `MISSING_CONNECTOR`

A connector is missing when it's required for a given operation.

Ensure that a connector has been supplied to the `Account` or `Wallet`.

### `MISSING_PROVIDER`

A provider is missing when it's required for a given operation.

It could be caused by the provider not being set for either an [`Account`](DOCS_API_URL/modules/_fuel_ts_account.html) or a [`Wallet`](../wallets/index.md) - use the `connect` method to attach a provider.

### `MISSING_REQUIRED_PARAMETER`

When a required parameter has not been supplied to a given method.

The error message will determine which parameter is missing. This could be caused during type generation when neither `inputs` nor `filepaths` are supplied (at least one is required).

### `NODE_INFO_CACHE_EMPTY`

When the Fuel Node info cache is empty; This is usually caused by not being connected to the Fuel Node.

Ensure that the provider has connected to a Fuel Node successfully.

### `INSUFFICIENT_FUNDS_OR_MAX_COINS`

This error can occur during a funding operation or when calling the `getResourcesToSpend` method. It indicates one of the following issues:

`Insufficient Balance`: The specified account does not have enough balance to cover the required amount.

`UTXO Limit Exceeded`: Although the account has enough total funds, the funds are spread across too many UTXOs (coins). The blockchain limits how many UTXOs can be used in a single transaction, and exceeding this limit prevents the transaction from being processed.

First, to be sure what the real reason is, you can fetch the [balance](../wallets/checking-balances.md) of the `assetId` to ensure that the account has enough funds to cover the amount. After knowing the reason, to solve you can:

`For Insufficient Balance`: Acquire additional funds in the required asset to meet the amount needed.

`For UTXO Limit Exceeded`: Combine UTXOs to reduce their number and meet the network's requirements. You can follow [this guide](../cookbook/combining-utxos.md) to learn how to combine UTXOs effectively.

### `TIMEOUT_EXCEEDED`

When the timeout has been exceeded for a given operation.

Check that you're connected to the network and that the network is stable.

### `TYPE_NOT_FOUND`

When the type with the given type ID is not found in the ABI.

Check that the type ID is correct and exists in the ABI.

### `TYPE_NOT_SUPPORTED`

When an unexpected type has been detected - the error message will determine which type is incorrect.

Check the type against your ABI and ensure that it is correct. You can find a list of all our types [here](../types/index.md).

### `UNSUPPORTED_FUEL_CLIENT_VERSION`

When the version of the Fuel Node you are targeting is not supported by the client you are accessing it from.

Check the version of the Fuel Node and use a compatible version of the SDK to target it.

### `WALLET_MANAGER_ERROR`

A wallet manager will throw for a multitude of reasons. The error message will determine which element of the configuration is incorrect.

It could be that the passphrase is incorrect and/or the wallet does _not_ exist in the manager.

### `WORKSPACE_NOT_DETECTED`

When the workspace is not detected in the directory indicated in the message.

Ensure that the workspace is present in the directory specified.

### `UNKNOWN`

In cases where the error hasn't been mapped yet, this code will be used.

If you believe you found a bug, please report the [issue](https://github.com/FuelLabs/fuels-ts/issues/new/choose) to the team.

### `MAX_INPUTS_EXCEEDED`

When the number of transaction inputs exceeds the maximum limit allowed by the blockchain.

### `MAX_OUTPUTS_EXCEEDED`

When the number of transaction outputs exceeds the maximum limit allowed by the blockchain.

### `CHANGE_OUTPUT_COLLISION`

This error occurs when there's a conflict between the change output specified in the transaction request and the one specified in the `assembleTx` parameters:

1. The transaction request already has a change output set for a specific asset ID and address
2. The `assembleTx` parameters specify a different change output for the same asset ID

### `DUPLICATE_CHANGE_OUTPUT_ACCOUNT`

This error occurs when there are duplicate entries for the same asset ID with different `changeOutputAccount` values in the `accountCoinQuantities` parameter of the `assembleTx` method:

1. The `accountCoinQuantities` parameter contains multiple entries for the same asset ID
2. Each entry specifies a different `changeOutputAccount` for the same asset ID

### `RESPONSE_BODY_EMPTY`

This error occurs when the response from the server has an empty body. The issue will generally lie with the connection setup from your environment and the RPC.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/fuel-asm/index.md.md

# Fuel ASM

Instruction set for the [FuelVM](https://github.com/FuelLabs/fuel-specs).

---

This is a wrapped WASM version of the [`fuel-asm`](https://crates.io/crates/fuel-asm) Rust crate:

- https://crates.io/crates/fuel-asm
- https://github.com/FuelLabs/fuel-vm/tree/master/fuel-asm

## Usage

This example demonstrates how to use the `FuelAsm` to create a program, represented as a vector of instructions, and then convert it to bytes.

```
import { FuelAsm } from 'fuels';

// @ts-expect-error method reference missing in DTS
await FuelAsm.initWasm();

const programBytes = Uint8Array.from([
  ...FuelAsm.move_(0x10, 0x01).to_bytes(), // set r[0x10] := $one
  ...FuelAsm.slli(0x20, 0x10, 5).to_bytes(), // set r[0x20] := `r[0x10] << 5 == 32`
  ...FuelAsm.slli(0x21, 0x10, 6).to_bytes(), // set r[0x21] := `r[0x10] << 6 == 64`
  ...FuelAsm.aloc(0x21).to_bytes(), // alloc `r[0x21] == 64` to the heap
  ...FuelAsm.addi(0x10, 0x07, 1).to_bytes(), // set r[0x10] := `$hp + 1` (allocated heap)
  ...FuelAsm.move_(0x11, 0x04).to_bytes(), // set r[0x11] := $ssp
  ...FuelAsm.add(0x12, 0x04, 0x20).to_bytes(), // set r[0x12] := `$ssp + r[0x20]`
  ...FuelAsm.eck1(0x10, 0x11, 0x12).to_bytes(), // recover public key in memory[r[0x10], 64]
  ...FuelAsm.ret(0x01).to_bytes(), // return `1`
]);

console.log('Bytes', programBytes);
```

## Reference

The above usage is the `Typescript` equivalent of the [original example](https://crates.io/crates/fuel-asm) in `Rust`.

```
[Error reading file: /home/runner/work/docs-hub/docs-hub/docs/fuels-ts/apps/fuel-asm-example/src/main.rs]
```

## See Also

- [FuelVM Specs](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/)
- [FuelVM Semantics](https://docs.fuel.network/docs/specs/fuel-vm/#semantics)
- [Inline Assembly in Sway](https://docs.fuel.network/docs/sway/advanced/assembly)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/fuels-cli/abi-typegen.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const abiUrl = `
    https://docs.fuel.network/docs/sway/sway-program-types/smart_contracts/#the-abi-declaration
  `
  const contractsUrl = `
    https://docs.fuel.network/docs/sway/sway-program-types/smart_contracts/
  `
  const scriptsUrl = `
    https://docs.fuel.network/docs/sway/sway-program-types/scripts/
  `
</script>

# ABI Typegen

## The JSON ABI file

Whether you want to deploy or connect to a pre-existing smart contract, the <a :href="abiUrl" target="_blank" rel="noreferrer">JSON ABI</a> file is what makes it possible.

It tells the SDK about the <a :href="abiUrl" target="_blank" rel="noreferrer">ABI methods</a> in your <a :href="contractsUrl" target="_blank" rel="noreferrer">Smart Contracts</a> and <a :href="scriptsUrl" target="_blank" rel="noreferrer">Scripts</a>

Given the following Sway smart contract:

<!-- TODO: stop using hard-coded snippets -->

```rust:line-numbers
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

The JSON ABI file would look something like this:

```json
$ cat out/debug/my-test-abi.json
[
  {
    "type": "function",
    "inputs": [],
    "name": "test_function",
    "outputs": [
      {
        "name": "",
        "type": "bool",
        "components": null
      }
    ]
  }
]
```

See also:

- [Generating Types](./generating-types.md)
- [Using Generated Types](./using-generated-types.md)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/fuels-cli/commands.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels, forc, fuelCore } = data
</script>

# Commands

The `fuels` CLI consists of a couple of commands.

## `fuels init`

```console-vue
npx fuels@{{fuels}} help init
```

```console
Options:
  --path <path>                Path to project root (default: current directory)
  -w, --workspace <path>       Relative dir path to Forc workspace
  -c, --contracts [paths...]   Relative paths to Contracts
  -s, --scripts [paths...]     Relative paths to Scripts
  -p, --predicates [paths...]  Relative paths to Predicates
  -o, --output <path>          Relative dir path for Typescript generation output
  --forc-path <path>           Path to the `forc` binary
  --fuel-core-path <path>      Path to the `fuel-core` binary
  --auto-start-fuel-core       Auto-starts a `fuel-core` node during `dev` command
  --fuel-core-port <port>      Port to use when starting a local `fuel-core` node for dev mode
  -h, --help                   Display help
```

Creating a sample `fuel.config.ts` file:

```console-vue
npx fuels@{{fuels}} init --contracts ./my-contracts/* --output ./src/sway-contracts-api
```

Using [Forc workspaces](https://docs.fuel.network/docs/forc/workspaces/)? Try this instead:

```console-vue
npx fuels@{{fuels}} init --workspace ./sway-programs --output ./src/sway-programs-api
```

This will give you a minimal configuration:

```
import { createConfig } from 'fuels';

export default createConfig({
  workspace: './sway-programs', // forc workspace
  output: './src/sway-programs-api',
});
```

In a nutshell:

```sh
.
├── sway-programs # <— forc workspace
├── src
│   └── sway-programs-api # <— output
├── fuels.config.ts
└── package.json
```

### See more

- [Forc workspaces](https://docs.fuel.network/docs/forc/workspaces/)

## `fuels build`

```console-vue
npx fuels@{{fuels}} help build
```

```console
Options:
  --path <path>  Path to project root (default: "/Users/anderson/Code/fuel/fuels-ts/apps/docs")
  -d, --deploy       Deploy contracts after build (auto-starts a `fuel-core` node if needed)
  -h, --help         Display help
```

Examples:

```console-vue
npx fuels@{{fuels}} build
```

1.  Build all Sway programs under your `workspace` using `forc` <sup>[1](https://docs.fuel.network/docs/forc/commands/forc_build/)</sup>
1.  Generate types for them using `fuels-typegen` <sup>[2](#fuels-typegen)</sup>

```console-vue
npx fuels@{{fuels}} build --deploy
```

Using the `--deploy` flag will additionally:

1. Auto-start a short-lived `fuel-core` node if _needed_ ([docs](./config-file.md#autostartfuelcore))
1. Run `deploy` on that node

> _This is useful when working with contracts because a contract's ID is generated only on deployment._

## `fuels deploy`

```console-vue
npx fuels@{{fuels}} deploy
```

The `fuels deploy` command does two things:

1. Deploy all Sway contracts under `workspace`.
1. Saves their deployed IDs to:
   - _`./src/sway-programs-api/contract-ids.json`_

```json
{
  "myContract1": "0x..",
  "myContract2": "0x.."
}
```

Use it when instantiating your contracts:

```
    // #context import { Sample } from './sway-programs-api';
    // #context import contractsIds from './sway-programs-api/contract-ids.json';

    // #context /**
    // #context   * Get IDs using:
    // #context   *   contractsIds.<my-contract-name>
    // #context   */

    // #context const wallet = new Wallet.fromPrivateKey(process.env.PRIVATE_KEY);
    const contract = new Sample(contractsIds.sample, wallet);

    const { value } = await contract.functions.return_input(1337).dryRun();

    expect(value.toHex()).toEqual(toHex(1337));
```

For a complete example, see:

- [Using Generated Types](./using-generated-types.md)

### Proxy Contracts Deployment

Automatic deployment of proxy contracts can be enabled in `Forc.toml`.

For more info, please check these docs:

- [Proxy Contracts](https://docs.fuel.network/docs/forc/plugins/forc_client/#proxy-contracts)
- [Sway Libs / Upgradability Library](https://docs.fuel.network/docs/sway-libs/upgradability/#upgradability-library)
- [Sway Standards / SRC-14 - Simple Upgradable Proxies](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/#src-14-simple-upgradeable-proxies)

## `fuels dev`

```console-vue
npx fuels@{{fuels}} dev
```

The `fuels dev` command does three things:

1. Auto-start a short-lived `fuel-core` node ([docs](./config-file.md#autostartfuelcore))
1. Runs `build` and `deploy` once at the start
1. Watches your Forc workspace and repeats the previous step on every change

> _In `dev` mode, every time you update a contract on your Forc `workspace`, we re-generate type definitions and factory classes for it, following your pre-configured [`output`](./config-file.md#output) directory. If it's part of another build system running in dev mode (i.e. `next dev`), you can expect it to re-build / auto-reload as well._

## `fuels node`

```console-vue
npx fuels@{{fuels}} node
```

Starts a short-lived `fuel-core` node and requires a `fuels.config.ts` config file.

Generate one with [`fuels init`](#fuels-init):

```
import { createConfig } from 'fuels';

export default createConfig({
  workspace: './sway-programs', // forc workspace
  output: './src/sway-programs-api',
});
```

## `fuels typegen`

Manually generates type definitions and factory classes from ABI JSON files.

```console-vue
npx fuels@{{fuels}} help typegen
```

```console
Options:
  -i, --inputs <path|glob...>  Input paths/globals to your Abi JSON files
  -o, --output <dir>           Directory path for generated files
  -c, --contract               Generate types for Contracts [default]
  -s, --script                 Generate types for Scripts
  -p, --predicate              Generate types for Predicates
  -S, --silent                 Omit output messages
```

For more info, check:

- [Generating Types from ABI](./generating-types.md)

## `fuels versions`

Check for version incompatibilities between your [Fuel Toolchain](https://docs.fuel.network/docs/sway/introduction/fuel_toolchain/#the-fuel-toolchain) component versions, matching them against the ones supported by the Typescript SDK version that you have.

```console-vue
npx fuels@{{fuels}} versions
```

```console-vue
┌───────────┬───────────┬────────────────┬─────────────┐
│           │ Supported │ Yours / System │ System Path │
├───────────┼───────────┼────────────────┼─────────────┤
│ Forc      │ {{forc}}    │ {{forc}}         │ forc        │
├───────────┼───────────┼────────────────┼─────────────┤
│ Fuel-Core │ {{fuelCore}}    │ {{fuelCore}}         │ fuel-core   │
└───────────┴───────────┴────────────────┴─────────────┘

You have all the right versions! ⚡
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/fuels-cli/config-file.md.md

# Config File

Here, you can learn more about all configuration options.

## `workspace`

Relative directory path to Forc workspace.

```
  workspace: './sway-programs',
```

> _The property `workspace` is incompatible with [`contracts`](#contracts), [`predicates`](#predicates), and [`scripts`](#scripts)._

## `contracts`

List of relative directory paths to Sway contracts.

```
  contracts: ['./sway-programs/contracts'],
```

> _The property `contracts` is incompatible with [`workspace`](#workspace)._

## `predicates`

List of relative directory paths to Sway predicates.

```
  predicates: ['./sway-programs/predicates'],
```

> _The property `predicates` is incompatible with [`workspace`](#workspace)._

## `scripts`

List of relative directory paths to Sway scripts.

```
  scripts: ['./sway-programs/scripts'],
```

> _The property `scripts` is incompatible with [`workspace`](#workspace)._

## `output`

Relative directory path to use when generating Typescript definitions.

```
  output: './src/sway-programs-api',
```

## `providerUrl`

The URL to use when deploying contracts.

```
  // Default: http://127.0.0.1:4000/v1/graphql
  providerUrl: 'http://network:port/v1/graphql',
```

> _When [`autostartFuelCore`](#autostartfuelcore) property is set to `true`, the `providedUrl` is overridden by that of the local short-lived `fuel-core` node started by the [`fuels dev`](./commands.md#fuels-dev) command._

## `privateKey`

Wallet private key, used when deploying contracts.

This property should ideally come from env — `process.env.MY_PRIVATE_KEY`.

```
  privateKey: '0xa449b1ffee0e2205fa924c6740cc48b3b473aa28587df6dab12abc245d1f5298',
```

> _When [`autostartFuelCore`](#autostartfuelcore) property is set to `true`, the `privateKey` is overridden with the `consensusKey` of the local short-lived `fuel-core` node started by the [`fuels dev`](./commands.md#fuels-dev) command._

## `snapshotDir`

> - _Used by [`fuels dev`](./commands.md#fuels-dev) only_.

Relative path to directory containing custom configurations for `fuel-core`, such as:

- `chainConfig.json`
- `metadata.json`
- `stateConfig.json`

This will take effect only when [`autoStartFuelCore`](#autostartfuelcore) is `true`.

```
  snapshotDir: './my/snapshot/dir',
```

## `autoStartFuelCore`

> - _Used by [`fuels dev`](./commands.md#fuels-dev) only_.

When set to `true`, it will automatically:

1. Starts a short-lived `fuel-core` node as part of the [`fuels dev`](./commands.md#fuels-dev) command
1. Override property [`providerUrl`](#providerurl) with the URL for the recently started `fuel-core` node

```
  autoStartFuelCore: true,
```

If set to `false`, you must spin up a `fuel-core` node by yourself and set the URL for it via [`providerUrl`](#providerurl).

## `fuelCorePort`

> - _Used by [`fuels dev`](./commands.md#fuels-dev) only_.
> - _Ignored when [`autoStartFuelCore`](#autostartfuelcore) is set to `false`._

Port to use when starting a local `fuel-core` node.

```
  // Default: first free port, starting from 4000
  fuelCorePort: 4000,
```

## `forcBuildFlags`

> - _Used by [`fuels build`](./commands.md#fuels-build) and [`fuels deploy`](./commands.md#fuels-deploy)_.

Sway programs are compiled in `debug` mode by default.

Here you can customize all build flags, e.g. to build programs in `release` mode.

```
  // Default: []
  forcBuildFlags: ['--release'],
```

Check also:

- [Forc docs](https://docs.fuel.network/docs/forc/commands/forc_build/#forc-build)

## `deployConfig`

You can supply a ready-to-go deploy configuration object:

```
  deployConfig: {},
```

Or use a function for crafting dynamic deployment flows:

- If you need to fetch and use configs or data from a remote data source
- If you need to use IDs from already deployed contracts — in this case, we can use the `options.contracts` property to get the necessary contract ID. For example:

```
  deployConfig: async (options: ContractDeployOptions) => {
    // ability to fetch data remotely
    await Promise.resolve(`simulating remote data fetch`);

    // get contract by name
    const { contracts } = options;

    const contract = contracts.find(({ name }) => {
      const found = name === MY_FIRST_DEPLOYED_CONTRACT_NAME;
      return found;
    });

    if (!contract) {
      throw new Error('Contract not found!');
    }

    return {
      storageSlots: [
        {
          key: '0x..',
          /**
           * Here we could initialize a storage slot,
           * using the relevant contract ID.
           */
          value: contract.contractId,
        },
      ],
    };
  },
```

## `onBuild`

A callback function that is called after a build event has been successful.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)

```
  onBuild: (config: FuelsConfig): void | Promise<void> => {
    console.log('fuels:onBuild', { config });
  },
```

## `onDeploy`

A callback function that is called after a deployment event has been successful.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)
- `data` — The data (an array of deployed contracts)

```
  onDeploy: (config: FuelsConfig, data: DeployedData): void | Promise<void> => {
    console.log('fuels:onDeploy', { config, data });
  },
```

## `onDev`

A callback function that is called after the [`fuels dev`](./commands.md#fuels-dev) command has successfully restarted.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)

```
  onDev: (config: FuelsConfig): void | Promise<void> => {
    console.log('fuels:onDev', { config });
  },
```

## `onNode`

A callback function that is called after the [`fuels node`](./commands.md#fuels-node) command has successfully refreshed.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)

```
  onNode: (config: FuelsConfig): void | Promise<void> => {
    console.log('fuels:onNode', { config });
  },
```

## `onFailure`

Pass a callback function to be called in case of errors.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)
- `error` — Original error object

```
  onFailure: (config: FuelsConfig, error: Error): void | Promise<void> => {
    console.log('fuels:onFailure', { config, error });
  },
```

## `forcPath`

Path to the `forc` binary.

When not supplied, will default to using the `system` binaries (`forc`).

```
  // Default: 'forc',
  forcPath: '~/.fuelup/bin/forc',
```

## `fuelCorePath`

Path to the `fuel-core` binary.

When not supplied, will default to using the `system` binaries (`fuel-core`).

```
  // Default: 'fuel-core'
  fuelCorePath: '~/.fuelup/bin/fuel-core',
```

## Loading environment variables

If you want to load environment variables from a `.env` file, you can use the `dotenv` package.

First, install it:

::: code-group

```sh [pnpm]
pnpm install dotenv
```

```sh [npm]
npm install dotenv
```

```sh [bun]
bun install dotenv
```

:::

Then, you can use it in your `fuels.config.ts` file:

```
import { createConfig } from 'fuels';
import dotenv from 'dotenv';
import { providerUrl } from './src/lib';

dotenv.config({
  path: ['.env.local', '.env'],
});

// If your node is running on a port other than 4000, you can set it here
const fuelCorePort = +(process.env.VITE_FUEL_NODE_PORT as string) || 4000;

export default createConfig({
  workspace: './sway-programs', // Path to your Sway workspace
  output: './src/sway-api', // Where your generated types will be saved
  fuelCorePort,
  providerUrl,
  forcPath: 'fuels-forc',
  fuelCorePath: 'fuels-core',
});
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/fuels-cli/generating-types.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Generating Types from ABI

## Installation

First we install `fuels` to our project:

```console-vue
pnpm add fuels@{{fuels}}
```

## Help

A first glance at the docs:

```console
$ pnpm fuels typegen -h

Usage: fuels typegen [options]

Generate Typescript from Sway ABI JSON files

Options:
  -i, --inputs <path|glob...>  Input paths/globals to your ABI JSON files
  -o, --output <dir>           Directory path for generated files
  -c, --contract               Generate types for Contracts [default]
  -s, --script                 Generate types for Scripts
  -p, --predicate              Generate types for Predicates
  -S, --silent                 Omit output messages
  -h, --help                   Display help
```

## Generating Types for Contracts

You can generate types for a Sway contract using the command below:

<!-- This section should have the command to generate types for a Sway contract -->
<!-- gen_types:example:start -->

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types
```

<!-- gen_types:example:end -->

<!-- This section should explain the flags used in the typegen command -->
<!-- flags:example:start -->

The path after the input flag `-i` should point to the file ending in `-abi.json` produced when the contract was built.

The path after the output flag `-o` will be the output directory for the generated types.

You can omit the `--contract` option here since it's the default.

<!-- flags:example:end -->

## Generating Types for Scripts

To generate types for a Sway script, use the `--script` flag:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --script
```

## Generating Types for Predicates

To generate types for a Sway predicate, use the `--predicate` flag:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --predicate
```

---

See also:

- [Using Generated Contract Types](./using-generated-types.md#contract)
- [Using Generated Script Types](./using-generated-types.md#script)
- [Using Generated Predicate Types](./using-generated-types.md#predicate)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/fuels-cli/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Fuels CLI

The quickest way to build full stack Fuel dApps.

- [`fuels init`](./commands.md#fuels-init) — Creates a new `fuels.config.ts` file
- [`fuels build`](./commands.md#fuels-build) — Build `forc` workspace and generate Typescript types for everything
- [`fuels deploy`](./commands.md#fuels-deploy) — Deploy workspace contracts and save their IDs to JSON file
- [`fuels dev`](./commands.md#fuels-dev) — Start local Fuel Core _node_ and `build` + `deploy` on every file change

## Getting started

Imagine you have this file structure:

```sh
my-fuel-dapp # NextJS app or similar
├── sway-programs # Forc's workspace
│   ├── src
│   ├── ...
│   └── Forc.toml
├── public
│   └── ...
├── src
│   ├── app
│   ├── ...
├   └── sway-programs-api # Type-safe generated API
└── package.json
```

## Prerequisites

The [Fuel Toolchain](https://docs.fuel.network/docs/sway/introduction/fuel_toolchain/#the-fuel-toolchain) and its components (namely `forc` and `fuel-core`) are pre-requisite for several operations with the Fuels CLI. For example:

- Building out contracts using [`fuels build`](./commands.md#fuels-build) requires `forc`.
- Deploying contracts locally using [`fuels deploy`](./commands.md#fuels-deploy) requires `fuel-core`.

Follow the [installation guide](https://docs.fuel.network/guides/installation/) if you don't have them installed already.

## Installation

Add it to your `my-fuel-dapp` project:

::: code-group

```console-vue [npm]
npm install fuels@{{fuels}} --save
```

```console-vue [pnpm]
pnpm add fuels@{{fuels}}
```

```console-vue [bun]
bun add fuels@{{fuels}}
```

:::

## Double-checking

```console-vue
npx fuels@{{fuels}} -v
```

## Next Step

Use [`fuels init`](./commands.md#fuels-init) to create a [`fuel.config.ts`](./config-file.md) file.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/fuels-cli/using-generated-types.md.md

<!-- TODO: Replace plan-text by code-snippets -->

# Using Generated Types

After generating types via:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types
```

We can use these files like so:

```
    // #context import { DemoContract } from './sway-programs-api';

    const contractInstance = new DemoContract(contractId, wallet);
    const call2 = await contractInstance.functions.return_input(1337).call();
    const { value: v2 } = await call2.waitForResult();
```

## Contract

Let's use the Contract class to deploy a contract:

```
    // #context import { DemoContract } from './sway-programs-api';

    // Deploy
    const deploy = await DemoContractFactory.deploy(wallet);
    const { contract } = await deploy.waitForResult();
```

### Autoloading of Storage Slots

Typegen tries to resolve, auto-load, and embed the [Storage Slots](../contracts/storage-slots.md) for your Contract within the `MyContract` class. Still, you can override it alongside other options from [`DeployContractOptions`](https://github.com/FuelLabs/fuels-ts/blob/a64b67b9fb2d7f764ab9151a21d2266bf2df3643/packages/contract/src/contract-factory.ts#L19-L24), when calling the `deploy` method:

```
    // #context import { DemoContractFactory } from './sway-programs-api';

    const { waitForResult } = await DemoContractFactory.deploy(wallet, {
      storageSlots,
    });

    const { contract } = await waitForResult();
```

## Script

After generating types via:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --script
```

We can use these files like so:

```
  // #context import { Script } from './sway-programs-api';

  const script = new DemoScript(wallet);
  const { waitForResult } = await script.functions.main().call();
  const { value } = await waitForResult();
```

## Predicate

After generating types via:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --predicate
```

We can use these files like so:

```
  // #context import type { PredicateInputs } from './sway-programs-api';
  // #context import { Predicate } from './sway-programs-api';

  // In this exchange, we are first transferring some coins to the predicate
  using launched = await launchTestNode();

  const {
    provider,
    wallets: [wallet],
  } = launched;

  const receiver = Wallet.fromAddress(Address.fromRandom(), provider);

  const predicateData: DemoPredicateInputs = [];
  const predicate = new DemoPredicate({
    provider,
    data: predicateData,
  });

  const tx = await wallet.transfer(predicate.address, 200_000, await provider.getBaseAssetId());
  const { isStatusSuccess } = await tx.wait();

  // Then we are transferring some coins from the predicate to a random address (receiver)
  const tx2 = await predicate.transfer(receiver.address, 50_000, await provider.getBaseAssetId());
  await tx2.wait();

  expect((await receiver.getBalance()).toNumber()).toEqual(50_000);
  expect(isStatusSuccess).toBeTruthy();
```

See also:

- [Generating Types for Contracts](./generating-types.md#generating-types-for-contracts)
- [Generating Types for Scripts](./generating-types.md#generating-types-for-scripts)
- [Generating Types for Predicates](./generating-types.md#generating-types-for-predicates)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/getting-started/cdn-usage.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# CDN Usage (browser only)

```html-vue
<script type="module">
  import {
    Wallet,
    Provider,
  } from "https://cdn.jsdelivr.net/npm/fuels@{{fuels}}/dist/browser.min.mjs";

  const main = async () => {
    const provider = new Provider(
      "https://mainnet.fuel.network/v1/graphql",
    );
    const { name } = await provider.getChain();
    console.log(name);
  };

  main();
</script>
```

# More

- [React Example](./react-example.md)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/getting-started/connecting-to-the-network.md.md

# Connecting to the Network

After [installing](./installation.md) the `fuels` package, it's easy to connect to the Network:

```
import { Provider } from 'fuels';

const NETWORK_URL = 'https://mainnet.fuel.network/v1/graphql';

const provider = new Provider(NETWORK_URL);

const baseAssetId = await provider.getBaseAssetId();
const chainId = await provider.getChainId();
const gasConfig = await provider.getGasConfig();

console.log('chainId', chainId);
console.log('baseAssetId', baseAssetId);
console.log('gasConfig', gasConfig);
```

# RPC URLs

These are our official RPC URLs:

| Network   | URL                                                         |
| --------- | ----------------------------------------------------------- |
| Mainnet   | `https://mainnet.fuel.network/v1/graphql`                   |
| Testnet   | `https://testnet.fuel.network/v1/graphql`                   |
| Localhost | [Running a local Fuel node](./running-a-local-fuel-node.md) |

# Resources

Access all our apps directly:

|          | Mainnet                                    | Testnet                                    |
| -------- | ------------------------------------------ | ------------------------------------------ |
| Faucet   | —                                          | https://faucet-testnet.fuel.network/       |
| Explorer | https://app.fuel.network                   | https://app-testnet.fuel.network           |
| Bridge   | https://app.fuel.network/bridge            | https://app-testnet.fuel.network/bridge    |
| GraphQL  | https://mainnet.fuel.network/v1/playground | https://testnet.fuel.network/v1/playground |


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/getting-started/index.md.md

# Getting Started

Welcome to `fuels` Typescript SDK!

We prepared some guides to walk you through your first steps:

1. [Installation](./installation.md)
1. [Connecting to the Network](./connecting-to-the-network.md)
1. [Running a local Fuel node](./running-a-local-fuel-node.md)
1. [React Example](./react-example.md)
1. [CDN Usage](./cdn-usage.md)
1. [Next Steps](./next-steps.md)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/getting-started/installation.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Installation

You must install the [Fuel Toolchain](https://docs.fuel.network/guides/installation/) before using this library.

Then add the `fuels` dependency to your project:

::: code-group

```sh-vue [bun]
bun add fuels@{{fuels}}
```

```sh-vue [pnpm]
pnpm add fuels@{{fuels}}
```

```sh-vue [npm]
npm install fuels@{{fuels}} --save
```

:::

Now you are ready to:

- [Connect to the Network](./connecting-to-the-network.md)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/getting-started/next-steps.md.md

# Done!

Wait no more, let's build your first Fuel dApp!

- [Creating a Fuel dApp](../creating-a-fuel-dapp/)

## Further Resources

For a more in-depth, step-by-step guide on working with the wider Fuel ecosystem, check out the [Developer Quickstart](https://docs.fuel.network/guides/quickstart/), which uses a more procedural and detailed approach:

1. Installing all tools needed to develop with the Fuel ecosystem
1. Writing your first Sway Project
1. Deploying your contract
1. Building a simple front-end dApp to interact with your deployed contract


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/getting-started/react-example.md.md

# React Example

<!-- TODO: Create properly code snippet on new package: `app/react-app` after https://github.com/FuelLabs/fuels-ts/pull/827 got merged -->

```tsx
import { BN, Provider, Wallet } from "fuels";
import { useEffect, useState } from "react";

function App() {
  const [balance, setBalance] = useState(0);

  useEffect(() => {
    const onPageLoad = async () => {
      const provider = new Provider("https://mainnet.fuel.network/v1/graphql");

      const wallet = Wallet.fromAddress("0x...", provider);
      const { balances } = await wallet.getBalances();

      setBalance(new BN(balances[0].amount).toNumber());
    };

    onPageLoad();
  }, []);

  return <div>My Balance: {balance}</div>;
}

export default App;
```

# See Also

- [Optimized React Example](../cookbook/optimized-react-example.md)
- [CDN Usage](./cdn-usage.md)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/getting-started/running-a-local-fuel-node.md.md

# Running a local Fuel node

Remember to first install the [Fuel Toolchain](https://docs.fuel.network/guides/installation/).

Check the online docs:

|             | Command      | Documentation                                                                                          |
| ----------- | ------------ | ------------------------------------------------------------------------------------------------------ |
| Fuel Binary | `fuel-core`  | [docs](https://docs.fuel.network/docs/node-operator/fuel-ignition/local-node/) — Running a local node  |
| TS SDK      | `fuels node` | [docs](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-node) — Using the `fuels` CLI |

<!-- | Forc | `forc node` | [docs](https://docs.fuel.network/docs/forc/commands/forc_node/) | -->

# Utilities

## Testing

You can run a Fuel node from within your `.ts` unit tests:

- [Launching a test node](../testing/launching-a-test-node.md)

## Developing

Configure your project for the `fuels` CLI using a `fuels.config.ts` file:

- [Using the `fuels init` command](../fuels-cli/commands.md#fuels-init)

It makes development easier with a hot-reload experience:

- [Using the `fuels dev` command](../fuels-cli/commands.md#fuels-dev)

# More

- [React Example](./react-example.md)
- [CDN Usage](./cdn-usage.md)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/predicates/configurable-constants.md.md

# Predicate With Configurable Constants

Predicates, much like [contracts](../contracts/configurable-constants.md) and [scripts](../scripts/configurable-constants.md), also supports configurable constants. This enables Predicates to suit specific use cases and enhance their functionality.

## Example: Asset Transfer Validation

Let's consider an example where a predicate is used to validate an asset transfer. In this case, the transfer will only be executed if the recipient's address is on a pre-approved whitelist.

The following snippet illustrates how this could be implemented:

```
predicate;

configurable {
    WHITELISTED: b256 = 0xa703b26833939dabc41d3fcaefa00e62cee8e1ac46db37e0fa5d4c9fe30b4132,
}

fn main(address: b256) -> bool {
    WHITELISTED == address
}
```

In this example, you'll notice the use of a configurable constant named `WHITELISTED`. This constant has a default value that represents the default approved address.

## Modifying The Whitelist

If there is a need to whitelist another address, the `WHITELISTED` constant can be easily updated. The following snippet demonstrates how to set a new value for the `WHITELISTED` constant and to make the predicate execute the transfer:

```
import { Wallet, Provider } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_ADDRESS,
  WALLET_PVT_KEY_2,
} from '../../../../env';
import { WhitelistedAddressPredicate } from '../../../../typegend/predicates/WhitelistedAddressPredicate';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const whitelisted = Wallet.fromAddress(WALLET_ADDRESS, provider);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);
const recipient = Wallet.generate({ provider });

const configurable = { WHITELISTED: whitelisted.address.toB256() };

// Instantiate predicate with configurable constants
const predicate = new WhitelistedAddressPredicate({
  provider,
  data: [configurable.WHITELISTED],
  configurableConstants: configurable,
});

// Transferring funds to the predicate
const tx1 = await sender.transfer(predicate.address, 200_000, baseAssetId, {
  gasLimit: 1000,
});

await tx1.waitForResult();

const amountToTransfer = 100;

// Transferring funds from the predicate to destination if predicate returns true
const tx2 = await predicate.transfer(
  recipient.address,
  amountToTransfer,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

await tx2.waitForResult();
```

By ensuring that the updated `WHITELISTED` address matches the intended recipient's address, the predicate will validate the transfer successfully.

## Default Whitelist Address

In scenarios where the default whitelisted address is already the intended recipient, there's no need to update the `WHITELISTED` constant. The predicate will validate the transfer based on the default value. Here's how this scenario might look:

```
import { Wallet, Provider } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { WhitelistedAddressPredicate } from '../../../../typegend/predicates/WhitelistedAddressPredicate';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient = Wallet.generate({ provider });

// Instantiate predicate without configurable constants (will use the address defined in Sway)
const predicate = new WhitelistedAddressPredicate({
  provider,
  data: ['0xa703b26833939dabc41d3fcaefa00e62cee8e1ac46db37e0fa5d4c9fe30b4132'],
});

// Transferring funds to the predicate
const tx1 = await sender.transfer(predicate.address, 200_000, baseAssetId, {
  gasLimit: 1000,
});

await tx1.waitForResult();

const amountToTransfer = 100;

// Transferring funds from the predicate to destination if predicate returns true
const tx2 = await predicate.transfer(
  recipient.address,
  amountToTransfer,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

await tx2.waitForResult();
```

This ability to configure constants within predicates provides a flexible mechanism for customizing their behavior, thereby enhancing the robustness and versatility of our asset transfer process.

It's important to note that these customizations do not directly modify the original predicate. The address of a predicate is a hash of its bytecode. Any change to the bytecode, including altering a constant value, would generate a different bytecode, and thus a different hash. This leads to the creation of a new predicate with a new address.

This doesn't mean that we're changing the behavior of the original predicate. Instead, we're creating a new predicate with a different configuration.

Therefore, while configurable constants do indeed enhance the flexibility and robustness of predicates, it is achieved by creating new predicates with different configurations, rather than altering the behavior of existing ones.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/predicates/custom-transactions.md.md

# Custom Transactions

Utilizing predicate logic unlocks a wide range of possibilities for your dApps when creating transactions. Therefore, pairing predicates with custom transactions can help you achieve more complex use cases. This can be achieved by instantiating a custom transaction, appending the predicate resources, and submitting the transaction via a successfully validated predicate.

Custom transactions can be shaped via a `ScriptTransactionRequest` instance. For more information on crafting custom transactions and the methods available to them, please refer to the [Transaction Request](../transactions/modifying-the-request.md) guide.

However, this guide will demonstrate how to use a predicate in a custom transaction. Consider the following predicate, where a configurable pin must be used to validate the predicate and unlock the funds:

```
predicate;

configurable {
    PIN: u64 = 1337,
}

fn main(pin: u64) -> bool {
    return PIN == pin;
}
```

We can interact with the above and include it in a custom transaction like so:

```
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ConfigurablePin } from '../../../typegend';
import type { ConfigurablePinInputs } from '../../../typegend/predicates/ConfigurablePin';

// Setup
const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });
const assetId = await provider.getBaseAssetId();
const amountToFundPredicate = 300_000;
const amountToReceiver = 100_000;

// Instantiate the predicate using valid predicate data, aka the pin we need
// to send the funds to the receiver
const data: ConfigurablePinInputs = [1337];
const predicate = new ConfigurablePin({ provider, data });

// Fund the predicate, so that we can send these funds via predicate logic
// to the receiver
const fundPredicateTx = await sender.transfer(
  predicate.address,
  amountToFundPredicate,
  assetId
);
await fundPredicateTx.waitForResult();
const initialPredicateBalance = await predicate.getBalance(assetId);

// Instantiate the script request
const request = new ScriptTransactionRequest();

// Adding the OutputCoin that represents the funds that we want to send to the receiver
request.addCoinOutput(receiver.address, amountToReceiver, assetId);

// Estimate the transaction cost and fund accordingly
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: predicate,
  accountCoinQuantities: [
    {
      amount: amountToReceiver,
      assetId,
      account: predicate,
      changeOutputAccount: predicate,
    },
  ],
});

// Submit the transaction and await it's result
const predicateTx = await predicate.sendTransaction(assembledRequest);
await predicateTx.waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/predicates/deploying-predicates.md.md

# Deploying Predicates

In order to optimize the cost of your recurring predicate executions, we recommend first deploying your predicate. This can be done using the [Fuels CLI](../fuels-cli/index.md) and running the [deploy command](../fuels-cli/commands.md#fuels-deploy).

By deploying the predicate, its bytecode is stored on chain as a blob. The SDK will then produce bytecode that can load the blob on demand to execute the original predicate. This far reduces the repeat execution cost of the predicate.

## How to Deploy a Predicate

To deploy a predicate, we can use the [Fuels CLI](../fuels-cli/index.md) and execute the [deploy command](../fuels-cli/commands.md#fuels-deploy).

This will perform the following actions:

1. Compile the predicate using your `forc` version
1. Deploy the built predicate binary to the chain as a blob
1. Generate a new, smaller predicate that loads the deployed predicate's blob
1. Generate types for both the predicate and the loader that you can use in your application

We can then utilize the above generated types like so:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import {
  ConfigurablePin,
  ConfigurablePinLoader,
} from '../../../typegend/predicates';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });
const baseAssetId = await provider.getBaseAssetId();

// We can deploy dynamically or via `fuels deploy`
const originalPredicate = new ConfigurablePin({
  provider,
  data: [1337],
});

const { waitForResult: waitForDeploy } = await originalPredicate.deploy(wallet);
await waitForDeploy();

// First, we will need to instantiate the script via it's loader bytecode.
// This can be imported from the typegen outputs that were created on `fuels deploy`.
// Then we can use the predicate as we would normally, such as overriding the configurables.
const loaderPredicate = new ConfigurablePinLoader({
  data: [23],
  provider,
  configurableConstants: {
    PIN: 23,
  },
});

// Now, let's fund the predicate
const fundTx = await wallet.transfer(
  loaderPredicate.address,
  100_000,
  baseAssetId
);
await fundTx.waitForResult();

// Then we'll execute the transfer and validate the predicate
const transferTx = await loaderPredicate.transfer(
  receiver.address,
  1000,
  baseAssetId
);
const { isStatusSuccess } = await transferTx.waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/predicates/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const introUrl = `https://docs.fuel.network/docs/sway/introduction/`
  const debugUrl = `https://docs.fuel.network/docs/sway/sway-program-types/predicates/#debugging-predicates`
</script>

# Predicates

Predicates in Sway are specific types of programs that return a boolean value, meaning they function like rules that a transaction must follow to be valid.

They don't have access to the information written on the blockchain – they make decisions based solely on the received parameters.

These predicates are pure functions, which means they don't cause any unintended side effects.

The key difference here is that instead of checking these rules directly on the blockchain, we check them 'off' the blockchain first. Once we're confident they're valid, we then record the transaction on the blockchain.

This method is not only more efficient but also helps to prevent traffic jams on the network and makes transactions cheaper. It does so by reducing the need for repetitive calculations on the blockchain.

## Working with Predicates

Users can send assets to the predicate address as they would to any other address on the blockchain. To spend funds stored at the predicate address, users must provide the original byte code of the predicate and, if required, the predicate data.

The predicate data relates to the parameters received by the predicate's `main` function. This data comes into play during the byte code's execution. If the `main` function does not have any parameters then there is no data to be provided, therefore we do not provide the predicate data.

If the predicate is validated successfully, the funds will be accessible. Otherwise, the SDK will throw a validation error.

In the next section, we provide a step-by-step guide on how to interact with a predicate to validate your transactions.

## Debugging Predicates

Currently there is no way to <a :href="debugUrl" target="_blank" rel="noreferrer">debug a predicate</a> yet. In the meantime, a practical workaround is to initially write, test, and debug your predicate as a script, which has more debugging tools available. Once it's working as expected, you can then convert it back into a predicate.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/predicates/instantiating-a-predicate.md.md

# Instantiating predicates

A predicate in Sway can be as simple as the following:

```
predicate;

fn main() -> bool {
    true
}
```

In this minimal example, the `main` function does not accept any parameters and simply returns true.

Just like contracts in Sway, once you've created a predicate, you can compile it using `forc build`. For more information on working with Sway, refer to the <a :href="introUrl" target="_blank" rel="noreferrer">Sway documentation</a>.

After compiling, you will obtain the binary of the predicate and its JSON ABI (Application Binary Interface). Using these, you can instantiate a predicate in TypeScript as shown in the code snippet below:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);

const predicate = new ReturnTruePredicate({
  provider,
});
```

The created [`Predicate`](DOCS_API_URL/classes/_fuel_ts_account.Predicate.html) instance, among other things, has three important properties: the predicate `bytes` (byte code), the `chainId`, and the predicate `address`.

This address, generated from the byte code, corresponds to the Pay-to-Script-Hash (P2SH) address used in Bitcoin.

## Predicate with multiple arguments

You can pass more than one argument to a predicate. For example, this is a predicate that evaluates to `true` if the two arguments are not equal:

```
predicate;

fn main(arg1: u64, arg2: u64) -> bool {
    return arg1 != arg2;
}
```

You can pass the two arguments to this predicate like this:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { PredicateMultiArgs } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);

const predicate = new PredicateMultiArgs({ provider, data: [20, 30] });
```

## Predicate with a Struct argument

You can also pass a struct as an argument to a predicate. This is one such predicate that expects a struct as an argument:

```
predicate;

struct Validation {
    has_account: bool,
    total_complete: u64,
}

fn main(received: Validation) -> bool {
    let expected_has_account: bool = true;
    let expected_total_complete: u64 = 100;

    received.has_account == expected_has_account && received.total_complete == expected_total_complete
}
```

You can pass a struct as an argument to this predicate like this:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { PredicateMainArgsStruct } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);

const predicate = new PredicateMainArgsStruct({
  provider,
  data: [{ has_account: true, total_complete: 100 }],
});
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/predicates/methods.md.md

# Interacting With Predicates

The `Predicate` class extends the [`Account`](DOCS_API_URL/modules/_fuel_ts_account.html) class, inheriting all its methods. Therefore, there are multiple ways to interact with predicates, but broadly speaking, we can think about three:

- `Checking Balances`
- `Transactions`
- `Transfers`

## Checking Balances

### `getBalances`

This will return the balances of all assets owned by the predicate.

See also: [Checking Wallet Balances](https://docs.fuel.network/docs/fuels-ts/wallets/checking-balances/#getting-a-wallets-balance)

### `getResourcesToSpend`

This will return the resources owned by a predicate so that they can be added to a transaction request.

This method is called under the hood when using [`transfer`](./methods.md#transfer) or [`createTransfer`](./methods.md#createtransfer).

You may want to use this method when using a predicate in an existing transaction request.

```
import { bn, Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

// Fund the predicate
const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

// Instantiate the transaction request.
const transactionRequest = new ScriptTransactionRequest({
  gasLimit: 2000,
  maxFee: bn(0),
});

// Get the resources available to send from the predicate.
const predicateCoins = await predicate.getResourcesToSpend([
  { amount: 2000, assetId: baseAssetId },
]);

// Add the predicate input and resources.
transactionRequest.addResources(predicateCoins);
```

## Transactions

### `setData`

The `setData` method can be used to update the predicate data (i.e., predicate arguments) after the predicate has already been instantiated. Since the predicate data is initially set during instantiation, `setData` provides a way to modify it afterward if needed.

```
const predicate = new ConfigurablePin({
  provider,
  data: [1000], // This is the initial set data
});

predicate.setData([1337]); // This is the new set data
```

> Note: Using `setData` only updates the predicate data inside the predicate instance itself. It does not affect predicate data already embedded in a transaction request that includes predicate UTXOs. This is because each predicate UTXO carries its own copy of the predicate data.

```
const predicate = new ConfigurablePin({
  provider,
  data: [1000],
});

// Fund the predicate
const fundPredicate = await funder.transfer(predicate.address, 100_000_000);
await fundPredicate.waitForResult();

const transactionRequest = await predicate.createTransfer(
  receiver.address,
  100_000,
  baseAssetId
);

// The data will not be modified within the transaction request
predicate.setData([1337]);
```

If you need to modify the predicate data within a transaction request, use the `populateTransactionPredicateData` method after setting the new data.

```
const predicate = new ConfigurablePin({
  provider,
  data: [1000],
});

// Fund the predicate
const fundPredicate = await funder.transfer(predicate.address, 100_000_000);
await fundPredicate.waitForResult();

const transactionRequest = await predicate.createTransfer(
  receiver.address,
  100_000,
  baseAssetId
);

predicate.setData([1337]);

predicate.populateTransactionPredicateData(transactionRequest);
```

### `sendTransaction`

This is used to send a transaction to the node.

```
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

// Fund the predicate
const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);

await fundPredicate.waitForResult();

// Instantiate the transaction request.
const request = new ScriptTransactionRequest();

// Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: predicate,
  accountCoinQuantities: [
    {
      amount: '0',
      assetId: baseAssetId,
      account: predicate,
      changeOutputAccount: predicate,
    },
  ],
});

// Send the transaction using the predicate
const result = await predicate.sendTransaction(assembledRequest);

await result.waitForResult();
```

### `simulateTransaction`

You can use the `simulateTransaction` method to dry-run a predicate call without consuming resources. A typical use case of a dry-run call is to validate that sufficient funds are available to cover the transaction fees.

```
import {
  bn,
  Provider,
  ReceiptType,
  ScriptTransactionRequest,
  Wallet,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });

const predicate = new ReturnTruePredicate({
  provider,
});

const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

// Instantiate the transaction request.
const request = new ScriptTransactionRequest();

const amount = bn(1_000_000);

request.addCoinOutput(receiver.address, amount, baseAssetId);

// Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: predicate,
  accountCoinQuantities: [
    {
      amount,
      assetId: baseAssetId,
      account: predicate,
      changeOutputAccount: predicate,
    },
  ],
});

const result = await predicate.simulateTransaction(assembledRequest);
```

## Transfers

### `createTransfer`

The `createTransfer` method creates a transaction request with all the necessary transfer details. It automatically estimates the transaction costs via a dry-run call and funds the request with the required predicate resources. After this, one can submit the returned transaction request with greater certainty that it will succeed.

However, please remember that you can still modify the transfer request details and use its properties before submitting it to the node.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

// Fund the predicate
const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

const receiver = Wallet.generate({ provider });
const amountToReceiver = 1000;

const transactionRequest = await predicate.createTransfer(
  receiver.address,
  amountToReceiver,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

const sendFromPredicate = await predicate.sendTransaction(transactionRequest);

await sendFromPredicate.waitForResult();
```

### `transfer`

You can send funds to another address using the `transfer` method.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

const receiver = Wallet.generate({ provider });
const amountToReceiver = 1000;

const transferPredicateCoins = await predicate.transfer(
  receiver.address,
  amountToReceiver,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

await transferPredicateCoins.waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/predicates/send-and-spend-funds-from-predicates.md.md

# Send And Spend Funds From Predicates

Predicates can be used to validate transactions. This implies that a predicate can safeguard assets, only allowing their transfer if the predicate conditions are met.

This guide will demonstrate how to send and spend funds using a predicate.

## Predicate Example

Consider the following predicate:

```
predicate;

fn main(input_address: b256) -> bool {
    let valid_address = 0xfc05c23a8f7f66222377170ddcbfea9c543dff0dd2d2ba4d0478a4521423a9d4;

    input_address == valid_address
}
```

This predicate accepts an address of type `B256` and compares it with a hard-coded address of the same type. If both addresses are equal, the predicate returns true, otherwise it will return false.

## Interacting with the Predicate Using SDK

Let's use the above predicate to validate our transaction.

Once you've compiled the predicate (`forc build`), you'll obtain two important artifacts: the JSON ABI and the predicate's binary code. These are needed to instantiate a new predicate.

This is where we also pass in the predicate's data. Note that the `main` function in our predicate example requires a parameter called `input_address` of type `B256`. We will pass this parameter to the `Predicate` constructor along with the bytecode and the JSON ABI.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { SimplePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });

const inputAddress =
  '0xfc05c23a8f7f66222377170ddcbfea9c543dff0dd2d2ba4d0478a4521423a9d4';

const predicate = new SimplePredicate({
  provider,
  data: [inputAddress],
});
```

> Note: If you want to pass in the predicate data _after_ instantiating the `Predicate` or if you want to use a different data than the one passed in the constructor, you will have to create a new `Predicate` instance.

With the predicate instantiated, we can transfer funds to its address. This requires us to have a wallet with sufficient funds. If you're unsure about using wallets with the SDK, we recommend checking out our [wallet](../wallets/) guide.

```
// The amount of coins to send to the predicate
const amountToPredicate = 10_000_000;

// Fund the predicate with some funds from our wallet (sender)
const fundPredicateTx = await sender.transfer(
  predicate.address,
  amountToPredicate,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

// Wait for the transaction
await fundPredicateTx.waitForResult();
```

Now that our predicate holds funds, we can use it to validate a transaction and hence execute our transfer. We can achieve that by doing the following:

```
// The amount of coins to send from the predicate, to our receiver wallet.
const amountToReceiver = 200;

// Transfer funds from the predicate, to our receiver wallet
const transferFromPredicateTx = await predicate.transfer(
  receiver.address,
  amountToReceiver,
  baseAssetId
);

// Wait for the transaction
await transferFromPredicateTx.waitForResult();
```

Note the method transfer has two parameters: the recipient's address and the intended transfer amount.

Once the predicate resolves with a return value `true` based on its predefined condition, our predicate successfully spends its funds by means of a transfer to a desired wallet.

---

In a similar approach, you can use the `createTransfer` method, which returns a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html). Then, we can submit this transaction request by calling the `sendTransaction` method.

The following example, we are pre-staging a transaction and therefore we are able to know the transaction ID without actually submitting the transaction.

```
// Create the transaction for transferring funds from the predicate.
const transactionRequest = await predicate.createTransfer(
  receiver.address,
  amountToReceiver,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

// We can obtain the transaction ID before submitting the transaction.
const chainId = await provider.getChainId();
const transactionId = transactionRequest.getTransactionId(chainId);

// We can submit the transaction and wait for the result.
const submitTransaction = await predicate.sendTransaction(transactionRequest);
await submitTransaction.waitForResult();
```

## Spending Entire Predicate Held Amount

Trying to forward the entire amount held by the predicate results in an error because no funds are left to cover the transaction fees. Attempting this will result in an error message like:

```
const errorMessage = `Insufficient funds or too many small value coins. Consider combining UTXOs.`;
```

## Predicate Validation Failure

What happens when a predicate fails to validate? Recall our predicate only validates if the `input_address` matches the hard-coded `valid_address`. Hence, if we set a different data from the `valid_address`, the predicate will fail to validate.

When a predicate fails to validate, the SDK throws an error that starts like this:

```
const errorMessage = `PredicateVerificationFailed`;
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/provider/index.md.md

# Provider

The [`Provider`](DOCS_API_URL/classes/_fuel_ts_account.Provider.html) lets you connect to a Fuel node ([_*docs*_](../getting-started/connecting-to-the-network.md)) and interact with it, encapsulating common client operations in the SDK. Those operations include querying the blockchain for network, block, and transaction-related info (and [more](DOCS_API_URL/classes/_fuel_ts_account.Provider.html)), as well as sending [transactions](../transactions/index.md) to the blockchain.

All higher-level abstractions (e.g. [`Wallet`](../wallets/index.md), [`Contract`](../contracts/index.md)) that interact with the blockchain go through the `Provider`, so it's used for various actions like getting a wallet's balance, deploying contracts, querying their state, etc.

```
import { Provider, WalletUnlocked } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// Create the provider
const provider = new Provider(LOCAL_NETWORK_URL);

// Querying the blockchain
const { consensusParameters } = await provider.getChain();

// Create a new wallet
const wallet = WalletUnlocked.generate({ provider });

// Get the balances of the wallet (this will be empty until we have assets)
const { balances } = await wallet.getBalances();
// []
```

You can find more examples of `Provider` usage [here](./querying-the-chain.md).


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/provider/pagination.md.md

# Pagination

Pagination is highly efficient when dealing with large sets of data. Because of this some methods from the `Provider` class support [GraphQL cursor pagination](https://graphql.org/learn/pagination/), allowing you to efficiently navigate through data chunks.

## Pagination Arguments

The pagination arguments object is used to specify the range of data you want to retrieve. It includes the following properties:

- `after`: A cursor pointing to a position after which you want to retrieve items.
- `first`: The number of items to retrieve after the specified cursor. This is used in conjunction with the `after` argument.
- `before`: A cursor pointing to a position before which you want to retrieve items.
- `last`: The number of items to retrieve before the specified cursor. This is used in conjunction with the `before` argument.

```
const paginationArgsExample: CursorPaginationArgs = {
  after: 'cursor',
  first: 10,
  before: 'cursor',
  last: 10,
};
```

## Page Info

The `pageInfo` object is included in the GraphQL response for requests that support cursor pagination. It provides crucial metadata about the current page of results, allowing you to understand the pagination state and determine if there are more items to fetch before or after the current set.

- `endCursor`: A cursor representing the last item in the current set of results. It should be used as the `after` argument in subsequent queries to fetch the next set of items.
- `hasNextPage`: A boolean indicating whether there are more items available after the current set.
- `startCursor`: A cursor representing the first item in the current set of results. It should be used as the `before` argument in subsequent queries to fetch the previous set of items.
- `hasPreviousPage`: A boolean indicating whether there are more items available before the current set.

```
const pageInfoExample: PageInfo = {
  endCursor: 'cursor',
  hasNextPage: true,
  startCursor: 'cursor',
  hasPreviousPage: true,
};
```

## Using Pagination

One of the methods that supports pagination is the `getCoins` method. This method receives three parameters:

- `address`: The owner's account address
- `assetId`: The asset ID of the coins (optional)
- `paginationArgs`: The pagination arguments (optional)

### Basic Pagination

Here is how you can use the `getCoins` method with pagination:

```
const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

let paginationArgs: CursorPaginationArgs = {
  first: 10, // It will return only the first 10 coins
};

const { coins, pageInfo } = await provider.getCoins(
  WALLET_ADDRESS,
  baseAssetId,
  paginationArgs
);

if (pageInfo.hasNextPage) {
  paginationArgs = {
    after: pageInfo.endCursor,
    first: 10,
  };
  // The coins array will include the next 10 coins after the last one in the previous array
  await provider.getCoins(WALLET_ADDRESS, baseAssetId, paginationArgs);
}
```

### Navigating to the Previous Page

You can also use the `paginationArgs` to navigate to the previous page of results:

```
if (pageInfo.hasPreviousPage) {
  paginationArgs = {
    before: pageInfo.startCursor,
    last: 10,
  };

  // It will includes the previous 10 coins before the first one in the previous array
  await provider.getCoins(WALLET_ADDRESS, baseAssetId, paginationArgs);
}
```

## Valid Combinations

- Forward Pagination:

  Use `after` with `first` to retrieve items following a cursor.

```
const paginationArgsForward: CursorPaginationArgs = {
  after: 'cursor',
  first: 10,
};
```

- Backward Pagination:

  Use `before` with `last` to retrieve items preceding a cursor.

```
const paginationArgsBackwards: CursorPaginationArgs = {
  before: 'cursor',
  last: 10,
};
```

## Default Behavior

If neither `assetId` nor `paginationArgs` are provided, the `getCoins` method will default to the base asset ID and return the first 100 items:

```
// It will return the first 100 coins for a given wallet
await provider.getCoins(WALLET_ADDRESS);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/provider/provider-options.md.md

# Provider Options

You can provide various [options](DOCS_API_URL/types/_fuel_ts_account.ProviderOptions.html) on `Provider` instantiation to modify its behavior.

### `retryOptions`

Calls to a fuel node via the `Provider` will fail if a connection cannot be established.
Specifying retry options allows you to customize the way you want to handle that failure scenario before ultimately throwing an error.

_NOTE: retrying is only done when a connection cannot be established. If the connection is established and the node throws an error, no retry will happen._

You can provide the following settings:

- `maxRetries` - Amount of attempts to retry after initial attempt before failing the call.
- `backoff` - Strategy used to define the intervals between attempts.
  - `exponential` _(default)_: Doubles the delay with each attempt.
  - `linear` - Increases the delay linearly with each attempt.
  - `fixed`: Uses a constant delay between attempts.
- `baseDelay` _(default 150ms)_ - Base time in milliseconds for the backoff strategy.

```
new Provider(NETWORK_URL, {
  retryOptions: {
    maxRetries: 5,
    baseDelay: 100,
    backoff: 'linear',
  },
});
```

### `requestMiddleware`

Allows you to modify the request object to add additional headers, modify the request's body, and much more.

```
// synchronous request middleware
new Provider(NETWORK_URL, {
  requestMiddleware: (request: RequestInit) => {
    request.credentials = 'omit';

    return request;
  },
});

// asynchronous request middleware
new Provider(NETWORK_URL, {
  requestMiddleware: async (request: RequestInit) => {
    const credentials = await fetchSomeExternalCredentials();
    request.headers ??= {};
    (request.headers as Record<string, string>).auth = credentials;

    return request;
  },
});
```

### `timeout`

Specify the timeout in milliseconds after which every request will be aborted.

```
new Provider(NETWORK_URL, {
  timeout: 3000, // will abort if request takes 30 seconds to complete
});
```

### `fetch`

Provide a custom `fetch` function that'll replace the default fetch call.

_Note: If defined, `requestMiddleware`, `timeout` and `retryOptions` are applied to this custom `fetch` function as well._

```
new Provider(NETWORK_URL, {
  fetch: async (url: string, requestInit: RequestInit | undefined) => {
    // native fetch
    const response = await fetch(url, requestInit);

    const updatedResponse = decorateResponseWithCustomLogic(response);

    return updatedResponse;
  },
});
```

### `resourceCacheTTL`

When using the SDK, it may be necessary to submit multiple transactions from the same account in a short period. In such cases, the SDK creates and funds these transactions, then submits them to the node.

However, if a second transaction is created before the first one is processed, there is a chance of using the same resources (UTXOs or Messages) for both transactions. This happens because the resources used in the first transaction are still unspent until the transaction is fully processed.

If the second transaction attempts to use the same resources that the first transaction has already spent, it will result in one of the following error:

```console
Transaction is not inserted. Hash is already known

Transaction is not inserted. UTXO does not exist: {{utxoID}}

Transaction is not inserted. A higher priced tx {{txID}} is already spending this message: {{messageNonce}}
```

This error indicates that the resources used by the second transaction no longer exist, as the first transaction already spent them.

To prevent this issue, the SDK sets a default cache for resources to 20 seconds. This default caching mechanism ensures that resources used in a submitted transaction are not reused in subsequent transactions within the specified time. You can control the duration of this cache using the `resourceCacheTTL` flag. If you would like to disable caching, you can pass a value of `-1` to the `resourceCacheTTL` parameter.

```
new Provider(NETWORK_URL, {
  // Cache resources (Coin's and Message's) for 5 seconds
  resourceCacheTTL: 5000,
});
```

**Note:**

If you would like to submit multiple transactions without waiting for each transaction to be completed, your account must have multiple UTXOs available. If you only have one UTXO, the first transaction will spend it, and any remaining amount will be converted into a new UTXO with a different ID.

By ensuring your account has multiple UTXOs, you can effectively use the `resourceCacheTTL` flag to manage transactions without conflicts. For more information on UTXOs, refer to the [UTXOs guide](../the-utxo-model/index.md).


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/provider/querying-the-chain.md.md

# Querying the Chain

Once you have set up a provider, you're ready to interact with the Fuel blockchain.

- [Connecting to the Network](../getting-started/connecting-to-the-network.md)

Let's look at a few examples below.

## `getBaseAssetId`

The base asset is the underlying asset used to perform any transaction on a chain. This should be fetched from a provider to then be used in transactions.

```
import { Address, Provider, ScriptTransactionRequest } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_ADDRESS } from '../../../../env';

// Fetch the base asset ID using the provider
const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();
// 0x...

// Instantiate our recipients address
const recipientAddress = new Address(WALLET_ADDRESS);

// Create a transaction request
const transactionRequest = new ScriptTransactionRequest();
// Use the base asset for an operation
transactionRequest.addCoinOutput(recipientAddress, 100, baseAssetId);
```

## `getCoins`

Returns UTXOs coins from an account address, optionally filtered by asset ID. This method supports [pagination](./pagination.md).

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const assetIdA =
  '0x0101010101010101010101010101010101010101010101010101010101010101';
const baseAssetId = await provider.getBaseAssetId();

// Fetches up to 100 coins that have an asset ID that is equal to the base asset ID
const { coins: coinsOnlyBaseAsset } = await provider.getCoins(
  wallet.address,
  baseAssetId
);
// [
//   { amount: bn(100), assetId: baseAssetId },
//   ...
// ]

// Fetches up to 100 coins - irrespective of the asset ID
const { coins: coinsAnyAsset } = await provider.getCoins(wallet.address);
// [
//   { amount: bn(100), assetId: baseAssetId }
//   { amount: bn(100), assetId: assetIdA }
//   ...
// ]
```

This method is also implemented on the `Account` class and can be used without providing the `address`:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const baseAssetId = await provider.getBaseAssetId();

const { coins } = await wallet.getCoins(baseAssetId);
// [
//   { amount: bn(100), assetId: baseAssetId },
//   ...
// ]
```

## `getResourcesToSpend`

Returns spendable resources (coins or messages) for a transaction request. It accepts an optional third parameter, `resourcesIdsToIgnore`, to exclude specific UTXO IDs or coin message nonces:

```
import type { CoinQuantityLike, ResourcesIdsToIgnore } from 'fuels';
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const assetIdA =
  '0x0101010101010101010101010101010101010101010101010101010101010101';

const baseAssetId = await provider.getBaseAssetId();

const quantities: CoinQuantityLike[] = [
  { amount: 32, assetId: baseAssetId, max: 42 },
  { amount: 50, assetId: assetIdA },
];

const utxoId =
  '0x00000000000000000000000000000000000000000000000000000000000000010001';
const messageNonce =
  '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0';
const excludedIds: ResourcesIdsToIgnore = {
  utxos: [utxoId],
  messages: [messageNonce],
};

const spendableResources = await provider.getResourcesToSpend(
  wallet.address,
  quantities,
  excludedIds
);

const tx = new ScriptTransactionRequest();
tx.addResources(spendableResources);
```

This method is also available in the `Account` class and can be used without providing the `address`:

```
import type { CoinQuantityLike, ResourcesIdsToIgnore } from 'fuels';
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const assetIdA =
  '0x0101010101010101010101010101010101010101010101010101010101010101';

const baseAssetId = await provider.getBaseAssetId();

const quantities: CoinQuantityLike[] = [
  { amount: 32, assetId: baseAssetId, max: 42 },
  { amount: 50, assetId: assetIdA },
];

const utxoId =
  '0x00000000000000000000000000000000000000000000000000000000000000010001';
const messageNonce =
  '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0';
const excludedIds: ResourcesIdsToIgnore = {
  utxos: [utxoId],
  messages: [messageNonce],
};

const spendableResources = await wallet.getResourcesToSpend(
  quantities,
  excludedIds
);

const tx = new ScriptTransactionRequest();
tx.addResources(spendableResources);
```

## `getBalances`

Returns the sum of all UTXOs coins and unspent message coins amounts for all assets. Unlike `getCoins`, it only returns the total amounts, not the individual coins:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const { balances } = await provider.getBalances(wallet.address);
// [
//   { amount: bn(42), assetId: baseAssetId } // total amount of baseAssetId
//   { amount: bn(100), assetId: assetIdA } // total amount of assetIdA
// ]
```

This method is also available in the `Account` class and can be used without providing the `address` parameter:

```
await wallet.getBalances();
```

## `getBlocks`

The `getBlocks` method returns blocks from the blockchain matching the given `paginationArgs` parameter, supporting [pagination](./pagination.md). The below code snippet shows how to get the last 10 blocks.

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const blockToProduce = 3;

// Force-producing some blocks to make sure that blocks exist
await provider.produceBlocks(blockToProduce);

const { blocks } = await provider.getBlocks({
  last: blockToProduce,
});
```

## `getMessageByNonce`

You can use the `getMessageByNonce` method to retrieve a message by its nonce.

```
import { launchTestNode, TestMessage } from 'fuels/test-utils';

const { provider } = await launchTestNode({
  nodeOptions: {
    snapshotConfig: {
      stateConfig: {
        messages: [
          new TestMessage({
            nonce:
              '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0',
          }).toChainMessage(),
        ],
      },
    },
  },
});

const nonce =
  '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0';
const message = await provider.getMessageByNonce(nonce);
```

## `getMessages`

You can use the `getMessages` method to retrieve a list of messages from the blockchain.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

// Instantiate a provider and wallet
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Retrieves messages from the wallet
const { messages } = await wallet.getMessages();
```

## `getMessageProof`

A message proof is a cryptographic proof that a message was included in a block. You can use the `getMessageProof` method to retrieve a message proof for a given transaction ID and message ID.

You can retrieve a message proof by either using it's block ID:

```
import type { TransactionResultMessageOutReceipt } from 'fuels';
import { sleep } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode({
  nodeOptions: {
    args: ['--poa-instant', 'false', '--poa-interval-period', '1s'],
  },
});

const {
  provider,
  wallets: [sender, recipient],
} = launched;

// Performs a withdrawal transaction from sender to recipient, thus generating a message
const withdrawTx = await sender.withdrawToBaseLayer(
  recipient.address.toB256(),
  100
);
const result = await withdrawTx.waitForResult();

// Waiting for a new block to be committed (1 confirmation block)
// Retrieves the latest block
await sleep(1500);
const latestBlock = await provider.getBlock('latest');

// Retrieves the `nonce` via message out receipt from the initial transaction result
const { nonce } = result.receipts[0] as TransactionResultMessageOutReceipt;

// Retrieves the message proof for the transaction ID and nonce using the next block Id
const messageProofFromBlockId = await provider.getMessageProof(
  result.id,
  nonce,
  latestBlock?.id
);
```

Or by it's block height:

```
import type { TransactionResultMessageOutReceipt } from 'fuels';
import { sleep } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode({
  nodeOptions: {
    args: ['--poa-instant', 'false', '--poa-interval-period', '1s'],
  },
});

const {
  provider,
  wallets: [sender, recipient],
} = launched;

// Performs a withdrawal transaction from sender to recipient, thus generating a message
const withdrawTx = await sender.withdrawToBaseLayer(
  recipient.address.toB256(),
  100
);
const result = await withdrawTx.waitForResult();

// Waiting for a new block to be committed (1 confirmation block)
// Retrieves the latest block
await sleep(1000);
const latestBlock = await provider.getBlock('latest');

// Retrieves the `nonce` via message out receipt from the initial transaction result
const { nonce } = result.receipts[0] as TransactionResultMessageOutReceipt;

// Retrieves the message proof for the transaction ID and nonce using the block height
const messageProofFromBlockHeight = await provider.getMessageProof(
  result.id,
  nonce,
  undefined,
  latestBlock?.height
);
```

## `getTransactions`

You can use the `getTransactions` method to retrieve a list of transactions from the blockchain. This is limited to 30 transactions per page.

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const { transactions } = await provider.getTransactions();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/provider/rpc-consistency.md.md

# RPC Consistency

A common issue with querying distributed networks is ensuring consistency between nodes. At any moment, each node could be at a different block height; therefore, querying the state of the blockchain may yield different results from node to node.

To defend against this, the SDK appends the block height to block-sensitive requests so the node will verify that it meets the block height criteria before processing the request.

If the node has not met the block height criteria, the request will either be awaited on the node's side (if the node supports this) or retried from the SDK side. The SDK will attempt to retry the request until it reaches the maximum number of retries and then throw an error.

This functionality is enabled by default but can be disabled as so:

```
import { Provider } from 'fuels';

Provider.ENABLE_RPC_CONSISTENCY = false;
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/scripts/configurable-constants.md.md

# Script With Configurable

In the same way as [contracts](../contracts/configurable-constants.md) and [predicates](../predicates/configurable-constants.md), Scripts also support configurable constants. This feature enables dynamic adjustment of certain values within your scripts.

Configurable constants are fairly straightforward to add and set in your scripts.

Let's consider the following script:

```
// #region encode-and-decode-1
script;

configurable {
    AMOUNT: u32 = 10,
}

fn main(inputted_amount: u32) -> u32 {
    inputted_amount + AMOUNT
}
// #endregion encode-and-decode-1
```

In this script, `AMOUNT` is a configurable constant with a default value of `10`. The main function returns the sum of the `inputted_amount` and the configurable constant `AMOUNT`.

To change the value of the `AMOUNT` constant, we can use the `setConfigurableConstants` method as shown in the following example:

```
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const script = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const configurableConstants = {
  AMOUNT: 81,
};

script.setConfigurableConstants(configurableConstants);

const inputtedValue = 10;

const { waitForResult } = await script.functions.main(inputtedValue).call();
const { value } = await waitForResult();

const expectedTotal = inputtedValue + configurableConstants.AMOUNT;
```

In this example, we're setting a new value `81` for the `AMOUNT` constant. We then call the main function with an inputted value of `10`.

The expectation is that the script will return the sum of the inputted value and the new value of `AMOUNT`.

This way, configurable constants in scripts allow for more flexibility and dynamic behavior during execution.

## Full Example

For a full example, see below:

```
import { Script, BN, Wallet, Provider } from 'fuels';

import { WALLET_PVT_KEY, LOCAL_NETWORK_URL } from '../../../env';
import { ScriptSum } from '../../../typegend/scripts/ScriptSum';

// #region script-with-configurable-contants-2
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const script = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const configurableConstants = {
  AMOUNT: 81,
};

script.setConfigurableConstants(configurableConstants);

const inputtedValue = 10;

const { waitForResult } = await script.functions.main(inputtedValue).call();
const { value } = await waitForResult();

const expectedTotal = inputtedValue + configurableConstants.AMOUNT;

// #endregion script-with-configurable-contants-2

const argument = 10;
const expected = 20;

// #region preparing-scripts
const myMainScript = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const tx = myMainScript.functions.main(argument);

// Set the call parameters
tx.callParams({ gasLimit: 7500 });

// Get the entire transaction request prior to
const txRequest = await tx.getTransactionRequest();

// Get the transaction ID
const chainId = await provider.getChainId();
const txId = txRequest.getTransactionId(chainId);

// Retrieve the value of the call and the actual gas used
const { waitForResult: waitForActualGasUsed } = await tx.call();
const { value: valueOfActualGasUsed, gasUsed: gasUsedOfActualGasUsed } =
  await waitForActualGasUsed();
// #endregion preparing-scripts
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/scripts/custom-script-call.md.md

# Preparing a Script Transaction

Akin to Contracts, we can configure the [call parameters](../contracts/call-parameters.md) and [transaction parameters](../transactions/adding-parameters.md) for Scripts, as well as retrieve the entire transaction request prior to submission.

```
const myMainScript = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const tx = myMainScript.functions.main(argument);

// Set the call parameters
tx.callParams({ gasLimit: 7500 });

// Get the entire transaction request prior to
const txRequest = await tx.getTransactionRequest();

// Get the transaction ID
const chainId = await provider.getChainId();
const txId = txRequest.getTransactionId(chainId);

// Retrieve the value of the call and the actual gas used
const { waitForResult: waitForActualGasUsed } = await tx.call();
const { value: valueOfActualGasUsed, gasUsed: gasUsedOfActualGasUsed } =
  await waitForActualGasUsed();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/scripts/deploying-scripts.md.md

# Deploying Scripts

In order to optimize the cost of your recurring script executions, we recommend first deploying your script. This can be done using the [Fuels CLI](../fuels-cli/index.md) and running the [deploy command](../fuels-cli/commands.md#fuels-deploy).

By deploying the script, its bytecode is stored on chain as a blob. The SDK will then produce bytecode that can load the blob on demand to execute the original script. This far reduces the repeat execution cost of the script.

## How to Deploy a Script

To deploy a script, we can use the [Fuels CLI](../fuels-cli/index.md) and execute the [deploy command](../fuels-cli/commands.md#fuels-deploy).

This will perform the following actions:

1. Compile the script using your `forc` version
1. Deploy the built script binary to the chain as a blob
1. Generate a script that loads the blob that can be used to execute the script
1. Generate types for both the script and the loader that you can use in your application

We can then utilize the above generated types like so:

```
const provider = new Provider(providerUrl);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// First, we will need to instantiate the script via it's loader bytecode. This can be imported from the typegen outputs
// that were created on `fuels deploy`
const script = new TypegenScriptLoader(wallet);

// Now we are free to interact with the script as we would normally, such as overriding the configurables
const configurable = {
  AMOUNT: 20,
};
script.setConfigurableConstants(configurable);

const { waitForResult } = await script.functions.main(10).call();
const { value, gasUsed } = await waitForResult();
console.log('value', value);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/scripts/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `
    https://docs.fuel.network/docs/sway/sway-program-types/scripts/#scripts-and-the-sdks
  `
</script>

# Scripts

A script, in Sway, is runnable bytecode on the chain which executes once to perform some task. A script can return a single value of any type.

Learn more about scripts <a :href="url" target="_blank" rel="noreferrer">here</a>.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/scripts/instantiating-a-script.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `
    https://docs.fuel.network/docs/sway/introduction/
  `
</script>

# Instantiating a script

Similar to contracts and predicates, once you've written a script in Sway and compiled it with `forc build` (read <a :href="url" target="_blank" rel="noreferrer">here</a> for more on how to work with Sway), you'll get the script binary. Using the binary, you can instantiate a `script` as shown in the code snippet below:

```
import type { BigNumberish } from 'fuels';
import { arrayify, Provider, ReceiptType, ScriptRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CallTestScript } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const script = new CallTestScript(wallet);

type MyStruct = {
  arg_one: boolean;
  arg_two: BigNumberish;
};

const scriptRequest = new ScriptRequest(
  CallTestScript.bytecode,
  (myStruct: MyStruct) => {
    const encoded = script.interface.functions.main.encodeArguments([myStruct]);

    return arrayify(encoded);
  },
  (scriptResult) => {
    if (scriptResult.returnReceipt.type === ReceiptType.Revert) {
      throw new Error('Reverted');
    }
    if (scriptResult.returnReceipt.type !== ReceiptType.ReturnData) {
      throw new Error('fail');
    }

    const [decodedResult] = script.interface.functions.main.decodeOutput(
      scriptResult.returnReceipt.data
    );
    return decodedResult;
  }
);
```

In the [next section](./running-scripts.md), we show how to run a script.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/scripts/logs.md.md

# Working with Script Logs

When you log a value within a script, you can generates a log entry that is added to the log receipt, and the variable type is recorded in the script's ABI. The SDK enables you to parse these values into TypeScript types.

## Simple

Consider the following example script:

```
script;

fn main(log_value: str[7]) -> str[7] {
    log(log_value);
    log_value
}
```

To access the logged values in TypeScript, use the `logs` property in the response of a script call.

```
import { Provider, Wallet } from 'fuels';

import { WALLET_PVT_KEY, LOCAL_NETWORK_URL } from '../../../env';
import { ScriptLogSimple } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const script = new ScriptLogSimple(wallet);
const { waitForResult } = await script.functions.main('ScriptA').call();

const { logs } = await waitForResult();
// logs: ['ScriptA']
```

## Grouped logs

Consider the following example script:

```
script;

use log_simple_abi::LogSimple;

fn main(contract_id: b256) {
    log("Script started");

    let log_contract = abi(LogSimple, contract_id);
    log_contract.log_simple(__to_str_array("ContractA"));

    log("Script finished");
}
```

### With Contract

To access the fine-grained logs for each contract, use the `groupedLogs` property from the script call response.

```
import { Provider, Wallet, ZeroBytes32 } from 'fuels';

import { WALLET_PVT_KEY, LOCAL_NETWORK_URL } from '../../../env';
import { LogSimpleFactory, ScriptLogWithContract } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Create a contract instance
const { waitForResult: waitForDeploy } = await LogSimpleFactory.deploy(wallet);
const { contract } = await waitForDeploy();

// Create a script instance
const script = new ScriptLogWithContract(wallet);

// Call the script
const { waitForResult } = await script.functions
  .main(contract.id.toB256())
  .addContracts([contract])
  .call();

// Wait for the script to finish and get the logs
const { groupedLogs } = await waitForResult();
// groupedLogs = {
//   [ZeroBytes32]: ['Script started', 'Script finished'],
//   [contract.id.toB256()]: ['ContractA', 'ContractB'],
// }
```

Although Scripts don't have IDs/addresses, they can still call contracts and generate logs, so we use a zeroed-out (hexadecimal) address as their key instead.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/scripts/running-scripts.md.md

# Running a script

Suppose your Sway script `main` function is written using the arguments passed to the `main` function like so:

```
script;

use std::logging::log;

fn main(foo: u8) -> u8 {
    log(__to_str_array("u8 foo"));
    log(foo);
    foo
}
```

You can still hand code out a solution wrapper using `callScript` utility to call your script with data. However, if you prefer to use the ABI generated from your script, you can use the `ScriptFactory` helper:

```
import { bn, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ScriptMainArgs } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const foo = 3;

const scriptInstance = new ScriptMainArgs(wallet);

const { waitForResult } = await scriptInstance.functions.main(foo).call();

const { value, logs } = await waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/advanced-example.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Advanced Example

A more complex example showcasing genesis block state configuration with [`walletsConfig`](./test-node-options.md#walletsconfig) and deployment of multiple contracts is shown below.

```
const assets = TestAssetId.random(2);
const message = new TestMessage({ amount: 1000 });

using counterContractNode = await launchTestNode({
  walletsConfig: {
    count: 4,
    assets,
    coinsPerAsset: 2,
    amountPerCoin: 1_000_000,
    messages: [message],
  },
  contractsConfigs: [
    {
      factory: CounterFactory,
      walletIndex: 3,
      options: { storageSlots: [] },
    },
  ],
});

const {
  contracts: [counterContract],
  wallets: [wallet1, wallet2, wallet3, wallet4],
} = counterContractNode;
```

## Summary

1. All points listed in the [basic example](./basic-example.md#summary) apply here as well.
1. Multiple wallets were generated with highly-specific coins and messages.
1. It's possible to specify the wallet to be used for contract deployment via `walletIndex`.
1. The test contract can be deployed with all the options available for real contract deployment.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/basic-example.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Basic Example

Let's use `launchTestNode` with the counter contract from the [Fuel dApp tutorial](../creating-a-fuel-dapp/index.md).

_Note: you will have to change the import paths of the contract factory and bytecode to match your folder structure._

```
import { CounterFactory } from '../../../typegend/contracts/CounterFactory';

using launchedContractNode = await launchTestNode({
  contractsConfigs: [CounterFactory],
});

const {
  contracts: [contract],
  provider,
  wallets,
} = launchedContractNode;

const { waitForResult } = await contract.functions.get_count().call();
const response = await waitForResult();
```

## Summary

1.  The `launched` variable was instantiated with the [`using`](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations) keyword.
1.  `launchTestNode` spun up a short-lived `fuel-core` node, deployed a contract to it and returned it for testing.
1.  The deployed contract is fully typesafe because of `launchTestNode`'s type-level integration with `typegen` outputs.
1.  Besides the contract, you've got the [provider](../provider/index.md) and [wallets](../wallets/index.md) at your disposal.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/custom-blocks.md.md

# Custom Blocks

You can force-produce blocks using the `produceBlocks` helper to achieve an arbitrary block height. This is especially useful when you want to do some testing regarding transaction maturity.

```
import { DateTime } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode();
const { provider } = launched;
const block = await provider.getBlock('latest');
if (!block) {
  throw new Error('No latest block');
}
const { time: timeLastBlockProduced } = block;

const producedBlockHeight = await provider.produceBlocks(3);

const producedBlock = await provider.getBlock(producedBlockHeight.toNumber());

const oldest = DateTime.fromTai64(timeLastBlockProduced);
const newest = DateTime.fromTai64(producedBlock!.time);
// newest >= oldest
```

# Blocks With Custom Timestamps

You can also produce blocks with a custom block time using the `produceBlocks` helper by specifying the second optional parameter.

```
using launchedWithCustomTimestamp = await launchTestNode();
const { provider: providerWithCustomTimestamp } = launchedWithCustomTimestamp;

const latestBlock = await providerWithCustomTimestamp.getBlock('latest');
if (!latestBlock) {
  throw new Error('No latest block');
}
const latestBlockTimestamp = DateTime.fromTai64(
  latestBlock.time
).toUnixMilliseconds();
const newBlockHeight = await providerWithCustomTimestamp.produceBlocks(
  3,
  latestBlockTimestamp + 1000
);
```

# Full Example

For a full example, see the following file:
```
// #region produce-blocks
import { DateTime } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode();
const { provider } = launched;
const block = await provider.getBlock('latest');
if (!block) {
  throw new Error('No latest block');
}
const { time: timeLastBlockProduced } = block;

const producedBlockHeight = await provider.produceBlocks(3);

const producedBlock = await provider.getBlock(producedBlockHeight.toNumber());

const oldest = DateTime.fromTai64(timeLastBlockProduced);
const newest = DateTime.fromTai64(producedBlock!.time);
// newest >= oldest
// #endregion produce-blocks

// #region produceBlocks-custom-timestamp
using launchedWithCustomTimestamp = await launchTestNode();
const { provider: providerWithCustomTimestamp } = launchedWithCustomTimestamp;

const latestBlock = await providerWithCustomTimestamp.getBlock('latest');
if (!latestBlock) {
  throw new Error('No latest block');
}
const latestBlockTimestamp = DateTime.fromTai64(
  latestBlock.time
).toUnixMilliseconds();
const newBlockHeight = await providerWithCustomTimestamp.produceBlocks(
  3,
  latestBlockTimestamp + 1000
);

// #endregion produceBlocks-custom-timestamp
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/fuel-core-options.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Fuel-Core Options

The `launchTestNode` creates a temporary snapshot directory and configurations every time it runs. The path to this directory is passed to `fuel-core` via the `--snapshot` flag.

## Default Snapshot

The default snapshot used is that of the current testnet network iteration.

Click [here](https://github.com/FuelLabs/fuels-ts/tree/master/.fuel-core/configs) to see what it looks like.

## Custom Snapshot

If you need a different snapshot, you can specify a `DEFAULT_CHAIN_SNAPSHOT_DIR` environment variable which points to your snapshot directory. `launchTestNode` will read that config and work with it instead, integrating all the functionality with it the same way it'd do with the default config.

How and where you specify the environment variable depends on your testing tool.

```
process.env.DEFAULT_CHAIN_SNAPSHOT_DIR = mySnapshotDirPath;

const launchedWithCustomChainConfig = await launchTestNode();

const { provider: providerWithCustomChainConfig } =
  launchedWithCustomChainConfig;

const { name } = await providerWithCustomChainConfig.fetchChain();
```

## Fuel-Core Node Options

Besides the snapshot, you can provide arguments to the `fuel-core` node via the `nodeOptions.args` property. For a detailed list of all possible arguments run:

```shell
fuel-core run --help
```

If you want _all_ your tests to run with the same arguments, consider specifying the `DEFAULT_FUEL_CORE_ARGS` environment variable.

```
process.env.DEFAULT_FUEL_CORE_ARGS = `--tx-max-depth 20`;

// `nodeOptions.args` will override the above values if provided.

const nodeWithCustomArgs = await launchTestNode();
const { provider: providerWithCustomArgs } = nodeWithCustomArgs;

process.env.DEFAULT_FUEL_CORE_ARGS = '';
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Testing

This guide will teach you how to test Sway applications using the Typescript SDK.

While we use [Vitest](https://vitest.dev/) internally, we don't enforce any specific testing library or framework, so you can pick whichever you feel comfortable with.

### Not using Typescript?

See also:

1. Using [`forc test`](https://docs.fuel.network/docs/forc/commands/forc%5ftest/#forc-test)
1. Using [the Rust SDK](https://docs.fuel.network/docs/fuels-rs/testing/)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/launching-a-test-node.md.md

# Launching a Test Node

To simplify testing in isolation, we provide a utility called `launchTestNode`.

It allows you to spin up a short-lived `fuel-core` node, set up a custom provider, wallets, deploy contracts, and much more in one go.

For usage information for `launchTestNode` including it's inputs, outputs and options, please check the [API reference](DOCS_API_URL/functions/_fuel_ts_contract.test_utils.launchTestNode.html).

## Explicit Resource Management

We support [explicit resource management](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations), introduced in TypeScript 5.2, which automatically calls a `cleanup` function after a variable instantiated with the `using` keyword goes out of block scope:

```
using launched = await launchTestNode();

/*
 * The method `launched.cleanup()` will be automatically
 * called when the variable `launched` goes out of block scope.
 */
```

### Configuring Typescript

To use [explicit resource management](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations), you must:

1.  Set your TypeScript version to `5.2` or above
2.  Set the compilation target to `es2022` or below
3.  Configure your lib setting to either include `esnext` or `esnext.disposable`

```json
{
  "compilerOptions": {
    "target": "es2022",
    "lib": ["es2022", "esnext.disposable"]
  }
}
```

## Standard API

If you don't want, or can't use [explicit resource management](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations), you can use `const` as usual.

In this case, remember you must call `.cleanup()` to dispose of the node.

```
const launchedTestNode = await launchTestNode();

/*
  Do your things, run your tests, and then call
  `launchedTestNode.cleanup()` to dispose of everything.
*/

launchedTestNode.cleanup();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/setting-up-test-wallets.md.md

# Setting up test wallets

You'll often want to create one or more test wallets when testing your contracts. Here's how to do it.

## Create a single wallet

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
```

## Setting up multiple test wallets

You can set up multiple test wallets using the `launchTestNode` utility via the `walletsConfigs` option.

To understand the different configurations, check out the [walletsConfig](./test-node-options.md#walletsconfig) in the test node options guide.

```
using launched = await launchTestNode({
  walletsConfig: {
    count: 3,
    assets: [TestAssetId.A, TestAssetId.B],
    coinsPerAsset: 5,
    amountPerCoin: 100_000,
  },
});

const {
  wallets: [wallet1, wallet2, wallet3],
} = launched;
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/testing/test-node-options.md.md

# Test Node Options

This reference describes all the options of the [`launchTestNode`](./launching-a-test-node.md) utility:

- [`walletsConfig`](./test-node-options.md#walletsconfig)
- [`contractsConfigs`](./test-node-options.md#contractsconfigs)
- [`nodeOptions`](./test-node-options.md#nodeoptions)
- [`providerOptions`](./test-node-options.md#provideroptions)

```
const customLaunchTestNode = await launchTestNode(/* options */);
```

Check out the [API reference](DOCS_API_URL/interfaces/_fuel_ts_contract.test_utils.LaunchTestNodeOptions.html) for usage information on the Test Node Options.

## `walletsConfig`

Used to set the node's genesis block state (coins and messages).

- `count`: number of wallets/addresses to generate on the genesis block.
- `assets`: configure how many unique assets each wallet will own with the base asset included. Can be `number` or `TestAssetId[]`.
  - The `TestAssetId` utility simplifies testing when different assets are necessary.
- `coinsPerAsset`: number of coins (UTXOs) per asset id.
- `amountPerCoin`: for each coin, the amount it'll contain.
- `messages`: messages to assign to the wallets.

### `walletsConfig.assets`

The `TestAssetId` utility integrates with [`walletsConfig`](./test-node-options.md#walletsconfig) and gives you an easy way to generate multiple random asset ids via the `TestAssetId.random` static method.

```
const randomAssetIds = TestAssetId.random();

const nodeWithCustomAssetIds = await launchTestNode({
  walletsConfig: {
    assets: randomAssetIds,
  },
});

const {
  wallets: [walletWithCustomAssetIds],
} = nodeWithCustomAssetIds;

const { coins } = await walletWithCustomAssetIds.getCoins(
  randomAssetIds[0].value
);
```

### `walletsConfig.messages`

The `TestMessage` helper class is used to create messages for testing purposes. When passed via `walletsConfig.messages`, the `recipient` field of the message is overriden to be the wallet's address.

```
const testMessage = new TestMessage({ amount: 1000 });

const nodeWithTestMessages = await launchTestNode({
  walletsConfig: {
    messages: [testMessage],
  },
});

const {
  wallets: [walletWithTestMessages],
} = nodeWithTestMessages;

const {
  messages: [messageWithTestMessages],
} = await walletWithTestMessages.getMessages();
```

It can also be used standalone and passed into the initial state of the chain via the `TestMessage.toChainMessage` instance method.

```
const recipient = WalletUnlocked.generate();
const testMessageOnChain = new TestMessage({
  amount: 1000,
  recipient: recipient.address,
});

using launchedWithTestMessagesOnChain = await launchTestNode({
  nodeOptions: {
    snapshotConfig: {
      stateConfig: {
        messages: [testMessageOnChain.toChainMessage()],
      },
    },
  },
});

const { provider: providerWithTestMessagesOnChain } =
  launchedWithTestMessagesOnChain;

recipient.provider = providerWithTestMessagesOnChain;

const {
  messages: [messageOnChain],
} = await recipient.getMessages();
```

## `contractsConfigs`

Used to deploy contracts on the node the `launchTestNode` utility launches. It's an array of objects with the following properties:

- `factory`: contract factory class outputted by `pnpm fuels typegen`.
- `walletIndex`: the index of the wallets generated by [`walletsConfig`](./test-node-options.md#walletsconfig) that you want to deploy the contract with.
- `options`: options for [contract deployment](../contracts/deploying-contracts.md#2-contract-deployment) that get passed to the [`ContractFactory.deploy`](DOCS_API_URL/classes/_fuel_ts_contract.index.ContractFactory.html#deploy) method.

## `nodeOptions`

<!-- TODO: will cross-reference work done in [#1915](https://github.com/FuelLabs/fuels-ts/issues/1915) -->

Options to modify the behavior of the node.

For example, you can specify your own base asset id of the chain like below:

```
const [baseAssetId] = TestAssetId.random();

const nodeWithCustomBaseAssetId = await launchTestNode({
  nodeOptions: {
    snapshotConfig: {
      chainConfig: {
        consensus_parameters: {
          V2: {
            base_asset_id: baseAssetId.value,
          },
        },
      },
    },
  },
});
```

_Note: The API for these options is still not fully complete and better documentation will come in the future._

## `providerOptions`

Provider options passed on `Provider` instantiation. More on them [here](../provider/provider-options.md).


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/the-utxo-model/index.md.md

# The UTXO Model

In UTXO (Unspent Transaction Output) based systems, each coin is unique, similar to how physical currency bills have different denominations.

A UTXO represents a coin with a specific amount, similar to having a $10 or $5 bill. It's crucial to understand this unique feature of UTXOs, as it differs significantly from Ethereum's account-based system.

In Ethereum, balances are tracked as cumulative totals, similar to a bank account, rather than as distinct 'coins' or 'bills'.

## Why UTXOs Matter

Each UTXO corresponds to a unique coin and has an associated amount. This model allows for greater transparency and control in cryptocurrency transactions. Understanding UTXOs is key for effectively managing and tracking your digital assets.

## How UTXOs Work

When you create a transaction, you will use UTXOs from your account to fund it. Here's a step-by-step explanation:

`1. Selecting UTXOs`: The SDK selects one or more UTXOs from your account that together are equal to or greater than the transaction amount plus the transaction fee.

`2. Spending UTXOs`: These selected UTXOs are used to fund the transaction and cover the transaction fee. For example, if you need to send $15 and the transaction fee is $1, and you have $10 and $6 UTXOs, both will be used.

`3. New UTXOs`: If the total value of the selected UTXOs exceeds the transaction amount plus the transaction fee, the difference is returned to your account as new UTXOs. For instance, if you spend a $20 UTXO for a $15 transaction with a $1 fee, a new UTXO worth $4 will be created as change and added back to your account.

In summary, the original UTXOs used in the transaction are marked as spent and cannot be used again. The new UTXOs are available for future transactions.

Suppose you have the following UTXOs in your account:

- $10 UTXO
- $20 UTXO

You want to send $15 to someone, and the transaction fee is $1. Here's what happens:

- The $20 UTXO is selected to fund the $15 transaction and cover the $1 fee.
- The transaction is completed and the $20 UTXO is spent.
- A new $15 UTXO is generated to the recipient, and a new $4 UTXO (change) is created and added to your account.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/adding-parameters.md.md

# Adding Parameters

Transaction parameters allow you to configure various aspects of your blockchain transactions. Dependent on these parameters, it may introduce a [transaction policy](./adding-policies.md).

All available parameters are shown below:

```
const txParams: TxParams = {
  // #region transaction-parameters-1
  gasLimit: bn(70935),
  // #endregion transaction-parameters-1
  // #region transaction-parameters-2
  maxFee: bn(69242),
  // #endregion transaction-parameters-2
  // #region transaction-parameters-3
  tip: bn(100),
  // #endregion transaction-parameters-3
  // #region transaction-parameters-4
  maturity: 1,
  // #endregion transaction-parameters-4
  // #region transaction-parameters-5
  witnessLimit: bn(5000),
  // #endregion transaction-parameters-5
  // #region transaction-parameters-6
  expiration: 200,
  // #endregion transaction-parameters-6
};
```

## Gas Limit

The maximum amount of gas you're willing to allow the transaction to consume. If the transaction requires more gas than this limit, it will fail.

```
  gasLimit: bn(70935),
```

## Max Fee

The maximum amount you're willing to pay for the transaction using the base asset. This allows users to set an upper limit on the transaction fee they are willing to pay, preventing unexpected high costs due to sudden network congestion or fee spikes.

```
  maxFee: bn(69242),
```

## Tip

An optional amount of the base asset to incentivise the block producer to include the transaction, ensuring faster processing for those willing to pay more. The value set here will be added to the transaction `maxFee`.

```
  tip: bn(100),
```

## Maturity

The number of blocks that must pass before the transaction can be included in a block. This is useful for time-sensitive transactions, such as those involving time-locked assets.

For example, if the chain produces a new block every second, setting Maturity to `10` means the transaction will be processed after approximately 10 seconds.

```
  maturity: 1,
```

## Witness Limit

The maximum byte length allowed for the transaction witnesses array. For instance, imagine a transaction that will deploy a contract. The contract bytecode will be one of the entries in the transaction witnesses. If you set this limit to `5000` and the contract bytecode length is `6000`, the transaction will be rejected because the witnesses bytes length exceeds the maximum value set.

```
  witnessLimit: bn(5000),
```

## Expiration

The block number after which the transaction can no longer be included in the blockchain. For example, if you set the expiration block for your transaction to 200, and the transaction remains in the queue waiting to be processed when block 200 is created, the transaction will be rejected.

```
  expiration: 200,
```

## Variable Outputs

The number of variable outputs that should be added to the transaction request. You can read more about it on this [guide](../contracts/variable-outputs.md)

> **Note**: Setting transaction parameters is optional. If you don't specify them, the SDK will fetch some sensible defaults from the chain.

## Setting Transaction Parameters

To set the transaction parameters, you have access to the `txParams` method on a transaction request.

```
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  gasLimit: 100,
});
```

The same method is also accessible within a function invocation scope, so it can also be used when calling contract functions.

```
const { waitForResult } = await contract.functions
  .increment_count(15) //
  .txParams(txParams)
  .call();

const {
  value,
  transactionResult: { isStatusSuccess },
} = await waitForResult();

console.log('Transaction request', transactionRequest);
console.log('Transaction status', isStatusSuccess);
console.log('Transaction value', value);
```

> **Note:** When performing an action that results in a transaction (e.g. contract deployment, contract call with `.call()`, asset transfer), the SDK will automatically estimate the fee based on the gas limit and the transaction's byte size. This estimation is used when building the transaction. As a side effect, your wallet must own at least one coin of the base asset, regardless of the amount.

## Full Example

Here is the full example of the transaction parameters:

```
import type { TxParams } from 'fuels';
import { bn, Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CounterFactory } from '../../../typegend';
import { ScriptSum } from '../../../typegend/scripts';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploy = await CounterFactory.deploy(wallet);

const { contract } = await deploy.waitForResult();

// #region transaction-parameters-7
const txParams: TxParams = {
  // #region transaction-parameters-1
  gasLimit: bn(70935),
  // #endregion transaction-parameters-1
  // #region transaction-parameters-2
  maxFee: bn(69242),
  // #endregion transaction-parameters-2
  // #region transaction-parameters-3
  tip: bn(100),
  // #endregion transaction-parameters-3
  // #region transaction-parameters-4
  maturity: 1,
  // #endregion transaction-parameters-4
  // #region transaction-parameters-5
  witnessLimit: bn(5000),
  // #endregion transaction-parameters-5
  // #region transaction-parameters-6
  expiration: 200,
  // #endregion transaction-parameters-6
};
// #endregion transaction-parameters-7

// #region transaction-parameters-8
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  gasLimit: 100,
});
// #endregion transaction-parameters-8

// #region transaction-parameters-9
const { waitForResult } = await contract.functions
  .increment_count(15) //
  .txParams(txParams)
  .call();

const {
  value,
  transactionResult: { isStatusSuccess },
} = await waitForResult();

console.log('Transaction request', transactionRequest);
console.log('Transaction status', isStatusSuccess);
console.log('Transaction value', value);

// #endregion transaction-parameters-9
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/adding-policies.md.md

# Adding Policies

Transaction policies are rules that can govern how a transaction is processed, introduced by the [transaction parameters](./adding-parameters.md) that you pass to a transaction request. The available policies are as follows:

### Tip

Optional amount on the base asset to incentivise block producer to include transaction, ensuring faster processing for those willing to pay more. The value set here will be added to the transaction `maxFee`.

### Witness Limit

The maximum byte length allowed for the transaction witnesses array.

### Maturity

The number of blocks that must pass before the transaction can be included in a block.

### Max Fee

The maximum amount you're willing to pay for the transaction using the base asset.

### Expiration

Block number after which the transaction can no longer be included in the blockchain.

## Setting Transaction Policies

The following snippet shows which transaction parameters correspond to which policies:

```
import { bn, ScriptTransactionRequest } from 'fuels';

const transactionRequest = new ScriptTransactionRequest({
  tip: bn(10), // Sets the tip policy
  witnessLimit: bn(1), // Sets the witness limit policy
  maturity: 1, // Sets the maturity policy
  maxFee: bn(1), // Sets the max fee policy
  expiration: 200, // Sets the block after which the transaction cannot be included.
});
```

## Retrieving Transaction Policies from a Transaction

Policies used for a transaction can be retrieved from a transaction using a `TransactionResponse`. The below snippet will show how to retrieve the policies from a transaction:

```
import type { Policy } from 'fuels';
import { Provider, Wallet, ScriptTransactionRequest, bn } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ScriptSum } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

/**
 * Instantiate the transaction request with transaction parameters
 * that will set the respective policies.
 */
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  gasLimit: bn(2000),
  tip: bn(10),
  witnessLimit: 900,
  maxFee: bn(2000),
  expiration: 200,
});

// Set the script main function arguments
const scriptArguments = [1];
transactionRequest.setData(ScriptSum.abi, scriptArguments);

// Fund the transaction
const resources = await wallet.getResourcesToSpend([
  { amount: 1000, assetId: await provider.getBaseAssetId() },
]);

transactionRequest.addResources(resources);

// Submit the transaction and retrieve the transaction response
const tx = await wallet.sendTransaction(transactionRequest);
const response = await tx.waitForResult();
const policies: Policy[] | undefined = response.transaction.policies;

console.log('policies', policies);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/assemble-tx-migration-guide.md.md

# AssembleTx Migrating Guide

The old methods of estimating and funding transaction were deprecated in favor of a more robust `provider.assembleTx`. This guide will help you migrate your code to use the new method.

## Migrating From `getTransactionCost` and `fund`

### Old Approach (Deprecated)

```
const transferAmount = 100;

const request = new ScriptTransactionRequest();

// Add a coin output to transfer 100 base asset to account
request.addCoinOutput(accountB.address, transferAmount, baseAssetId);

const txCost = await accountA.getTransactionCost(request);

request.maxFee = txCost.maxFee;
request.gasLimit = txCost.gasUsed;

await accountA.fund(request, txCost);

const tx = await accountA.sendTransaction(request);
const { isStatusSuccess } = await tx.waitForResult();
```

### New Approach

```
const transferAmount = 100;

const request = new ScriptTransactionRequest();
request.addCoinOutput(accountB.address, transferAmount, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: accountA,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: baseAssetId,
      account: accountA,
      changeOutputAccount: accountA,
    },
  ],
});

const tx = await accountA.sendTransaction(assembledRequest);
const { isStatusSuccess } = await tx.waitForResult();
```

### More Complex Transactions

Consider the following Sway script

```
script;

use std::asset::transfer;

fn main(
    contract_address: b256,
    asset_a: AssetId,
    amount_asset_a: u64,
    asset_b: AssetId,
    amount_asset_b: u64,
) -> bool {
    let wrapped_contract = ContractId::from(contract_address);
    let contract_id = Identity::ContractId(wrapped_contract);
    transfer(contract_id, asset_a, amount_asset_a);
    transfer(contract_id, asset_b, amount_asset_b);
    true
}
```

This script transfers two asset amounts to the same contract address. To ensure the transaction succeeds, it must be properly funded with the required amounts. This means we need to explicitly define how the transaction should be funded.

### Old Approach (Deprecated)

```
const transferAmountA = 400;
const transferAmountB = 600;

const script = new ScriptTransferToContract(account);

const request = await script.functions
  .main(
    contractId,
    { bits: TestAssetId.A.value },
    transferAmountA,
    { bits: TestAssetId.B.value },
    transferAmountB
  )
  .addContracts([contract])
  .getTransactionRequest();

const txCost = await account.getTransactionCost(request, {
  quantities: [
    {
      amount: bn(transferAmountA),
      assetId: TestAssetId.A.value,
    },
    {
      amount: bn(transferAmountB),
      assetId: TestAssetId.B.value,
    },
  ],
});

request.maxFee = txCost.maxFee;
request.gasLimit = txCost.gasUsed;

await account.fund(request, txCost);

const tx = await account.sendTransaction(request);
const { isStatusSuccess } = await tx.waitForResult();
```

### New Approach

```
const transferAmountA = 400;
const transferAmountB = 600;

const script = new ScriptTransferToContract(account);

const scope = script.functions
  .main(
    contractId,
    { bits: TestAssetId.A.value },
    transferAmountA,
    { bits: TestAssetId.B.value },
    transferAmountB
  )
  .assembleTxParams({
    feePayerAccount: account,
    accountCoinQuantities: [
      {
        amount: transferAmountA,
        assetId: TestAssetId.A.value,
        account,
        changeOutputAccount: account,
      },
      {
        amount: transferAmountB,
        assetId: TestAssetId.B.value,
        account,
        changeOutputAccount: account,
      },
    ],
  });

const { waitForResult } = await scope.call();

const {
  transactionResult: { isStatusSuccess },
} = await waitForResult();
```

By specifying which parameters `assembleTx` should use, we gain control over how the script call is estimated and funded.

## Migrating from `estimateAndFund`

### Old Code

```
const request = new ScriptTransactionRequest();

// Add a coin output to transfer 100 base asset to accountB
request.addCoinOutput(accountB.address, 100, baseAssetId);

// Estimate and fund the request
await request.estimateAndFund(accountA);

// Send the transaction
const tx = await accountA.sendTransaction(request);
await tx.waitForResult();
```

### New Code

```
const request = new ScriptTransactionRequest();

// Add a coin output to transfer 100 base asset to accountB
request.addCoinOutput(accountB.address, 100, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: accountA,
  accountCoinQuantities: [
    {
      amount: 100,
      assetId: baseAssetId,
      account: accountA,
      changeOutputAccount: accountA,
    },
  ],
});

const tx = await accountA.sendTransaction(assembledRequest);
await tx.waitForResult();
```

### Key Differences

1. **More Explicit Control**: `assembleTx` provides clearer control over which account pays fees and which accounts provide resources.

2. **Better Resource Management**: The new method allows you to specify exactly which accounts should provide which quantities of assets.

3. **Controlling Change Output**: When informing each account coin quantity you have control over determining who is going to receive a the change for that specific asset ID.

## Notes

- The methods `getTransactionCost` and `estimateAndFund` are deprecated and are going to be removed on futures updates
- The new method provides more predictable transaction assembly

## Additional Options

The new `assembleTx` method provides several additional options:

```
export type AssembleTxParams<T extends TransactionRequest = TransactionRequest> = {
  // The transaction request to assemble
  request: T;
  // Coin quantities required for the transaction, optional if transaction only needs funds for the fee
  accountCoinQuantities?: AccountCoinQuantity[];
  // Account that will pay for the transaction fees
  feePayerAccount: Account;
  // Block horizon for gas price estimation (default: 10)
  blockHorizon?: number;
  // Whether to estimate predicates (default: true)
  estimatePredicates?: boolean;
  // Resources to be ignored when funding the transaction (optional)
  resourcesIdsToIgnore?: ResourcesIdsToIgnore;
  // Amount of gas to reserve (optional)
  reserveGas?: BigNumberish;
};

export type AssembleTxResponse<T extends TransactionRequest = TransactionRequest> = {
  assembledRequest: T;
  gasPrice: BN;
  receipts: TransactionResultReceipt[];
  rawReceipts: TransactionReceiptJson[];
};
```

You can read more about the `assembleTx` [here](./index.md).


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/assemble-tx.md.md

# AssembleTx

The `assembleTx` method is a crucial part of the Fuel TypeScript SDK that helps prepare and assemble transactions with the correct inputs, outputs, and policies. It is used by all higher-level APIs in the SDK, including account transfers, contract and blob deployments, and contract calls. This guide provides a comprehensive overview of how to use `assembleTx` effectively.

## Overview

The `assembleTx` method takes a transaction request and assembles it with the necessary inputs, outputs, and policies based on the provided parameters. It handles:

- Coin quantity for different assets
- Fee payer account
- Gas and fee estimation
- Predicate estimation
- Resource exclusion (specific resources to ignore)

## Parameters

The [AssembleTxParams](DOCS_API_URL/types/_fuel_ts_account.AssembleTxParams.html) interface includes the following parameters:

```
export type AssembleTxParams<T extends TransactionRequest = TransactionRequest> = {
  // The transaction request to assemble
  request: T;
  // Coin quantities required for the transaction, optional if transaction only needs funds for the fee
  accountCoinQuantities?: AccountCoinQuantity[];
  // Account that will pay for the transaction fees
  feePayerAccount: Account;
  // Block horizon for gas price estimation (default: 10)
  blockHorizon?: number;
  // Whether to estimate predicates (default: true)
  estimatePredicates?: boolean;
  // Resources to be ignored when funding the transaction (optional)
  resourcesIdsToIgnore?: ResourcesIdsToIgnore;
  // Amount of gas to reserve (optional)
  reserveGas?: BigNumberish;
};

export type AssembleTxResponse<T extends TransactionRequest = TransactionRequest> = {
  assembledRequest: T;
  gasPrice: BN;
  receipts: TransactionResultReceipt[];
  rawReceipts: TransactionReceiptJson[];
};
```

### Parameter Details

- `request`: The transaction request to be assembled.
- `blockHorizon`: The number of blocks to look ahead for gas price estimation. Defaults to `10` blocks.
- `feePayerAccount`: The account that will pay for the transaction fees
- `accountCoinQuantities`: An array of coin quantities needed for the transaction. This is optional if the transaction only requires funds to cover the fee. The parameters are:
  - `amount`: The amount of coins needed (fee value does need to be included)
  - `assetId`: The asset ID of the coins
  - `account`: The account providing the coins (optional, defaults to `feePayerAccount`)
  - `changeOutputAccount`: The account to receive change (optional, defaults to the `account` or `feePayerAccount` properties, respectively)
- `resourcesIdsToIgnore`: Resources to be ignored when funding the transaction (UTXOs or messages)
- `estimatePredicates`: Whether to estimate gas for predicates
- `reserveGas`: Additional Amount of gas to be set for the transaction

### Default Behaviors for Account Properties

The `accountCoinQuantities` entries have two optional properties with specific default behaviors:

1. `account` property:

   - If not provided, defaults to the root `feePayerAccount`
   - Used to specify which account provides the resources for the transaction

2. `changeOutputAccount` property:
   - If not provided, defaults to the `account` property
   - Used to specify which account receives the change from all spent resources from a specific `assetId`

Example of default behaviors:

```
import { Provider, Wallet, type AccountCoinQuantity } from 'fuels';
import { TestAssetId } from 'fuels/test-utils';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
  WALLET_PVT_KEY_3,
} from '../../../../env';

// #region transaction-request-3
const provider = new Provider(LOCAL_NETWORK_URL);
const accountA = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const accountB = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);
const accountC = Wallet.fromPrivateKey(WALLET_PVT_KEY_3, provider);
const baseAssetId = await provider.getBaseAssetId();
const accountCoinQuantities: AccountCoinQuantity[] = [
  {
    amount: 100,
    assetId: baseAssetId,
    // account defaults to feePayerAccount
    // changeOutputAccount defaults to feePayerAccount
  },
  {
    amount: 200,
    assetId: TestAssetId.A.value,
    account: accountA,
    // changeOutputAccount defaults to accountA
  },
  {
    amount: 300,
    assetId: TestAssetId.B.value,
    account: accountB,
    changeOutputAccount: accountC,
    // Both account and changeOutputAccount are explicitly set
  },
];
```

## Return Value

The method returns an object of the type [AssembleTxResponse](DOCS_API_URL/types/_fuel_ts_account.AssembleTxResponse.html):

- `assembledRequest`: The fully assembled transaction request with all necessary inputs, outputs, and policies
- `gasPrice`: The estimated gas price for the transaction
- `receipts`: Parsed receipts returned from the transaction dry run.
- `rawReceipts`: Unparsed receipts returned from the transaction dry run.

## Usage Example

```
const request = new ScriptTransactionRequest();

request.addCoinOutput(accountB.address, transferAmount, baseAssetId);

const accountCoinQuantities: AccountCoinQuantity[] = [
  {
    amount: transferAmount,
    assetId: baseAssetId, // Asset ID
    account: accountA,
    changeOutputAccount: accountA, // Optional
  },
];

// Assemble the transaction
const { assembledRequest, gasPrice, receipts } = await provider.assembleTx({
  request,
  accountCoinQuantities,
  feePayerAccount: accountA,
  blockHorizon: 10,
  estimatePredicates: true,
});

// The assembledRequest is now ready to be signed and sent
const submit = await accountA.sendTransaction(assembledRequest);
await submit.waitForResult();
```

## Attention to `account` and `changeOutputAccount` Fields

As mentioned earlier, the `account` and `changeOutputAccount` fields are optional in the `accountCoinQuantities` entries. However, **special attention must be paid to** `changeOutputAccount` due to how change from spent resources works on Fuel.

In Fuel, only one `OutputChange` is allowed per `assetId` in a transaction. But what exactly is an `OutputChange`? In simple terms, it designates the recipient of the leftover funds ("change") after all UTXO resources for a specific `assetId` have been spent.

### Understanding Change in Fuel's UTXO Model

Because Fuel uses a **UTXO-based model** (unlike Ethereum’s account-based model), transactions will spend all included UTXOs, even if only a small portion is actually required. For example, suppose you have a single UTXO worth 10 ETH. If you create a transaction to send just 1 Gwei, the entire 10 ETH UTXO will be consumed. The transaction will then:

- Create a UTXO with 1 Gwei to the recipient.
- Create another UTXO for the remaining amount (i.e., 10 ETH - 1 Gwei - fee), sent to the address defined in the `OutputChange`.

In this context, the `OutputChange` ensures that **you receive the change** from your transaction.

### Fuel's Constraint: One Change Output per `assetId`

A key rule in Fuel is that only one `OutputChange` per `assetId` is allowed per transaction. This becomes particularly important when a transaction includes resources from **multiple accounts** that hold the same `assetId` (e.g., ETH). In such a case, **only one account can receive the change**, whichever one is defined on the `OutputChange`.

If not managed correctly, this can lead to unintended behavior, such as one account spending its funds while another receives the leftover balance.

### How This Relates to `assembleTx`

The `changeOutputAccount` field in `assembleTx` explicitly specifies **which account should receive the change** for a particular `assetId`. This is critical when you're using resources from multiple accounts in the same transaction.

Here's an example:

```
let { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: accountA,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: baseAssetId,
      account: accountB,
      /**
       * accountB will receive the change. Although it is explicitly set here,
       * if it were not set, it would default to the account property,
       * which in this case is also accountB.
       */
      changeOutputAccount: accountB,
    },
  ],
});
```

In the example above:

- Resources from `accountB` are being explicitly requested in `accountCoinQuantities`.
- `accountA` is listed as the `feePayerAccount`, meaning it will also contribute resources to cover fees.
- `changeOutputAccount` is explicitly set to `accountB`.

As a result, `accountB` will receive the change, even if UTXOs from `accountA` are spent in the transaction.

This means that if `accountA` contributes a 10 ETH UTXO, the transaction will spend the full 10 ETH. The leftover amount (change) will be sent to `accountB`, not back to `accountA`, because `changeOutputAccount`is set to `accountB`.

## Best Practices

1. Always provide the correct `feePayerAccount` that has sufficient funds for the transaction fees
2. Pay special attention to change outputs when dealing with multiple accounts and the same asset ID:
   - In Fuel, only one change output is allowed per asset ID
   - If a transaction includes resources from the same asset ID for multiple accounts, only one account will receive the change from all spent resources
   - Make sure to coordinate with all parties involved to determine which account should receive the change output

## Notes

- The method automatically handles base asset requirements for fees
- It performs a dry run to validate the transaction before returning
- The assembled transaction will include all necessary inputs and outputs based on the provided coin quantities
- Gas and fee estimation is performed using the specified block horizon


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/getting-the-response.md.md

# Transaction Response

Once a transaction has been submitted, you may want to extract information regarding the result of the transaction. The SDK offers a `TransactionResponse` class with helper methods to expose the following information:

- The transaction ID
- The status (submitted, success, squeezed out, or failure)
- Receipts (return data, logs, mints/burns, transfers and panic/reverts)
- Operations (contract calls, transfers, withdrawals)
- Gas fees and usages
- Date and time of the transaction
- The block the transaction was included in

We can easily extract this information from a contract call:

```
// Call a contract function
const call = await contract.functions.increment_count(15).call();

// Wait for the result
const { transactionResponse } = await call.waitForResult();

// Retrieve the full transaction summary
const transactionSummary = await transactionResponse.getTransactionSummary({
  // Pass a Contract ID and ABI map to generate the contract operations
  [contract.id.toB256()]: Counter.abi,
});
```

We can also use the result of a transaction request to extract a transaction summary:

```
/**
 * Instantiate the transaction request using a ScriptTransactionRequest and
 * set the script main function arguments
 */
const request = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

request.setData(ScriptSum.abi, [1]);

// Estimate and funding the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: await provider.getBaseAssetId(),
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Submit the transaction
const response = await wallet.sendTransaction(assembledRequest);

// Generate the transaction summary
const transactionSummary = await response.getTransactionSummary();
```

Or we can build a transaction summary from a stored transaction ID:

```
// Take a transaction ID from a previous transaction
const transactionId = previouslySubmittedTransactionId;
// 0x...

// Retrieve the transaction response from the transaction ID
const transactionResponse = await TransactionResponse.create(
  transactionId,
  provider
);

// Generate the transaction summary
const summary = await transactionResponse.getTransactionSummary();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/index.md.md

# Transactions

A transaction is a way of interacting with a Fuel blockchain and can include actions like transferring assets, deploying contracts and minting tokens. All of which are possible through the SDK by using simple utility methods or building out more custom transactions.

Transferring assets is the most common transaction type and can be be executed by calling the `transfer` function from an account to a recipient address:

```
const tx = await sender.transfer(receiver.address, 100, assetId);
await tx.waitForResult();

const newBalance = await receiver.getBalance(assetId);
// 100
```

Deploying and interacting with contracts are other common transactions. More information on this can be found in the [contracts guide](../contracts/index.md), either through the [contract deployment guide](../contracts/deploying-contracts.md) or the [contract interaction guide](../contracts/methods.md).

This guide will discuss how to create and modify transactions to fit bespoke use cases, as well as submit them to the network using transactional policies and parameters. As well as retrieving information about submitted transactions.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/modifying-the-request.md.md

# Transaction Request

A transaction request provides the foundations for submitting a transaction and interacting with the blockchain.

Within Fuel, we have the following transaction types:

- Script
- Create
- Mint

The SDK provides class helpers for handling script and create transactions: `ScriptTransactionRequest` and `CreateTransactionRequest`, respectively.

> **Note**: Mint transactions can only be created by the block producer and do not have any use outside of block creation. Therefore, the SDK only provides the ability to decode them.

## Creating a Transaction Request

To create a transaction request, you must first instantiate either a `ScriptTransactionRequest` or `CreateTransactionRequest`.

A `ScriptTransactionRequest` is used for script transactions, which allows you to execute bytecode on chain to perform a task or chain of tasks. Within the SDK they can be created like so:

```
import {
  CreateTransactionRequest,
  ScriptTransactionRequest,
  ZeroBytes32,
} from 'fuels';

import { ScriptSum } from '../../../../typegend';

// Instantiate the transaction request using a ScriptTransactionRequest
const scriptTransactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const scriptData = [1];

// Set the script main function arguments (can also be passed in the class constructor)
scriptTransactionRequest.setData(ScriptSum.abi, scriptData);
```

A `CreateTransactionRequest` is used for create transactions, which are transactions that create a new contract on the blockchain.

```
// Instantiate the transaction request using a CreateTransactionRequest
const createTransactionRequest = new CreateTransactionRequest({
  witnesses: [contractByteCode],
});
```

> **Note**: We recommend you use the `ContractFactory` for contract deployment as this will shape the create transaction request for you. Information on this can be found in the [contract deployment guide](../contracts/deploying-contracts.md#2-contract-deployment).

## Modifying a Transaction Request

Once you have instantiated a transaction request, you can modify it by setting the transaction parameters and policies. This can either be done manually by directly altering the transaction request object, or through helper methods that are available on the above classes.

### Adding `OutputCoin`

Including `OutputCoin`s in the transaction request specifies the UTXOs that will be created once the transaction is processed. These UTXOs represent the amounts being transferred to specified account addresses during the transaction:

```
const provider = new Provider(LOCAL_NETWORK_URL);

const recipient1 = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient2 = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const baseAssetId = await provider.getBaseAssetId();
const assetA = TestAssetId.A.value;

const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

transactionRequest.addCoinOutput(recipient1.address, 1000, baseAssetId);
transactionRequest.addCoinOutput(recipient2.address, 500, assetA);
```

### Estimating and Funding the Transaction Request

Before submitting a transaction, ensure it is fully funded to meet its requirements and cover the associated fees. The `assembleTx` method handles this by returning a fully funded and estimated transaction, ready for submission.

```
const transferAmount = 1000;

const request = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const baseAssetId = await provider.getBaseAssetId();

request.addCoinOutput(wallet.address, transferAmount, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: baseAssetId,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

await wallet.sendTransaction(assembledRequest);
```

### Manually Fetching Resources

In certain scenarios, you may need to manually fetch resources. This can be achieved using the `getResourcesToSpend` method, which accepts an array of `CoinQuantities` and returns the necessary resources to meet the specified amounts:

```
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const baseAssetId = await provider.getBaseAssetId();
const assetA = TestAssetId.A.value;

// Define the quantities to fetch
const quantities: CoinQuantity[] = [
  {
    amount: bn(10000),
    assetId: baseAssetId,
  },
  {
    amount: bn(100),
    assetId: assetA,
  },
];

// Fetching resources
const resources = await wallet.getResourcesToSpend(quantities);

// Adding resources (coins or messages)
transactionRequest.addResources(resources);
```

#### Manually Fetching Coins or Messages

If needed, you can manually include specific coins or messages in the transaction. However, this approach is generally discouraged and should only be used in scenarios where explicitly adding particular coins or messages to the transaction request is required:

```
// Fetching coins
const { coins } = await wallet.getCoins(baseAssetId);
const { messages } = await wallet.getMessages();

// Adding a specific coin or message
transactionRequest.addCoinInput(coins[0]);
transactionRequest.addMessageInput(messages[0]);
```

### Adding a Contract Input and Output to a Transaction Request

Imagine that you have a Sway script that manually calls a contract:

```
use counter::CounterAbi;
fn main(contract_id: ContractId) -> u64 {
    let counter_contract = abi(CounterAbi, contract_id.into());
    counter_contract.get_count()
}
```

In those cases, you will need to add both an `InputContract` and `OutputContract` to the transaction request:

```
const deploy = await CounterFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  scriptData: contract.id.toB256(),
});

// Add the contract input and output using the contract ID
transactionRequest.addContractInputAndOutput(contract.id);
```

### Adding a Predicate to a Transaction Request

Predicates are used to define the conditions under which a transaction can be executed. Therefore you may want to add a predicate to a transaction request to unlock funds that are utilized by a script. This can be added like so:

```
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const predicateArguments = [ZeroBytes32];

/**
 * Instantiate the predicate and pass valid input data to validate
 * the predicate and unlock the funds
 */
const predicate = new Predicate({
  bytecode: SimplePredicate.bytecode,
  abi: SimplePredicate.abi,
  data: predicateArguments,
  provider,
});

// Fund the predicate
const tx = await wallet.transfer(predicate.address, bn(100_000));
await tx.waitForResult();

const predicateCoins = await predicate.getResourcesToSpend([
  { amount: 2000, assetId: await provider.getBaseAssetId() },
]);

// Add the predicate input and resources
transactionRequest.addResources(predicateCoins);
```

> **Note**: For more information on predicates, including information on configuring them, funding them and using them to unlock funds, please refer to the [predicate guide](../predicates/index.md).

### Adding a Witness and Signing a Transaction Request

The SDK provides a way of either modifying the witnesses for a transaction request directly, or by passing accounts. This will then sign the transaction request with the account's private key. Below will detail how to add a witness to a transaction request:

```
const provider = new Provider(LOCAL_NETWORK_URL);
const accountA = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const accountB = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

// Add a witness directly
// Add a witness signature directly
const signature = await accountA.signTransaction(transactionRequest);
transactionRequest.addWitness(signature);

// Or add multiple via `addAccountWitnesses`
await transactionRequest.addAccountWitnesses([accountB]);
```

A more complex example would when signatures are validated inside the script itself, like this guide [here](../cookbook/sway-script-with-signature-validation.md), .

> **Note**: Once `addAccountWitnesses` has been called, any additional modifications to the transaction request will invalidate the signature as the transaction ID changes. Therefore, it is recommended to add witnesses last.

### Getting the Transaction ID for a Transaction Request

The transaction ID is a SHA-256 hash of the entire transaction request. This can be useful for tracking the transaction on chain. To get the transaction ID, you can use the following method:

```
// Get the chain ID
const chainId = await provider.getChainId();

// Get the transaction ID using the Chain ID
const transactionId = transactionRequest.getTransactionId(chainId);
// TX ID: 0x420f6...
```

> **Note**: Any changes made to a transaction request will alter the transaction ID. Therefore, you should only get the transaction ID after all modifications have been made.

### Burning assets

Assets can be burnt as part of a transaction that has inputs without associated output change. The SDK validates against this behavior, so we need to explicitly enable this by sending the transaction with the `enableAssetBurn` option set to `true`.

```
const baseAssetId = await provider.getBaseAssetId();
const request = new ScriptTransactionRequest();

const {
  coins: [coin],
} = await sender.getCoins(ASSET_A);

// Add the coin as an input, without a change output
request.addResource(coin);

/**
 * Remove the OutputChange for the specific assetId as it is always added by default
 * when using 'addResource'
 */
request.outputs = request.outputs.filter(
  (output) =>
    output.type !== OutputType.Change || String(output.assetId) !== ASSET_A
);

// Fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: sender,
  accountCoinQuantities: [
    {
      amount: '0',
      assetId: baseAssetId,
      account: sender,
      changeOutputAccount: sender,
    },
  ],
});

// Send the transaction with asset burn enabled
const tx = await sender.sendTransaction(assembledRequest, {
  enableAssetBurn: true,
});
```

> **Note**: Burning assets is permanent and all assets burnt will be lost. Therefore, be mindful of the usage of this functionality.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/optimizing-frontend-apps.md.md

# Optimizing Frontend Apps

Your application must perform a series of operations to estimate, submit and receive the result of a transaction. However, the flow in which it performs these actions can be organized or performed optimistically, increasing it's perceived speed.

## Use Case

In a frontend application, imagine we have a button that executes a contract call:

```tsx
<Button onClick={handleSubmit}>Submit</Button>
```

The handler would be implemented as follows:

```
async function handleSubmit() {
  // 1. Calling the `call` function for a contract method will create
  // a transaction request, estimate it, fund it and then submit it
  const transaction = await contract.functions.increment_count(1).call();
  info(`Transaction ID Submitted: ${transaction.transactionId}`);

  // 2. Calling `waitForResult` will wait for the transaction to
  // settle, then assemble and return it
  const result = await transaction.waitForResult();
  info(`Transaction ID Successful: ${result.transactionId}`);
}
```

Once the user clicks the button, multiple sequential calls are made to the network, which can take a while because the transaction must be:

1. Estimated
1. Funded
1. Submitted

## Optimization Strategy

With a few optimizations, the flow can be organized as follows:

```
/**
 * Here we'll prepare our transaction upfront on page load, so that
 * by the time the user interacts with your app (i.e. clicking a btn),
 * the transaction is ready to be submitted
 */
async function onPageLoad() {
  // 1. Invoke the contract function whilst estimating and funding the
  // call, which gives us the transaction request
  request = await contract.functions.increment_count(1).fundWithRequiredCoins();
}

/**
 * By the time user user clicks the submit button, we only need to
 * submit the transaction to the network
 */
async function handleSubmit() {
  // 1. Submit the transaction to the network
  info(`Transaction ID Submitted: ${request.getTransactionId(chainId)}`);
  const response = await wallet.sendTransaction(request);

  // 2. Wait for the transaction to settle and get the result
  const result = await response.waitForResult();
  info(`Transaction ID Successful: ${result.id}`);
}
```

## Conclusion

Finally, when users click the button, they only need to submit the transaction, which vastly improves the perceived speed of the transaction because many of the necessary requests were done upfront, under the hood.

Just remember:

- _After preparation, any changes made to the transaction request will require it to be re-estimated and re-funded before it can be signed and submitted._

# See Also

- Check a full example at [Optimized React Example](../cookbook/optimized-react-example.md)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/transactions/pre-confirmations.md.md

# Pre-Confirmations

## What is a Pre-Confirmation?

A **pre-confirmation** is an intermediate transaction status that occurs after a transaction has been **submitted** and **accepted** by the blockchain, but **before** it is fully **processed and included** in a new block.

At this stage, the transaction is pre-executed and assigned one of two possible statuses:

- `PreconfirmationSuccessStatus`: The transaction is expected to be successfully included in a future block.

- `PreconfirmationFailureStatus`: The transaction will **not** be included in any future block.

## Why are Pre-Confirmations important?

Pre-confirmations allow applications to **react earlier** by providing immediate feedback about a transaction's expected outcome without waiting for full block finalization.

Additionally, pre-confirmations expose **processed outputs** (such as `OutputChange` and `OutputVariable`) that can be **immediately reused** in new transactions.

## Available Outputs for Pre-Confirmations

When a transaction reaches the **pre-confirmation** stage, certain `resolvedOutputs` become available:

- `OutputChange`: Represents the change UTXO generated from unspent inputs, grouped by `assetId` (one per asset).

- `OutputVariable`: Similar to `OutputCoin`, but only created if the transaction succeeds.

These outputs can be:

- Extracted directly from the pre-confirmation response.
- **Used immediately** to fund new transactions, without waiting for block confirmation.

This significantly improves the ability to build transaction sequences or reactive transaction flows.

This is the `ResolvedOutput` interface structure:

```
export type ResolvedOutput = {
  utxoId: string;
  output: OutputChange | OutputVariable;
};
```

## Example Workflow

Suppose you send a transaction that will send funds to another wallet.

As soon as you receive a `PreconfirmationSuccessStatus`, you can:

- Use the `OutputChange` in a new transaction.
- Submit the next transaction **without waiting** for block finalization.

This reduces wait times and accelerates transaction chaining.

## Code Examples

### Using Pre-Confirmations when Submitting a Transfer

The following example sends a transfer, waits for the pre-confirmation success, and then submits another transfer using the resolved outputs from the first:

```
const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient1 = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);
const recipient2 = Wallet.fromPrivateKey(WALLET_PVT_KEY_3, provider);
const baseAssetId = await provider.getBaseAssetId();

// Send a transfer and retrieve the pre-confirmation callback
const { waitForPreConfirmation } = await wallet.transfer(
  recipient1.address,
  1000
);

// Wait for the transaction to reach a pre-confirmation status
const { resolvedOutputs, isStatusPreConfirmationSuccess } =
  await waitForPreConfirmation();

// Check if the pre-confirmation status indicates success
if (isStatusPreConfirmationSuccess) {
  // Find the change output associated with the base asset ID
  const resolvedChangeOutput = resolvedOutputs?.find(
    (resolved) =>
      resolved.output.type === OutputType.Change &&
      resolved.output.assetId === baseAssetId
  );

  // If we find the change output, we can use it to create a new transaction
  if (resolvedChangeOutput) {
    const { output, utxoId } = resolvedChangeOutput;

    // Create a new transaction request
    const newTransaction = new ScriptTransactionRequest({
      maxFee: 1000,
      gasLimit: 1000,
    });

    // Add the change output as an input resource for the new transaction
    newTransaction.addResource({
      id: utxoId,
      assetId: output.assetId,
      amount: output.amount,
      owner: new Address(output.to),
      blockCreated: bn(0),
      txCreatedIdx: bn(0),
    });

    // Define the transfer recipient of the new transaction
    newTransaction.addCoinOutput(recipient2.address, 1000, baseAssetId);

    // Send the new transaction
    await wallet.sendTransaction(newTransaction);
  }
}
```

### Using Pre-Confirmations with a Contract Call

This example performs a contract call, waits for pre-confirmation success, and then uses the resolved output to execute another contract call:

```
// Send a contract call and retrieve the pre-confirmation callback
const { waitForPreConfirmation } = await contract.functions
  .increment_count(1)
  .call();

const {
  transactionResult: { resolvedOutputs, isStatusPreConfirmationSuccess },
} = await waitForPreConfirmation();

// Check if the pre-confirmation status indicates success
if (isStatusPreConfirmationSuccess) {
  // Find the change output associated with the base asset ID
  const resolvedChangeOutput = resolvedOutputs?.find(
    (resolved) =>
      resolved.output.type === OutputType.Change &&
      resolved.output.assetId === baseAssetId
  );

  // If we find the change output, we can use it to create a new transaction
  if (resolvedChangeOutput) {
    const { output, utxoId } = resolvedChangeOutput;

    // Creates a new scope invocation for another contract call
    const scope = contract.functions.increment_count(1).txParams({
      maxFee: 100_000,
      gasLimit: 100_000,
    });

    // Get the transaction request from the scope invocation
    const request = await scope.getTransactionRequest();

    // Add the change output as an input resource for the new transaction
    request.addResource({
      id: utxoId,
      assetId: output.assetId,
      amount: output.amount,
      owner: new Address(output.to),
      blockCreated: bn(0),
      txCreatedIdx: bn(0),
    });

    /**
     * Call the scope invocation and skip the assembleTx step since the transaction
     * request is already funded
     */
    await scope.call({ skipAssembleTx: true });
  }
}
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/address.md.md

# Address

In Sway, the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) type serves as a type-safe wrapper around the primitive `B256` type. The SDK takes a different approach and has its own abstraction for the [Address](DOCS_API_URL/classes/_fuel_ts_address.Address.html) type.

## Address Class

The [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class also provides a set of utility functions for easy manipulation and conversion between address formats along with one property; `b256Address`, which is of the [`B256`](./b256.md) type.

```
  readonly b256Address: B256Address;
```

## Creating an Address

There are several ways to create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) instance:

### From a b256 address

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from a 256-bit address, use the following code snippet:

```
import { Address } from 'fuels';
// #region b256-1
const b256 =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';
// #endregion b256-1

const address = new Address(b256);

console.log('b256', address.toB256());
// 0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6
```

### From a Public Key

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from a public key, use the following code snippet:

```
import { Address, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.generate({ provider });

const address = new Address(wallet.publicKey);
```

### From an EVM Address

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from an EVM address, use the following code snippet:

```
import { Address } from 'fuels';

const evmAddress = '0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c';

const address = new Address(evmAddress);
```

### From an existing Address

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from an existing [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) instance, use the following code snippet:

```
import { Address } from 'fuels';

const address = Address.fromRandom();

const addressClone = new Address(address);
```

## Utility functions

### `equals`

As you may already notice, the `equals` function can compare addresses instances:

```
import { Address } from 'fuels';

const address = Address.fromRandom();

const address1 = new Address(address.toString());
const address2 = new Address(address.toB256());

console.log('equals', address1.equals(address2));
// true
```

### `toChecksum`

To convert an address to a checksum address, use the `toChecksum` function:

```
import { Address } from 'fuels';

const b256 =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';

const address = new Address(b256);

console.log('checksum', address.toChecksum());
// true
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/arrays.md.md

# Arrays

In Sway, an `Array` is a fixed-size collection of elements of the same type, similar to a `Tuple`. `Arrays` can hold arbitrary types, including non-primitive types, with their size determined at compile time.

## Using Arrays in the SDK

You can pass a TypeScript `Array` into your contract method seamlessly just like you would pass an `Array` to a TypeScript function.

The SDK handles the conversion from TypeScript to Sway in the background, allowing the expected data to be passed through the type regardless of the `Array` type.

An `Array` in Sway is simply a typed `Array`, as demonstrated in the following example:

```
// in Sway: [u8; 5]
const numberArray: number[] = [1, 2, 3, 4, 5];

// in Sway: [bool; 3]
const boolArray: boolean[] = [true, false, true];
```

In Sway, `Arrays` are fixed in size, so the storage size is determined at the time of program compilation, not during runtime.

Let's say you have a contract that takes an `Array` of type `u64` with a size length of 2 as a parameter and returns it:

```
    fn echo_u64_array(u64_array: [u64; 2]) -> [u64; 2] {
        u64_array
    }
```

To execute the contract call using the SDK, you would do something like this:

```
const u64Array: [BigNumberish, BigNumberish] = [10000000, 20000000];

const { value } = await contract.functions.echo_u64_array(u64Array).get();

console.log('value', value);
// [<BN: 0x989680>, <BN: 1312D00>]
```

You can easily access and validate the `Array` returned by the contract method, as demonstrated in the previous example.

As previously mentioned, Sway `Arrays` have a predefined type and size, so you need to be careful when passing `Arrays` as parameters to contract calls.

Passing an Array with an incorrect size, whether it has more or fewer elements than the specified length, will result in an error:

```
try {
  // @ts-expect-error forced error
  await contract.functions.echo_u64_array([10000000]).get();
} catch (e) {
  console.log('error', e);
  // Types/values length mismatch.
}
```

Similarly, passing an `Array` with an incorrect type will also result in an error:

```
try {
  await contract.functions.echo_u64_array([10000000, 'a']).get();
} catch (e) {
  console.log('error', e);
  // Invalid u64.
}
```

## Vectors

If your `Array` size is unknown until runtime, consider using the [Vectors](./vectors.md) type, which is more suitable for dynamic-sized collections.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/asset-id.md.md

# Asset ID

An Asset ID can be represented using the `AssetId` type. It's definition matches the Sway standard library type being a `Struct` wrapper around an inner `B256` value.

```
import type { AssetId } from 'fuels';
import { getRandomB256 } from 'fuels';

const b256 = getRandomB256();

const assetId: AssetId = {
  bits: b256,
};
```

## Using an Asset ID

You can easily use the `AssetId` type within your Sway programs. Consider the following contract that can compares and return an `AssetId`:

```
contract;

abi EvmTest {
    fn echo_asset_id() -> AssetId;
    fn echo_asset_id_comparison(asset_id: AssetId) -> bool;
    fn echo_asset_id_input(asset_id: AssetId) -> AssetId;
}

const ASSET_ID: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);

impl EvmTest for Contract {
    fn echo_asset_id() -> AssetId {
        ASSET_ID
    }

    fn echo_asset_id_comparison(asset_id: AssetId) -> bool {
        asset_id == ASSET_ID
    }

    fn echo_asset_id_input(asset_id: AssetId) -> AssetId {
        asset_id
    }
}
```

The `AssetId` struct can be passed to the contract function as follows:

```
const assetId: AssetId = {
  bits: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c',
};

const { value } = await contract.functions
  .echo_asset_id_comparison(assetId)
  .get();
```

And to validate the returned value:

```
const { value } = await contract.functions.echo_asset_id().get();

console.log('value', value);
// const value: AssetId = {
//   bits: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c',
// };
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/b256.md.md

# `B256`

The type `B256` in Fuel represents hashes and holds a 256-bit (32-bytes) value. The TypeScript SDK represents `B256` as a hexlified string value for portability and provides utilities to convert to `Uint8Array` when the [raw bytes](./bytes32.md) are required.

## Generating random `B256` values

To generate a random `B256` value, you can use the `getRandomB256()` function:

```
import { getRandomB256 } from 'fuels';

// b256 is a hexlified string representing a 256-bit value
const b256: string = getRandomB256();

console.log('b256', b256);
// 0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6
```

### Converting between `B256` and `Uint8Array`

To convert between a `B256` hexlified string and a `Uint8Array`, you can use the `arrayify` and `hexlify` functions:

```
import { arrayify, getRandomB256, hexlify } from 'fuels';

const randomB256: string = getRandomB256();

// Convert to Uint8Array
const uint8Arr: Uint8Array = arrayify(randomB256);

// Convert back to hexlified string
const hexedB256: string = hexlify(uint8Arr);
```

## Support from `Address` Class

A `B256` value is also supported as part of the [`Address`](https://fuels-ts-docs-api.vercel.app/classes/_fuel_ts_address.Address.html) class, providing seamless integration with other components of your application. To create an [`Address`](https://fuels-ts-docs-api.vercel.app/classes/_fuel_ts_address.Address.html) instance from a b256 value, use the `new Address()` method:

```
import { getRandomB256, Address } from 'fuels';

const randomB256: string = getRandomB256();

const address = new Address(randomB256);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/b512.md.md

# B512

In Sway, the `B512` type is commonly used to handle public keys and signatures. This guide will explain how the `B512` type is defined in Sway, how to visualize a `B512` value using the SDK, and how to interact with a contract function that accepts a `B512` parameter.

The `B512` type in Sway is a wrapper around two `B256` types, allowing for the representation of 64-byte values. It is defined as a struct:

```
pub struct B512 {
    /// The two `B256`s that make up the `B512`.
    bits: [b256; 2],
}
```

## `B512` in the SDK

In the SDK, you can visualize a `B512` value by examining a wallet's public key:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.generate({ provider });

console.log('public key', wallet.publicKey);

// 0x97e3a666e4cd34b6b3cf778ef5ec617de4439b68f7a629245442a1fece7713094a1cb0aa7ad0ac253ca1ea47d4618f9090b2a881e829e091fb2c426763e94cca
```

## Example: Echoing a `B512` Value in a Contract Function

Let's consider a contract function that accepts a `B512` parameter and returns the same value:

```
    fn echo_b512(input: B512) -> B512 {
        input
    }
```

To call this function and validate the returned value, follow these steps:

```
const b512 = wallet.publicKey;

const { value } = await contract.functions.echo_b512(b512).get();
```

In this example, we generate a wallet, use its public key as the `B512` input, call the `echo_b512` contract function, and expect the returned value to match the original input.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/bytes.md.md

# Bytes

A dynamic array of byte values can be represented using the `Bytes` type, which represents raw bytes.

## Using Bytes

The `Bytes` type can be integrated with your contract calls. Consider the following contract that can compare and return a `Bytes`:

```
contract;

use std::bytes::Bytes;

abi BytesTest {
    fn echo_bytes(value: Bytes) -> Bytes;
    fn bytes_comparison(value: Bytes) -> bool;
}

impl BytesTest for Contract {
    fn echo_bytes(value: Bytes) -> Bytes {
        value
    }

    fn bytes_comparison(value: Bytes) -> bool {
        let mut bytes = Bytes::new();

        bytes.push(40u8);
        bytes.push(41u8);
        bytes.push(42u8);

        value == bytes
    }
}
```

A `Bytes` array can be created using a native JavaScript array of numbers or Big Numbers, and sent to a Sway contract:

```
const bytes: Bytes = [40, 41, 42];

const { value } = await contract.functions.echo_bytes(bytes).get();

console.log('value', value);
// Uint8Array(3)[40, 41, 42]
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/bytes32.md.md

# Bytes32

In Sway and the FuelVM, `bytes32` is used to represent hashes. It holds a 256-bit (32-bytes) value.

## Generating Random bytes32 Values

To generate a random `bytes32` value, you can use the `randomBytes` function from the fuels module:

```
import { randomBytes, type Bytes } from 'fuels';

const bytes32: Bytes = randomBytes(32);
```

## Converting Between Byte Arrays and Strings

You can use the `hexlify` function to convert a byte array to a hex string, and the `arrayify` function to convert a hex string back to a byte array:

```
import type { Bytes } from 'fuels';
import { arrayify, hexlify, randomBytes } from 'fuels';

const randomBytes32: Bytes = randomBytes(32);

const bytes32String: string = hexlify(randomBytes32);

const bytes32: Bytes = arrayify(bytes32String);
```

## Working with b256 in Fuel

In Fuel, there is a special type called b256, which is similar to `bytes32`. Like `bytes32`, `B256` is also used to represent hashes and holds a 256-bit value. You can learn more about working with `B256` values in the [B256 documentation](./b256.md).


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/enums.md.md

# Enums

Sway Enums are a little distinct from TypeScript Enums. In this document, we will explore how you can represent Sway Enums in the SDK and how to use them with Sway contract functions.

## Basic Sway Enum Example

Consider the following basic Sway Enum called `StateError`:

```
// #region enums-4
pub enum StateError {
    Void: (),
    Pending: (),
    Completed: (),
}
```

The type `()` indicates that there is no additional data associated with each Enum variant. Sway allows you to create Enums of Enums or associate types with Enum variants.

### Using Sway Enums As Function Parameters

Let's define a Sway contract function that takes a `StateError` Enum variant as an argument and returns it:

```
    fn echo_state_error_enum(state_error: StateError) -> StateError {
        state_error
    }
```

To execute the contract function and validate the response, we can use the following code:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoEnumFactory } from '../../../../typegend';
import { StateErrorInput } from '../../../../typegend/contracts/EchoEnum';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const deploy = await EchoEnumFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const enumParam = StateErrorInput.Completed;

const { value } = await contract.functions
  .echo_state_error_enum(enumParam)
  .get();

console.log('value', value);
// StateErrorInput.Completed
```

In this example, we simply pass the Enum variant as a value to execute the contract function call.

## Enum of Enums Example

In this example, the `Error` Enum is an Enum of two other Enums: `StateError` and `UserError`.

```
pub enum StateError {
    Void: (),
    Pending: (),
    Completed: (),
}
// #endregion enums-1

pub enum UserError {
    Unauthorized: (),
    InsufficientPermissions: (),
}

pub enum Error {
    StateError: StateError,
    UserError: UserError,
}
```

### Using Enums of Enums with Contract Functions

Now, let's create a Sway contract function that accepts any variant of the `Error` Enum as a parameter and returns it immediately. This variant could be from either the `StateError` or `UserError` Enums.

```
    fn echo_error_enum(error: Error) -> Error {
        error
    }
```

Since the `Error` Enum is an Enum of Enums, we need to pass the function parameter differently. The parameter will be a TypeScript object:

```
const enumParam = { UserError: UserErrorInput.InsufficientPermissions };

const { value } = await contract.functions.echo_error_enum(enumParam).get();

console.log('value', value);
// { UserError: UserErrorInput.InsufficientPermissions }
```

In this case, since the variant `InsufficientPermissions` belongs to the `UserError` Enum, we create a TypeScript object using the Enum name as the object key and the variant as the object value.

We would follow the same approach if we intended to use a variant from the `StateError` Enum:

```
const enumParam = { StateError: StateErrorInput.Completed };

const { value } = await contract.functions.echo_error_enum(enumParam).get();

console.log('value', value);
// { StateError: StateErrorInput.Completed }
```

## Errors

While working with enums, you may run into the following issues:

### Using an invalid enum type

Thrown when the type being passed to the enum does not match that expected by it.

```
// Valid types: string
const emumParam = 1;

try {
  // @ts-expect-error number is not a valid type
  await contract.functions.echo_state_error_enum(emumParam).get();
} catch (error) {
  console.log('error', error);
}
```

### Using an invalid enum value

Thrown when the parameter passed is not an expected enum value.

```
// Valid values: 'Void', 'Pending', 'Completed'
const invalidEnumValue = 'NotStateEnumValue';

try {
  // @ts-expect-error NotStateEnumValue is not a valid value
  await contract.functions.echo_state_error_enum(invalidEnumValue).get();
} catch (error) {
  console.log('error', error);
}
```

### Using an invalid enum case key

Thrown when the passed enum case is not an expected enum case value.

```
// Valid case keys: 'StateError', 'UserError'
const enumParam = { UnknownKey: 'Completed' };

try {
  // @ts-expect-error UnknownKey is not a valid key
  await contract.functions.echo_error_enum(enumParam).get();
} catch (error) {
  console.log('error', error);
}
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/evm-address.md.md

# `EvmAddress`

An Ethereum Virtual Machine (EVM) Address can be represented using the `EvmAddress` type. It's definition matches the Sway standard library type being a `Struct` wrapper around an inner `B256` value.

```
import type { B256AddressEvm, EvmAddress } from 'fuels';

const b256: B256AddressEvm =
  '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6';

const evmAddress: EvmAddress = {
  bits: b256,
};
```

## Creating an EVM Address

An EVM Address only has 20 bytes therefore the first 12 bytes of the `B256` value are set to 0. Within the SDK, an `Address` can be instantiated and converted to a wrapped and Sway compatible EVM Address using the `toEvmAddress()` function:

```
import { Address } from 'fuels';

// #region snippet-2
const b256Address =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';
// #endregion snippet-2

const address = new Address(b256Address);

const evmAddress = address.toEvmAddress();

console.log('evmAddress', evmAddress);
// '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6'
```

## Using an EVM Address

The `EvmAddress` type can be integrated with your contract calls. Consider the following contract that can compare and return an EVM Address:

```
contract;

use std::vm::evm::evm_address::EvmAddress;

configurable {
    B256_ADDR: b256 = 0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6,
}

abi EvmTest {
    fn echo_address() -> EvmAddress;
    fn echo_address_comparison(evm_addr: EvmAddress) -> bool;
}

impl EvmTest for Contract {
    fn echo_address() -> EvmAddress {
        return EvmAddress::from(B256_ADDR);
    }

    fn echo_address_comparison(evm_addr: EvmAddress) -> bool {
        let evm_addr2 = EvmAddress::from(B256_ADDR);

        evm_addr == evm_addr2
    }
}
```

The `EvmAddress` type can be used with the SDK and passed to the contract function as follows:

```
// #region snippet-2
const evmAddress: EvmAddress = {
  bits: '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6',
};
// #endregion snippet-2

const { value } = await contract.functions
  .echo_address_comparison(evmAddress)
  .get();
```

And to validate the returned value:

```
const { value } = await contract.functions.echo_address().get();

console.log('value', value);
// { bits: '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6' }
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/index.md.md

# Types

As you dive deeper into the SDK, it's essential to understand the variety of internal types available in both FuelVM and Sway, as well as their corresponding SDK equivalents. This section aims to provide you with the necessary knowledge to efficiently work with these types.

## Overview

In this section, you will learn about:

1. `FuelVM and Sway Internal Types`: Discover the various types used within FuelVM and Sway, and their significance in different contexts.

2. `SDK Equivalents`: Explore the corresponding types available in the SDK, and understand their similarities and differences compared to FuelVM and Sway internal types.

3. `Type Usage`: Gain insights into how to effectively use these types in your projects or applications, with examples and best practices.

4. `Type Conversion`: Learn the techniques and methods for converting between FuelVM, Sway, and SDK types, guaranteeing smooth interoperability and consistent data integrity.

## Additional Resources

As you progress through the documentation, you may find it helpful to refer back to the following resources:

- [Sway Documentation](https://docs.fuel.network/docs/sway/): Explore the Sway documentation homepage for an overview of Sway Types, as well as other sections.

- [The Fuel Book](https://fuelbook.fuel.network/master/index.html): A comprehensive guide to the whole Fuel ecosystem.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/native-parameters.md.md

# Native Parameter Types

Below you can find examples of how to convert between common native Sway program input and output types:

- [`Address`](#address)
- [`ContractId`](#contractid)
- [`Identity`](#identity)
- [`AssetId`](#assetid)

## `Address`

### `AddressInput`

To pass an `Address` as an input parameter to a Sway program, you can define the input as shown below:

```
const address = Address.fromRandom();
const addressInput = { bits: address.toB256() };
```

### `AddressOutput`

For a Sway program that returns an `Address` type, you can convert the returned value to an `Address` type in `fuels` as shown below:

```
const addressOutput = response1.value;
const addressFromOutput: Address = new Address(addressOutput.bits);
```

## `ContractId`

### `ContractIdInput`

To pass a `ContractId` as an input parameter to a Sway program, you can define the input as shown below:

```
const contractId =
  '0x7296ff960b5eb86b5f79aa587d7ebe1bae147c7cac046a16d062fbd7f3a753ec';
const contractIdInput = { bits: contractId };
```

### `ContractIdOutput`

For a Sway program that returns a `ContractId` type, you can convert the returned value to a `string` as shown below:

```
const contractIdOutput = response.value;
const contractIdFromOutput: string = contractIdOutput.bits;
```

## `Identity`

### `IdentityInput`

To pass an `Identity` as an input parameter to a Sway program, you can define the input as shown below:

For an address:

```
const address = Address.fromRandom();
const addressInput = { bits: address.toB256() };
const addressIdentityInput = { Address: addressInput };
```

For a contract:

```
const contractId =
  '0x7296ff960b5eb86b5f79aa587d7ebe1bae147c7cac046a16d062fbd7f3a753ec';
const contractIdInput = { bits: contractId.toString() };
const contractIdentityInput = { ContractId: contractIdInput };
```

### `IdentityOutput`

For a Sway program that returns an `Identity` type, you can convert the returned value to an `Address` or `string` as shown below:

For an address:

```
const response = await contract.functions.identity(addressIdentityInput).get();

const identityFromOutput: IdentityOutput = response.value;
const addressStringFromOutput: AddressOutput =
  identityFromOutput.Address as AddressOutput;
const addressFromOutput = new Address(addressStringFromOutput.bits);
```

For a contract:

```
const response = await contract.functions.identity(contractIdentityInput).get();

const identityFromOutput2: IdentityOutput = response.value;
const contractIdOutput = identityFromOutput2.ContractId as ContractIdOutput;
const contractIdFromOutput = contractIdOutput.bits;
```

## `AssetId`

### `AssetIdInput`

To pass an `AssetId` as an input parameter to a Sway program, you can define the input as shown below:

```
const assetId =
  '0x0cfabde7bbe58d253cf3103d8f55d26987b3dc4691205b9299ac6826c613a2e2';
const assetIdInput = { bits: assetId };
```

### `AssetIdOutput`

For a Sway program that returns an `AssetId` type, you can convert the returned value to a `string` as shown below:

```
const assetIdOutput = response5.value;
const assetIdFromOutput: string = assetIdOutput.bits;
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/numbers.md.md

# Numbers

In Sway, there are multiple primitive number types:

1. `u8` (8-bit unsigned integer)
1. `u16` (16-bit unsigned integer)
1. `u32` (32-bit unsigned integer)
1. `u64` (64-bit unsigned integer)
1. `u256` (256-bit unsigned integer)

This guide explains how to create and interact with Sway numbers while using the SDK.

## Creating Numbers

### For `u64` and `u256`

When you pass in a `u64` or a `u256` to a Sway program from JavaScript, you must first convert it to a `BigNum` object. This is because these types can have extremely large maximum values (`2^64` and `2^256` respectively), and JavaScript's `Number` type can only hold up to 53 bits of precision (`2^53`).

```
import { bn } from 'fuels';

const number: number | string = 20;

const bigNumber = bn(number);

console.log('equals', bigNumber.eqn(number));
// true
```

You can also create a `BigNum` from a string. This is useful when you want to pass in a number that is too large to be represented as a JavaScript number. Here's how you can do that:

```
import { bn } from 'fuels';

const strNumber = '9007199254740992';

const bigNumber = bn(strNumber);

console.log('equals', bigNumber.toString() === strNumber);
// true
```

### For `u8`, `u16`, and `u32`

You don't need to do anything special to create these numbers. You can pass in a JavaScript number directly. See the examples below for more details.

## Examples: Interacting with Numbers in Contract Methods

### For `u64` and `u256`

```
const bigNumber = bn('10000000000000000000');

const { value } = await contract.functions.echo_u64(bigNumber).get();

console.log('value', value.toString());
// '10000000000000000000'
```

> Note: If a contract call returns a number that is too large to be represented as a JavaScript number, you can convert it to a string using the `.toString()` method instead of `.toNumber()`.

### For `u8`, `u16`, and `u32`

```
const number = 200;

const { value } = await contract.functions.echo_u8(number).get();

console.log('value', Number(value));
// 200
```

### Using a `BigNum` from `ethers` with `fuels`

```
import { toBigInt } from 'ethers';
import { bn } from 'fuels';

const number = 20;

const ethersBigNum = toBigInt(number);

const fuelsBigNum = bn(ethersBigNum.toString());

console.log('value', fuelsBigNum.toNumber());
// 20
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/options.md.md

# Options

Sway provides the `Option` (optional) container for handling variables that can have a value or be marked as `no-value`. This concept is useful when dealing with situations where a variable may or may not have a defined value.

In this guide, we'll explain how to work with Option types in Sway and demonstrate their usage through a practical example.

## Overview of `Option` Type

The `Option` type in Sway is a special wrapper type of Enum. In TypeScript, you can represent the `Option` type by using the `undefined` keyword, as shown in the following example

```
// Sway Option<u8>
// #region snippet-2
const input: number | undefined = 10;
```

In this example, the variable `input1` can be either a `number` or `undefined`.

## Example: `Option<u8>` Parameters

Let's say we have a contract function that accepts two `Option<u8>` parameters. Both of these parameters can have a value or be undefined. The function checks whether each input has a value; if not, it assigns a value of `0`. Finally, the function returns the sum of the two inputs.

Here's the contract function written in Sway:

```
    fn sum_optional_u8(input1: Option<u8>, input2: Option<u8>) -> u8 {
        let value1 = match input1 {
            Option::Some(v) => v,
            Option::None => 0,
        };

        let value2 = match input2 {
            Option::Some(v) => v,
            Option::None => 0,
        };

        value1 + value2
    }
```

You can interact with the contract function using the SDK as follows:

```
const input: number | undefined = 10;
// #endregion snippet-1
const input2: number | undefined = 5;

const { value } = await contract.functions.sum_optional_u8(input, input2).get();

console.log('value', value);
// 15
```

In this case, the result of the contract function call is the sum of both input parameters. If we pass only one parameter, the contract function will default the other parameter's value to `0`.

```
const input: number | undefined = 10;

const { value } = await contract.functions.sum_optional_u8(input).get();

console.log('value', value);
// 10
```

Using `Option` types in Sway allows you to elegantly handle situations where a variable may or may not have a defined value.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/raw-slice.md.md

# `RawSlice`

A dynamic array of values can be represented using the `RawSlice` type. A raw slice can be a value reference or a raw pointer.

## Using a `RawSlice`

The `RawSlice` type can be integrated with your contract calls. Consider the following contract that can compare and return a `RawSlice`:

```
contract;

abi RawSliceTest {
    fn echo_raw_slice(value: raw_slice) -> raw_slice;
    fn raw_slice_comparison(value: raw_slice) -> bool;
}

impl RawSliceTest for Contract {
    fn echo_raw_slice(value: raw_slice) -> raw_slice {
        value
    }

    fn raw_slice_comparison(value: raw_slice) -> bool {
        let vec: Vec<u8> = Vec::from(value);

        vec.len() == 3 && vec.get(0).unwrap() == 40 && vec.get(1).unwrap() == 41 && vec.get(2).unwrap() == 42
    }
}
```

A `RawSlice` can be created using a native JavaScript array of numbers or Big Numbers, and sent to a Sway contract:

```
const rawSlice: RawSlice = [8, 42, 77];

const { value } = await contract.functions.echo_raw_slice(rawSlice).get();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/std-string.md.md

# `StdString`

A dynamic string of variable length can be represented using the `StdString` type, also known as a Standard Lib String or `std-lib-string`. It behaves much like a dynamic string in most languages, and is essentially an array of characters.

## Using a `StdString`

The `StdString` type can be integrated with your contract calls. Consider the following contract that can compare and return a String:

```
contract;

use std::string::String;

abi StdStringTest {
    fn echo_string(value: String) -> String;
    fn string_comparison(value: String) -> bool;
}

impl StdStringTest for Contract {
    fn echo_string(value: String) -> String {
        value
    }

    fn string_comparison(value: String) -> bool {
        let expected = String::from_ascii_str("Hello World");

        value.as_bytes() == expected.as_bytes()
    }
}
```

A string can be created using a native JavaScript string, and sent to a Sway contract:

```
const stdString: StdString = 'Hello Fuel';

const { value } = await contract.functions.echo_string(stdString).get();

console.log('value', value);
// 'Hello Fuel'
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/string.md.md

# String

In Sway, strings are statically-sized, which means you must define the size of the string beforehand. Statically-sized strings are represented using the `str[x]` syntax, where `x` indicates the string's size.
This guide explains how to create and interact with statically-sized strings while using the SDK.

## Creating Statically-Sized Strings

```
// Sway str[2]
const stringSize2 = 'st';

// Sway str[8]
const stringSize8 = 'fuel-sdk';
```

## Interacting with Statically-Sized Strings in Contract Methods

When a contract method accepts and returns a `str[8]`, the corresponding SDK wrapper method will also take and return a string of the same length. You can pass a string to the contract method like this:

```
const { value } = await contract.functions.echo_str_8('fuel-sdk').get();

console.log('value', value);
// 'fuel-sdk'
```

When working with statically-sized strings, ensure that the input and output strings have the correct length to avoid erroneous behavior.

If you pass a string that is either too long or too short for a contract method, the call will fail like this:

```
const longString = 'fuel-sdk-WILL-THROW-ERROR';

try {
  await contract.functions.echo_str_8(longString).call();
} catch (error) {
  console.log('error', error);
  // Value length mismatch during encode
}

const shortString = 'THROWS';

try {
  await contract.functions.echo_str_8(shortString).call();
} catch (error) {
  console.log('error', error);
  // Value length mismatch during encode
}
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/structs.md.md

# Structs

In Sway, a `struct` serves a similar purpose as an `Object` in TypeScript. It defines a custom data structure with specified property names and types. The property names and types in the Sway struct must match the corresponding TypeScript definition.

## Example

Here is an example of a `struct` in Sway:

```
pub struct EmployeeData {
    name: str[8],
    age: u8,
    salary: u64,
    idHash: b256,
    ratings: [u8; 3],
    isActive: bool,
}
```

And here is the equivalent structure represented in TypeScript:

```
type EmployeeDataStruct = {
  name: string;
  age: number;
  salary: number;
  idHash: string;
  ratings: number[];
  isActive: boolean;
};

const data: EmployeeDataStruct = {
  name: 'John Doe',
  age: 30,
  salary: 100_000,
  idHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
  ratings: [4, 5, 5],
  isActive: true,
};
```

## Handling Different Data Types

Please note that TypeScript does not have native support for `u8` and `u64` types. Instead, use the `number` type to represent them.

Additionally, TypeScript does not support specifying string length, so just use `string` for the `name`.

In a similar way, since the type `B256` on the SDK is just an hexlified string, we use `string` as well.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/tuples.md.md

# Tuples

In Sway, Tuples are fixed-length collections of heterogeneous elements. Tuples can store multiple data types, including basic types, structs, and enums. This guide will demonstrate how to represent and work with Tuples in TypeScript and interact with a contract function that accepts a tuple as a parameter.

In TypeScript, you can represent Sway tuples using arrays with specified types for each element:

```
// Sway let tuple2: (u8, bool, u64) = (100, false, 10000);
// #region tuples-3
const tuple: [number, boolean, number] = [100, false, 10000];
```

In this example, the Typescript `tuple` variable contains three elements of different types: a number, a boolean, and another number.

## Example: Passing Tuple as a Parameter

Let's consider a contract function that accepts a tuple as a parameter and returns the same Tuple:

```
    fn echo_tuple(tuple: (u8, bool, u64)) -> (u8, bool, u64) {
        tuple
    }
```

To execute and validate the contract function using the SDK, follow these steps:

```
const tuple: [number, boolean, number] = [100, false, 10000];
// #endregion tuples-1

const { value } = await contract.functions.echo_tuple(tuple).simulate();

console.log('value', value);
// [100, false, <BN 0x2710>]
```

In this example, we create a Tuple with three elements, call the `echo_tuple` contract function, and expect the returned tuple to match the original one. Note that we convert the third element of the returned tuple to a number using `new BN(value[2]).toNumber()`.

Tuples in Sway provide a convenient way to store and manipulate collections of heterogeneous elements. Understanding how to represent and work with tuples in TypeScript and Sway contracts will enable you to create more versatile and expressive code.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/types/vectors.md.md

# Vectors

In Sway, a Vector is a dynamic-sized collection of elements of the same type. Vectors can hold arbitrary types, including non-primitive types.

## Working with Vectors in the SDK

A basic Vector in Sway is similar to a TypeScript Array:

```
// Sway Vec<u8>
const basicU8Vector = [1, 2, 3];
```

Consider the following example of a `EmployeeData` struct in Sway:

```
pub struct EmployeeData {
    name: str[8],
    age: u8,
    salary: u64,
    idHash: b256,
    ratings: [u8; 3],
    isActive: bool,
}
```

Now, let's look at the following contract method. It receives a Vector of the `Transaction` struct type as a parameter and returns the last `Transaction` entry from the Vector:

```
    fn echo_last_employee_data(employee_data_vector: Vec<EmployeeData>) -> EmployeeData {
        employee_data_vector.get(employee_data_vector.len() - 1).unwrap()
    }
```

The code snippet below demonstrates how to call this Sway contract method, which accepts a `Vec<Transaction>`:

```
const employees: EmployeeDataInput[] = [
  {
    name: 'John Doe',
    age: 30,
    salary: bn(8000),
    idHash: getRandomB256(),
    ratings: [1, 2, 3],
    isActive: true,
  },
  {
    name: 'Everyman',
    age: 31,
    salary: bn(9000),
    idHash: getRandomB256(),
    ratings: [5, 6, 7],
    isActive: true,
  },
];
const { value } = await contract.functions
  .echo_last_employee_data(employees)
  .simulate();
```

## Converting Bytecode to Vectors

Some functions require you to pass in bytecode to the function. The type of the bytecode parameter is usually `Vec<u8>`, here's an example of how to pass bytecode to a function:

```
    fn compute_bytecode_root(bytecode_input: Vec<u8>) -> b256 {
        //simply return a fixed b256 value created from a hexadecimal string from testing purposes
        return 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20;
    }
```

To pass bytecode to this function, you can make use of the `arrayify` function to convert the bytecode file contents into a `UInt8Array`, the TS compatible type for Sway's `Vec<u8>` type and pass it the function like so:

```
const bytecodeAsVecU8 = Array.from(arrayify(BytecodeInputFactory.bytecode));

const { waitForResult } = await bytecodeContract.functions
  .compute_bytecode_root(bytecodeAsVecU8)
  .call();

const { value: bytecodeRoot } = await waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/utilities/address-conversion.md.md

# Address

Addresses and varying address formats are commonplace when interacting with decentralized applications. Furthermore, different networks may enforce different address formats.

The Fuel Network uses the [`B256`](../types/b256.md) address format for its interactions, an example of which can be seen below:

```
const b256 =
  '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c';
```

However, a hexlified [B256](../types/b256.md) (hex) is another common address format; an example can be seen below:

```
const b256Address =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';
```
apps/

At times, these can even be wrapped in a [Struct](../types/structs.md). Such as an [Asset ID](../types/asset-id.md) or a [EVM Address](../types/evm-address.md):

```
const evmAddress: EvmAddress = {
  bits: '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6',
};
```

The TS-SDK makes converting between these addresses simple using the [Address](../types/address.md) helper, which provides various utilities for conversion.

The following [conversion guide](./address-conversion.md#address-conversion) will show how to utilize this class to convert between address formats, as well as Sway Standard Types.

## Address Conversion

This guide demonstrates how to convert between address formats and Sway Standard Types using helper functions. Native types are wrappers for bytes, and you can perform conversions between them by leveraging these functions and classes.

## Converting a Contract ID

The Contract `id` property is an instance of the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class. Therefore, it can be converted using the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class functions such as `toAddress` and `toB256`:

```
import type { B256Address } from 'fuels';
import { Address, Provider, Contract } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { Counter } from '../../../../typegend/contracts';

const provider = new Provider(LOCAL_NETWORK_URL);

const contractAbi = Counter.abi;
const contractAddress = new Address(
  '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
);

const contract = new Contract(contractAddress, contractAbi, provider);

const b256: B256Address = contract.id.toAddress();
// 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
```

## Converting a Wallet Address

Similarly, the Wallet `address` property is also of type [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) and can therefore use the same [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class functions for conversion:

```
import type { B256Address, WalletLocked } from 'fuels';
import { Address, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const address = new Address(
  '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
);

const wallet: WalletLocked = Wallet.fromAddress(address, provider);

const b256: B256Address = wallet.address.toAddress();
// 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
```

## Converting an Asset ID

[Asset IDs](../types/asset-id.md) are a wrapped [`B256`](../types/b256.md) value. The following example shows how to create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from a `B256` type:

```
import type { AssetId, B256Address } from 'fuels';
import { Address } from 'fuels';

const b256: B256Address =
  '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f';
const address: Address = new Address(b256);
const assetId: AssetId = address.toAssetId();
// {
//    bits: '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
// }
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/utilities/asset-api.md.md

# Asset API

The Asset API is a RESTful API that allows you to query the assets on the Fuel blockchain. We allow for querying the Asset API on both the Mainnet and Testnet.

|         | Endpoint                                      |
| ------- | --------------------------------------------- |
| Mainnet | https://mainnet-explorer.fuel.network         |
| Testnet | https://explorer-indexer-testnet.fuel.network |

For more information about the API, please refer to the [Wiki](https://github.com/FuelLabs/fuel-explorer/wiki/Assets-API#) page.

## Asset by ID

We can request information about an asset by its asset ID, using the `getAssetById` function. This will leverage the endpoint `/assets/<assetId>` to fetch the asset information.

```
import type { AssetInfo } from 'fuels';
import { getAssetById } from 'fuels';

const asset: AssetInfo | null = await getAssetById({
  assetId: '0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07',
});

console.log('AssetInfo', asset);
// AssetInfo { ... }
```

By default, we will request the asset information for `mainnet`. If you want to request the asset information from other networks, you can pass the `network` parameter (this is the same for the [`getAssetsByOwner`](#assets-by-owner) function).

```
await getAssetById({
  assetId: '0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07',
  network: 'testnet',
});
```

## Assets by Owner

We can request information about an asset by its owner, using the `getAssetsByOwner` function. This will leverage the endpoint `/accounts/<owner>/assets` to fetch the asset information.

```
import type { AssetsByOwner } from 'fuels';
import { getAssetsByOwner } from 'fuels';

const assets: AssetsByOwner = await getAssetsByOwner({
  owner: '0x0000000000000000000000000000000000000000000000000000000000000000',
});

console.log('AssetsByOwner', assets);
// AssetsByOwner { data: [], pageInfo: { count: 0 } }
```

You can change the pagination parameters to fetch more assets (up to 100 assets per request).

```
await getAssetsByOwner({
  owner: '0x0000000000000000000000000000000000000000000000000000000000000000',
  pagination: { last: 100 },
});
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/utilities/date-conversion.md.md

# Date conversion

To allow for easier manipulation of date and time, the SDK exports the `DateTime` class which is a wrapper around the [built-in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) `Date` class. Below we will go over the methods of instantiation, utility functions and time formats.

Internally the transactions and other time/date assets are encoded using the [`TAI64`](#tai-format) format. We return a `DateTime` class, to allow of easier conversion and formatting between the two formats.

## Instantiating a `DateTime`

We have a host of static method for **instantiation** of our `DateTime` class.

```
import { DateTime } from 'fuels';

const tai64: DateTime = DateTime.fromTai64('4611686020108779339');
const unixSeconds: DateTime = DateTime.fromUnixSeconds(1681391398);
const unixMilliseconds: DateTime = DateTime.fromUnixMilliseconds(1681391398000);
```

### TAI64

`fromTai64` is a _static_ method, that allows the creation of `DateTime` class from a `TAI64` string.

`toTai64` is an _instance_ method, that allows the conversion of a `DateTime` class to a `TAI64` string.

```
import { DateTime } from 'fuels';

const date: DateTime = DateTime.fromTai64('4611686020108779339');

const tai64: string = date.toTai64();
// "4611686020108779339"
```

### UNIX

`fromUnixMilliseconds` is a _static_ method, that allows the creation of `DateTime` class from a UNIX Milliseconds number.

`toUnixMilliseconds` is an _instance_ method, that allows the conversion of a `DateTime` class to a `UNIX` number in milliseconds.

```
import { DateTime } from 'fuels';

const date: DateTime = DateTime.fromUnixMilliseconds(1681391398000);

const unixMilliseconds: number = date.toUnixMilliseconds();
// 1681391398000
```

`fromUnixSeconds` is a _static_ method, that allows the creation of `DateTime` class from a UNIX Seconds number.

`toUnixSeconds` is an _instance_ method, that allows the conversion of a `DateTime` class to a `UNIX` number in seconds.

```
import { DateTime } from 'fuels';

const date: DateTime = DateTime.fromUnixSeconds(1681391398);

const unixSeconds: number = date.toUnixSeconds();
// 1681391398
```

### Date

The `DateTime` class extends the functionality of the `Date` object, so all method are available for your usages.

```
import { DateTime } from 'fuels';

const dateTime: DateTime = DateTime.fromUnixMilliseconds(1681391398000);

// Extends the Date object
const date: Date = dateTime;

// Date object methods
date.getTime(); // 1681391398000
date.toISOString(); // 2023-04-13T13:09:58.000Z
date.toDateString(); // Thu Apr 13 2023
```

## Formats

Here we will go over the different date/time formats that we use in the SDK. Internally the blockchain uses the `TAI64` format, but we also support the `UNIX` format for ease of use.

### UNIX Format

UNIX time is the number of seconds that have elapsed since **00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970**, minus leap seconds. Every day is treated as if it contains exactly 86400 seconds, so leap seconds are ignored.

### TAI Format

TAI stands for _Temps Atomique International_ and is the current international real-time standard [Source](https://cr.yp.to/libtai/tai64.html).

We use `TAI64` is a 64-bit integer representing the number of nanoseconds since the epoch.

- the TAI second beginning exactly _(2^62 - s) seconds_ before the beginning of 1970 TAI, if s is between 0 inclusive and 2^62 exclusive; or

- the TAI second beginning exactly _(2^62 + s) seconds_ after the beginning of 1970 TAI, if s is between -2^62 inclusive and 0 exclusive.

[Source](https://cr.yp.to/libtai/tai64.html)


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/utilities/index.md.md

# Utilities

Utilities are a set of helpers that can be used for various purposes.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/utilities/unit-conversion.md.md

# Unit conversion

Internally, we use [Arbitrary-precision](https://mathworld.wolfram.com/ArbitraryPrecision.html) arithmetic (also known as Big Number arithmetic) to allow for the handling of large numbers and different assets.

On the Fuel network, we work with 9 decimals to represent amounts under a unit. This differs from chain to chain, so it is important to know the number of decimals used on the chain you are working with.

> Note: The package [`@fuels/assets`](https://www.npmjs.com/package/@fuels/assets) provides a list of assets and their decimals.

Below we will go over some common use cases for unit conversion.

Using our `BN` class we can instantiate these numbers.

```
const myBigNumberOne = '100000000';

const resultOne = new BN('100000000').toString();
```

Or using our `bn` utility function.

```
const resultTwo = bn('100000000').toString();
```

## Contract calls

Generally, we will need to convert `u64` and `u256` numbers to a `BN` object when passing them to a Sway program from JavaScript. More information on this can be found [here](../types/numbers.md).

```
// Let's deploy a contract that has a function that takes a u64 as input
const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = await Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployedContract = await new EchoValuesFactory(wallet).deploy();
const { contract } = await deployedContract.waitForResult();

const MAX_U64 = bn('18446744073709551615');

const { waitForResult } = await contract.functions.echo_u64(MAX_U64).call();
const { value } = await waitForResult();
```

> Note: If a contract call returns a number that is too large to be represented as a JavaScript number, you can convert it to a string using the `toString` method instead of `toNumber`.

## Parsing

Parsing string-represented numbers (from user input) has never been easier, than using the `parseUnits` function.

```
const resultThree = bn.parseUnits('0.000000001').toString();
```

We can parse large numbers.

```
const myBigNumberFour = '100100000000000';
const resultFour = bn.parseUnits('100100').toString();
```

Or numbers formatted for human readability.

```
const myBigNumberFive = '100100000200001';

const resultFive = bn.parseUnits('100,100.000200001').toString();
```

We can also parse numbers in other units of measure.

```
const myBigNumberSix = '1000000000';

const resultSix = bn.parseUnits('1', DECIMAL_GWEI).toString();
```

## Formatting

We can format common units of measure using the `format` function.

In the following example, we format a BigNumber representation of one Gwei, into units for the Fuel network (with 3 decimal place precision).

```
const myBigNumberSeven = '1.000';
const oneGwei = bn('1000000000');

const resultSeven = oneGwei.format();
```

We can also format numbers in other units of measure by specifying the `units` variable.

```
const myBigNumberEight = '2.000';

const twoGwei = bn('2000000000');

const resultEight = twoGwei.format({ units: DECIMAL_GWEI });
```

A `precision` variable will allow for the formatting of numbers with a specific number of decimal places.

```
const oneDecimalGwei = '1.0';

const formattedGwei = oneGwei.format({ precision: 1 });
```

### Format units

The `formatUnits` function is a lesser alternative to the `format` function, as it will maintain the same precision as the input value.

```
const myFormattedGwei = '1.000000000';

const formattedUnitsGwei = oneGwei.formatUnits();
```

We can also format numbers in other units of measure by specifying the `units` variable.

```
const myFormattedKwei = '1.000000000000000';

const oneKwei = bn('1000000000000000');

const formattedUnitsKwei = oneKwei.formatUnits(DECIMAL_KWEI);
```

## See also

- [Sway Numbers](../types/numbers.md)

## Full Example

For the full example of unit conversion see the snippet below:

```
import { BN, DECIMAL_GWEI, DECIMAL_KWEI, bn, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { EchoValuesFactory } from '../../../typegend/contracts/EchoValuesFactory';

// #region instantiation-1
const myBigNumberOne = '100000000';

const resultOne = new BN('100000000').toString();

// #endregion instantiation-1

const myBigNumberTwo = '100000000';

// #region instantiation-2

const resultTwo = bn('100000000').toString();
// #endregion instantiation-2

// #region contract-calls-1

// Let's deploy a contract that has a function that takes a u64 as input
const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = await Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployedContract = await new EchoValuesFactory(wallet).deploy();
const { contract } = await deployedContract.waitForResult();

const MAX_U64 = bn('18446744073709551615');

const { waitForResult } = await contract.functions.echo_u64(MAX_U64).call();
const { value } = await waitForResult();

// #endregion contract-calls-1

const myBigNumberThree = '1';

// #region parse-units-1
const resultThree = bn.parseUnits('0.000000001').toString();
// #endregion parse-units-1

// #endregion parse-units-1

// #region parse-units-2
const myBigNumberFour = '100100000000000';
const resultFour = bn.parseUnits('100100').toString();
// #endregion parse-units-2

// #endregion parse-units-3

// #region parse-units-3
const myBigNumberFive = '100100000200001';

const resultFive = bn.parseUnits('100,100.000200001').toString();
// #endregion parse-units-3

// #endregion parse-units-4

// #region parse-units-4
const myBigNumberSix = '1000000000';

const resultSix = bn.parseUnits('1', DECIMAL_GWEI).toString();
// #endregion parse-units-4

// #region format-1
const myBigNumberSeven = '1.000';
const oneGwei = bn('1000000000');

const resultSeven = oneGwei.format();
// #endregion format-1

// #region format-2
const myBigNumberEight = '2.000';

const twoGwei = bn('2000000000');

const resultEight = twoGwei.format({ units: DECIMAL_GWEI });
// #endregion format-2

// #region format-3
const oneDecimalGwei = '1.0';

const formattedGwei = oneGwei.format({ precision: 1 });
// #endregion format-3

// #region format-units-1
const myFormattedGwei = '1.000000000';

const formattedUnitsGwei = oneGwei.formatUnits();
// #endregion format-units-1

// #region format-units-2
const myFormattedKwei = '1.000000000000000';

const oneKwei = bn('1000000000000000');

const formattedUnitsKwei = oneKwei.formatUnits(DECIMAL_KWEI);
// #endregion format-units-2
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/utilities/using-assets.md.md

# Assets

We export an array of [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html) objects, that can be useful when creating your dApp. The `Asset` object has useful metadata about the different assets that are available on blockchain networks (Fuel and Ethereum).

Included assets such as:

- Ethereum (ETH)
- Tether (USDT)
- USD Coin (USDC)
- Wrapped ETH (WETH)

The helper functions `getAssetFuel` and `getAssetEth` can be used to get an asset's details relative to each network. These return a combination of the asset, and network information (the return types are [`AssetFuel`](DOCS_API_URL/types/_fuel_ts_account.AssetFuel.html) and [`AssetEth`](DOCS_API_URL/types/_fuel_ts_account.AssetEth.html) respectively).

```
import type { Asset, AssetFuel } from 'fuels';
import { assets, CHAIN_IDS, getAssetFuel, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient = Wallet.generate({ provider });

// Find the asset with symbol 'ETH'
const assetEth: Asset = assets.find((asset) => asset.symbol === 'ETH')!;

// Get all the metadata for ETH on Fuel Test Network
const chainId: number = CHAIN_IDS.fuel.testnet;
const assetEthOnFuel: AssetFuel = getAssetFuel(assetEth, chainId)!;

// Send a transaction (using the asset on Fuel Test Network)
const transaction = await sender.transfer(
  recipient.address,
  100,
  assetEthOnFuel.assetId
);
await transaction.waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/checking-balances.md.md

# Checking balances

To check the balance of a specific asset, you can use [`getBalance`](DOCS_API_URL/classes/_fuel_ts_account.Account.html#getBalance) method. This function aggregates the amounts of all unspent coins of the given asset in your wallet.

```
import type { BN } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const myWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// The returned amount is a BigNumber
const balance: BN = await myWallet.getBalance(await provider.getBaseAssetId());
```

To retrieve the balances of all assets in your wallet, use the [`getBalances`](DOCS_API_URL/classes/_fuel_ts_account.Account.html#getBalances) method, it returns an array of [`CoinQuantity`](DOCS_API_URL/types/_fuel_ts_account.CoinQuantity.html). This is useful for getting a comprehensive view of your holdings.

```
import { Provider, Wallet } from 'fuels';

import { WALLET_PVT_KEY_2, LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const myOtherWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const { balances } = await myOtherWallet.getBalances();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/connectors.md.md

# Connectors

Fuel Wallet Connectors offer a standardized interface to integrate multiple wallets with your DApps, simplifying wallet integration and ensuring smooth user interactions.

## Fuel Connectors

`Fuel Connectors` are a set of standardized interfaces that provide a way to interact with various wallets and services. They offer a consistent way to interact with different wallets and services, allowing developers to focus on building their applications rather than worrying about wallet integration.

To build your own wallet integration, you can create a custom connector that extends the abstract [`FuelConnector`](DOCS_API_URL/classes/_fuel_ts_account.FuelConnector.html) class. This interface provides a set of methods and events that allow you to interact with the wallet and handle various operations such as connecting, disconnecting, signing messages, and sending transactions.

```
class MyWalletConnector extends FuelConnector
```

### Properties

The `FuelConnector` abstract class provides several properties that should be implemented to provide information about the connector.

#### `name`

The `name` property is simply a `string` on the connector that serves as an identifier and will be displayed to the end-user when selecting a connector.

```
  public override name: string = 'My Wallet Connector';
```

### `external`

The `external` property is simply a `boolean` that indicates when a connector is external or not.
Connectors are considered external, or non-native, when they do not support the Fuel Network (e.g. `Solana`, `WalletConnect`).

#### `metadata`

The `metadata` property on the connector provides additional information about the connector. This information will be displayed to the end-user when selecting a connector. The following is the structure of the `metadata` object:

```
export type ConnectorMetadata = {
  image?:
    | string
    | {
        light: string;
        dark: string;
      };
  install: {
    action: string;
    link: string;
    description: string;
  };
};
```

##### `install`

The `metadata.install` property (_required_) is used to provide information about how to install the connector.

The `install` object requires three properties:

- `action` (_required_) - a `string` that will contain an action string that will be displayed to the user (e.g. "Install").

- `link` (_required_) - a `string` that will contain a URL that will be opened when the user clicks the action.

- `description` (_required_) - a `string` that will contain a description of the installation process.

```
  install: {
    action: 'Install',
    description: 'Install the My Wallet Connector',
    link: 'https://example.com/install',
  },
```

##### `image`

The `metadata.image` property (_optional_) provides an image that will be displayed to the end-user when selecting a connector. The image will be a URL to the image to be displayed (this can be an inline data URI, encoded in base64).

```
  image: 'https://example.com/image.png',
```

You can even define a `light` and `dark` theme for the image by providing an object with the `light` and `dark` keys (these will take a similar URI as above).

```
  image: {
    light: 'https://example.com/light.png',
    dark: 'https://example.com/dark.png',
  },
```

### Events

The `FuelConnector` class provides a number of events that enable developers to listen for changes in the connector state. As part of implementing a custom connector, you can emit these events to notify the consumer dApp of changes.

#### `accounts`

The `accounts` event is emitted every time a connector's accounts change. The event data is an array of `string` addresses available on the network.

```
    const accounts: Array<string> = ['0x1234567890abcdef'];

    this.emit(this.events.accounts, accounts);
```

#### `connectors`

The `connectors` event is emitted when the connectors are initialized. The event data is an array of [`FuelConnector`](DOCS_API_URL/classes/_fuel_ts_account.FuelConnector.html) objects available on the network.

```
    const connectors: Array<FuelConnector> = [new MyWalletConnector()];

    this.emit(this.events.connectors, connectors);
```

#### `currentConnector`

The `currentConnector` event is emitted every time the current connector changes. The event data is a [`FuelConnector`](DOCS_API_URL/classes/_fuel_ts_account.FuelConnector.html) object that is currently connected.

```
    const currentConnector: FuelConnector = new MyWalletConnector();

    this.emit(this.events.currentConnector, currentConnector);
```

#### `currentAccount`

The `currentAccount` event is emitted every time the current account changes. The event data is a string containing the current account address.

```
    const currentAccount: string = '0x1234567890abcdef';

    this.emit(this.events.currentAccount, currentAccount);
```

#### `connection`

The `connection` event is emitted every time the connection status changes. The event data is a `boolean` value that is `true` if the connection is established and `false` otherwise.

```
    const connection: boolean = true;

    this.emit(this.events.connection, connection);
```

#### `networks`

The `networks` event is emitted every time the network changes. The event data will be a [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html) object containing the current network information.

```
    const network: Network = {
      chainId: 1,
      url: 'https://example.com/rpc',
    };

    this.emit(this.events.networks, network);
```

#### `currentNetwork`

The `currentNetwork` event is emitted every time the current network changes. The event data will be a [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html) object containing the current network information.

```
    const currentNetwork: Network = {
      chainId: 1,
      url: 'https://example.com/rpc',
    };

    this.emit(this.events.currentNetwork, currentNetwork);
```

#### `assets`

The `assets` event is emitted every time the assets change. The event data will be an array of [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html) objects available on the network.

```
    const assets: Array<Asset> = [
      {
        name: 'Ethereum',
        symbol: 'ETH',
        icon: 'https://assets.fuel.network/providers/eth.svg',
        networks: [
          {
            type: 'ethereum',
            chainId: 11155111,
            decimals: 18,
          },
        ],
      },
    ];

    this.emit(this.events.assets, assets);
```

#### `abis`

The `abis` event is emitted every time an ABI is added to a connector. The event data will be an array of [`FuelABI`](DOCS_API_URL/types/_fuel_ts_account.FuelABI.html) object.

```
    const assets: Array<Asset> = [
      {
        name: 'Ethereum',
        symbol: 'ETH',
        icon: 'https://assets.fuel.network/providers/eth.svg',
        networks: [
          {
            type: 'ethereum',
            chainId: 11155111,
            decimals: 18,
          },
        ],
      },
    ];

    this.emit(this.events.assets, assets);
```

### Methods

The `FuelConnector` abstract class provides a number of methods that _can_ be implemented to perform various functions. Not all the methods are required to be implemented; if you choose not to implement a given method, then just don't include it in your connector.

#### `ping`

The `ping` method is used to check if the connector is available and connected.

It will return a promise that resolves to `true` if the connector is available and connected; otherwise, it will resolve to `false`.

```
  ping(): Promise<boolean>;
```

#### `version`

The `version` method is used to get the current supported version of the connector. It returns a promise that resolves to an object containing the `app` and `network` versions.

The returned version strings can be in a range of formats:

- Caret Ranges (e.g. `^1.2.3`)
- Tilde Ranges (e.g. `~1.2.3`)
- Exact Versions (e.g. `1.2.3`)

```
  version(): Promise<Version>;
```

#### `isConnected`

The `isConnected` method informs if the connector is currently connected.

It will return a promise that resolves to `true` if the connector is established and currently connected; otherwise, it will return `false`.

```
  isConnected(): Promise<boolean>;
```

#### `connect`

The `connect` method initiates the current connectors authorization flow if a connection has not already been made.

It will return a promise that resolves to `true` if the connection has been established successfully, or `false` if the user has rejected it.

```
  connect(): Promise<boolean>;
```

#### `disconnect`

The `disconnect` method revokes the authorization of the current connector (provided by the `connect` methods).

It will return a promise that resolves to `true` if the disconnection is successful; otherwise, it will resolve to `false`.

```
  connect(): Promise<boolean>;
```

#### `accounts`

The `accounts` method should return a list of all the accounts for the current connection.

It returns a promise that resolves to an array of addresses, pointing to the accounts currently available on the network.

```
  accounts(): Promise<Array<string>>;
```

#### `currentAccount`

The `currentAccount` method will return the default account address if it's authorized with the connection.

It will return a promise to resolve the issue to an address, or if the account is not authorized for the connection, it will return `null`.

```
  currentAccount(): Promise<string | null>;
```

#### `signMessage`

The `signMessage` method initiates the sign message flow for the current connection.

It requires two arguments:

- `address` (`string`)
- `message` (`string`)

Providing the message signing flow is successful, it will return the message signature (as a `string`).

```
  signMessage(address: string, message: HashableMessage): Promise<string>;
```

#### `sendTransaction`

The `signTransaction` method initiates the send transaction flow for the current connection.

It requires two arguments:

- `address` (`string`)
- `transaction` ([`TransactionRequestLike`](DOCS_API_URL/types/_fuel_ts_account.TransactionRequestLike.html))

It will return the transaction signature (as a `string`) if it is successfully signed.

```
  sendTransaction(
    address: string,
    transaction: TransactionRequestLike,
    params?: FuelConnectorSendTxParams
  ): Promise<string | TransactionResponse>;
```

#### `assets`

The `assets` method returns a list of all the assets available for the current connection.

It will return a promise that will resolve to an array of assets (see [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html)) that are available on the network.

```
  assets(): Promise<Array<Asset>>;
```

#### `addAsset`

The `addAsset` method adds asset metadata to the connector.

It requires a single argument:

- `asset` ([`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html))

It returns a promise that resolves to `true` if the asset is successfully added; otherwise, it resolves to `false`.

```
  addAssets(assets: Array<Asset>): Promise<boolean>;
```

#### `addAssets`

The `addAssets` method adds multiple asset metadata to the connector.

It requires a single argument:

- `assets` (an Array of [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html)).

Returns a promise that resolves to `true` if the assets are successfully added; otherwise, resolves to `false`.

```
  addAssets(assets: Array<Asset>): Promise<boolean>;
```

#### `addNetwork`

The `addNetwork` method starts the add network flow for the current connection.

It requires a single argument:

- `networkUrl` (`string`)

Returns a promise that resolves to `true` if the network is successfully added; otherwise, `false`.

It should throw an error if the network is not available or the network already exists.

```
  addNetwork(networkUrl: string): Promise<boolean>;
```

#### `networks`

The `networks` method returns a list of all the networks available for the current connection.

Returns a promise that resolves to an array of available networks (see [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html)).

```
  networks(): Promise<Array<Network>>;
```

#### `currentNetwork`

The `currentNetwork` method will return the current network that is connected.

It will return a promise that will resolve to the current network (see [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html)).

```
  currentNetwork(): Promise<Network>;
```

#### `selectNetwork`

The `selectNetwork` method requests the user to select a network for the current connection.

It requires a single argument:

- `network` ([`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html))

You call this method with either the `providerUrl` or `chainId` to select the network.

It will return a promise that resolves to `true` if the network is successfully selected; otherwise, it will return `false`.

It should throw an error if the network is not available or the network does _not_ exist.

```
  selectNetwork(network: SelectNetworkArguments): Promise<boolean>;
```

#### `addABI`

The `addABI` method adds ABI information about a contract to the connector. This operation does not require an authorized connection.

It requires two arguments:

- `contractId` (`string`)
- `abi` ([`FuelABI`](DOCS_API_URL/types/_fuel_ts_account.FuelABI.html)).

It will return a promise that will resolve to `true` if the ABI is successfully added; otherwise `false`.

```
  addABI(contractId: string, abi: FuelABI): Promise<boolean>;
```

#### `getABI`

The `getABI` method is used to get the ABI information that is sorted about a contract.

It requires a single argument:

- `contractId` (`string`)

Returns a promise that resolves to the ABI information (as a [`FuelABI`](DOCS_API_URL/types/_fuel_ts_account.FuelABI.html)) or `null` if the data is unavailable.

```
  getABI(contractId: string): Promise<FuelABI | null>;
```

#### `hasABI`

The `hasABI` method checks if the ABI information is available for a contract.

It requires a single argument:

- `contractId` (`string`)

Returns a promise that resolves to `true` if the ABI information is available; otherwise `false`.

```
  hasABI(contractId: string): Promise<boolean>;
```

## Connectors Manager

The TS SDK exports the `Fuel` class, which serves as the connectors manager. This class provides the interface for interacting with the TS SDK and the broader Fuel ecosystem.

It can be instantiated as follows:

```
const sdk = new Fuel();

/*
	Awaits for initialization to mitigate potential race conditions
	derived from the async nature of instantiating a connector.
*/
await sdk.init();
```

> [!NOTE] Note
> We recommend initializing the Fuel class with the `init` method to avoid any potential race conditions that may arise from the async nature of instantiating a connector.

### Options

Several options can be passed to the `Fuel` connector manager:

- [`connectors`](#connectors)
- [`storage`](#storage)
- [`targetObject`](#targetobject)

#### `connectors`

The `connectors` option provides a list of connectors with which the `Fuel` connector manager can interact. The manager interacts with the connectors, which in turn handle communication with the respective wallet. You can find a list of all the connectors in our [`FuelLabs/fuel-connectors`](https://github.com/FuelLabs/fuel-connectors).

Below, we initialize the manager using the `defaultConnectors` method which provides an array of all the default connectors available in the `fuel-connectors` package. It's being mocked here for the purposes of this example, but you can provide your own custom connectors. Supplying the `devMode` flag as `true` will enable the development wallet for the connectors (to install visit our [wallet documentation](https://docs.fuel.network/docs/wallet/install/)).

```
import { Fuel, FuelConnector } from 'fuels';

class WalletConnector extends FuelConnector {
  public override name: string = 'My Wallet Connector';
}

const defaultConnectors = (_opts: {
  devMode: boolean;
}): Array<FuelConnector> => [new WalletConnector()];

const sdkDevMode = await new Fuel({
  connectors: defaultConnectors({
    devMode: true,
  }),
}).init();
```

#### `storage`

The `storage` is used internally to store the current connector state. It can be overridden by passing an instance that extends the `StorageAbstract` class.

```
import { Fuel, MemoryStorage } from 'fuels';

const sdkWithMemoryStorage = await new Fuel({
  storage: new MemoryStorage(),
}).init();
```

The default behavior will use `LocalStorage` if the `window` is available:

```
import { Fuel, LocalStorage } from 'fuels';

const window = {
  localStorage: {
    setItem: vi.fn(),
    getItem: vi.fn(),
    removeItem: vi.fn(),
    clear: vi.fn(),
  } as unknown as Storage,
};

const sdkWithLocalStorage = await new Fuel({
  storage: new LocalStorage(window.localStorage),
}).init();
```

#### `targetObject`

The `targetObject` provides a target with which the `Fuel` manager can interact. Used for registering events and can be overridden as follows:

```
import { Fuel } from 'fuels';
import type { TargetObject } from 'fuels';

const emptyWindow = {} as unknown as TargetObject;

const targetObject: TargetObject = emptyWindow || document;

const sdkWithTargetObject = await new Fuel({
  targetObject,
}).init();
```

### Methods

The `Fuel` manager provides several methods to interact with the Manager:

#### All methods from connectors

The `Fuel` manager provides all the [methods](#methods) available from the connected connectors. Thus, you can interact with the current connector as if you were interacting with the `Fuel` manager directly.

If no current connector is available or connected, it will throw an error.

#### `connectors`

The `connectors` method gets the current list of _installed_ and _connected_ connectors.

```
  connectors: () => Promise<Array<FuelConnector>>;
```

#### `getConnector`

The `getConnector` method resolves a connector by its name. This is useful for finding a specific connector with which to interact. If the connector is not found, it will return `null`.

```
  getConnector: (connector: FuelConnector | string) => FuelConnector | null;
```

#### `hasConnector`

The `hasConnector` method will return `true` under the following conditions:

- There is a current connector that is connected.
- A connector is connected within two seconds of calling the method.

```
  hasConnector(): Promise<boolean>;
```

#### `selectConnector`

The `selectConnector` method accepts a connector name and will return `true` when it is _available_ and _connected_. Otherwise, if not found or unavailable, it will return `false`.

```
  selectConnector(connectorName: string, options: FuelConnectorSelectOptions): Promise<boolean>;
```

#### `currentConnector`

The `currentConnector` method will return the current connector that is connected or if one is available and connected, otherwise it'll return `null` or `undefined`.

```
  currentConnector(): FuelConnector | null | undefined;
```

#### `getWallet`

The `getWallet` method accepts an address (string or instance) as the first parameter and a provider or network as the second parameter. It will return an `Account` instance for the given address (providing it is valid).

The provider or network will default to the current network if not provided. When a provider cannot be resolved, it will throw an [`INVALID_PROVIDER`](../errors/index.md) error.

```
  getWallet(address: string | Address, providerOrNetwork?: Provider | Network): Promise<Account>;
```

#### `clean`

The `clean` method removes all the data currently stored in the [`storage`](#storage) instance.

```
  clean(): Promise<void>;
```

#### `unsubscribe`

The `unsubscribe` method removes all currently registered event listeners.

```
  unsubscribe(): void;
```

#### `destroy`

The `destroy` method unsubscribes from all the event listeners and clears the storage.

```
  destroy(): Promise<void>;
```

## Learning Resources

For a deeper understanding of `Fuel Connectors` and how to start using them in your projects, consider the following resources:

- [**Fuel Connectors Wiki**](https://github.com/FuelLabs/fuel-connectors/wiki) - read about what a `Fuel Connector` is and how it works.
- [**Fuel Connectors Guide**](https://docs.fuel.network/docs/wallet/dev/connectors/) - find out how to set up and use connectors.
- [**GitHub Repository**](https://github.com/FuelLabs/fuel-connectors) - explore different connector implementations.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/encrypting-and-decrypting.md.md

# Encrypting and Decrypting

JSON wallets are a standardized way of storing wallets securely. They follow a specific schema and are encrypted using a password. This makes it easier to manage multiple wallets and securely store them on disk. This guide will take you through the process of encrypting and decrypting JSON wallets using the Typescript SDK.

## Encrypting a Wallet

We will be calling `encrypt` from the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instance which will take a password as the argument. It will encrypt the private key using a cipher and returns the JSON keystore wallet. You can then securely store this JSON wallet.

Here is an example of how you can accomplish this:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.generate({ provider });

// Encrypt the wallet
const password = 'my-password';
const jsonWallet = await wallet.encrypt(password);

// Save the encrypted wallet to a file
// e.g. const jsonWallet = fs.writeFileSync('secure-path/my-wallet.json', jsonWallet);
```

Please note that `encrypt` must be called within an instance of [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html). This instance can only be achieved through passing a private key or mnemonic phrase to a locked wallet.

## Decrypting a Wallet

To decrypt the JSON wallet and retrieve your private key, you can call `fromEncryptedJson` on a [Wallet](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html) instance. It takes the encrypted JSON wallet and the password as its arguments, and returns the decrypted wallet.

Here is an example:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const newJsonWallet = await Wallet.generate({
  provider,
}).encrypt('my-password');

// Load the encrypted wallet from a file
// const jsonWallet = fs.readFileSync('secure-path/my-wallet.json', 'utf-8');

// Decrypt the wallet
const newPassword = 'my-password';
const decryptedWallet = await Wallet.fromEncryptedJson(
  newJsonWallet,
  newPassword,
  provider
);

// Use the decrypted wallet
const myBalance = await decryptedWallet.getBalance();
```

In this example, `decryptedWallet` is an instance of [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) class, now available for use.

## Important

Remember to securely store your encrypted JSON wallet and password. If you lose them, there will be no way to recover your wallet. For security reasons, avoid sharing your private key, encrypted JSON wallet or password with anyone.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/index.md.md

# Wallets

Wallets can be used for many important things, for instance:

1. Checking your balance;
2. Transferring coins to a destination address or contract;
3. Signing messages and transactions;
4. Paying for network fees when sending transactions or deploying smart contracts.

## Wallets Instances

The SDK has multiple classes related to a Wallet instance:

- [Wallet](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html): Works simply like a wrapper providing methods to create and instantiating `WalletUnlocked` and `WalletLocked` instances.

- [WalletLocked](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html): Provides the functionalities for a locked wallet.

- [WalletUnlocked](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html): Provides the functionalities for an unlocked wallet.

- [Account](DOCS_API_URL/classes/_fuel_ts_account.Account.html): Provides an abstraction with basic functionalities for wallets or accounts to interact with the network. It is essential to notice that both `WalletLocked` and `WalletUnlocked` extend from the `Account` class.

Let's explore these different approaches in the following sub-chapters.

> **Note:** Keep in mind that you should never share your private/secret key. And in the case of wallets that were derived from a mnemonic phrase, never share your mnemonic phrase. If you're planning on storing the wallet on disk, do not store the plain private/secret key and do not store the plain mnemonic phrase. Instead, use `WalletManager` to encrypt its content first before saving it to disk.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/instantiating-wallets.md.md

# Instantiating Wallets

Wallets can be instantiated in multiple ways within the SDK.

## Generating new wallets

To generate a new, unlocked wallet, use the [`generate`](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html#generate) method. This method creates a new [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instance, which is immediately ready for use.

```
import { Wallet } from 'fuels';
import type { WalletUnlocked } from 'fuels';

const wallet: WalletUnlocked = Wallet.generate();
```

## Instantiating Unlocked Wallets

Creating [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instances of your existing wallets is easy and can be done in several ways:

From a private key:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const privateKey =
  '0x36ca81ba70f3e04b7cc8780bff42d907ebca508097d4ae3df5147c93fd217f7c';

const wallet: WalletUnlocked = Wallet.fromPrivateKey(privateKey);
```

From a mnemonic phrase:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const mnemonic =
  'section gospel lady april mouse huge prosper boy urge fox tackle orient';

const wallet: WalletUnlocked = Wallet.fromMnemonic(mnemonic);
```

From a seed:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const seed =
  '0xa5d42fd0cf8825fc846b2f257887a515573ee5b779e99f060dc945b3d5504bca';

const wallet: WalletUnlocked = Wallet.fromSeed(seed);
```

From a Hierarchical Deterministic (HD) derived key:

```
import type { WalletUnlocked } from 'fuels';
import { HDWallet, Wallet } from 'fuels';

const seed =
  '0xa5d42fd0cf8825fc846b2f257887a515573ee5b779e99f060dc945b3d5504bca';

const extendedKey = HDWallet.fromSeed(seed).toExtendedKey();

const wallet: WalletUnlocked = Wallet.fromExtendedKey(extendedKey);
```

From a JSON wallet:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const jsonWallet = `{"id":"83d1792f-3230-496a-92af-3b44a1524fd6","version":3,"address":"ada436e1b80f855f94d678771c384504e46335f571aa244f11b5a70fe3e61644","crypto":{"cipher":"aes-128-ctr","mac":"6911499ec31a6a6d240220971730374396efd666bd34123d4e3ce85e4cf248c6","cipherparams":{"iv":"40576cbd4f7c84e88b0532320e23b425"},"ciphertext":"3e5e77f23444aa86b397dbc62e14d8b7d3fd7c7fe209e066bb7df17eca398129","kdf":"scrypt","kdfparams":{"dklen":32,"n":8192,"p":1,"r":8,"salt":"b046520d85090ee2abd6285174f37bc01e28846b6bb5edc03ae5f7c13aec03d2"}}}`;

const password = 'password';

const wallet: WalletUnlocked = await Wallet.fromEncryptedJson(
  jsonWallet,
  password
);
```

It's possible to instantiate a `WalletUnlocked` from a `WalletLocked`:

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const address =
  '0x4cb2b5d2bdbcc8dbdbf91cd00be3e2deedb0ea0f34c969c0ed741a1925111a87';
const privateKey =
  '0x9deba03f08676716e3a4247797672d8008a5198d183048be65415ef89447b890';

const lockedWallet: WalletLocked = Wallet.fromAddress(address);

const wallet: WalletUnlocked = lockedWallet.unlock(privateKey);
```

## Instantiating Locked Wallets

You can also instantiate [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) instances using just the wallet address:

```
import type { B256Address, WalletLocked } from 'fuels';
import { Wallet } from 'fuels';

const address: B256Address = `0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f`;

const wallet: WalletLocked = Wallet.fromAddress(address);
```

## Connecting to a Provider

While wallets can be used independently of a [`Provider`](DOCS_API_URL/classes/_fuel_ts_account.Provider.html), operations requiring blockchain interaction will need one.

Connecting an existing wallet to a Provider:

```
import type { WalletLocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_ADDRESS } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet: WalletLocked = Wallet.fromAddress(WALLET_ADDRESS);
wallet.connect(provider);
```

Instantiating a wallet with a Provider:

```
import type { WalletLocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_ADDRESS } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet: WalletLocked = Wallet.fromAddress(WALLET_ADDRESS, provider);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/locking-and-unlocking.md.md

# Locking and Unlocking

The kinds of operations we can perform with a [`Wallet`](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html) instance depend on
whether or not we have access to the wallet's private key.

In order to differentiate between [`Wallet`](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html) instances that know their private key
and those that do not, we use the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) and [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) types
respectively.

## Wallet States

The [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) type represents a wallet whose private key is known and
stored internally in memory. A wallet must be of type [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) in order
to perform operations that involve [signing messages or transactions](./signing.md).

The [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) type represents a wallet whose private key is _not_ known or stored
in memory. Instead, [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) only knows its public address. A [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) cannot be
used to sign transactions, however it may still perform a whole suite of useful
operations including listing transactions, assets, querying balances, and so on.

Note that the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) type implements most methods available on the [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html)
type. In other words, [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) can be thought of as a thin wrapper around [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) that
provides greater access via its private key.

## Basic Example

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
```

## Optional Provider

You can choose not to pass through a provider argument on `Wallet` construction:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

// You can create a wallet, without a provider
let unlockedWalletWithoutProvider: WalletUnlocked = Wallet.generate();
unlockedWalletWithoutProvider = Wallet.fromPrivateKey(
  unlockedWalletWithoutProvider.privateKey
);

// All non-provider dependent methods are available
unlockedWalletWithoutProvider.lock();

// All provider dependent methods will throw
try {
  await unlockedWalletWithoutProvider.getCoins();
} catch (e) {
  console.log('error', e);
}
```

## Transitioning States

A [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) instance can be unlocked by providing the private key:

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet: WalletUnlocked = Wallet.generate({ provider });
const PRIVATE_KEY = wallet.privateKey;

// Lock an existing wallet
const lockedWallet: WalletLocked = Wallet.fromAddress(wallet.address, provider);

// Unlock an existing wallet
const someUnlockedWallet: WalletUnlocked = lockedWallet.unlock(PRIVATE_KEY);
```

A [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instance can be locked using the `lock` method:

```
import type { WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const unlockedWallet: WalletUnlocked = Wallet.generate({ provider });
const newlyLockedWallet = unlockedWallet.lock();
```

Most wallet constructors that create or generate a new wallet are provided on
the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) type. Consider locking the wallet with the `lock` method after the new private
key has been handled in order to reduce the scope in which the wallet's private
key is stored in memory.

## Design Guidelines

When designing APIs that accept a wallet as an input, we should think carefully
about the kind of access that we require. API developers should aim to minimise
their usage of [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) in order to ensure private keys are stored in
memory no longer than necessary to reduce the surface area for attacks and
vulnerabilities in downstream libraries and applications.

## Full Example

For a full example of how to lock and unlock a wallet, see the snippet below:

```
// #region wallets
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
// #endregion wallets

const wallet: WalletUnlocked = Wallet.generate({ provider });
const PRIVATE_KEY = wallet.privateKey;

// Lock an existing wallet
const lockedWallet: WalletLocked = Wallet.fromAddress(
  myWallet.address,
  provider
);

// Unlock an existing wallet
const someUnlockedWallet: WalletUnlocked = lockedWallet.unlock(PRIVATE_KEY);

const unlockedWallet: WalletUnlocked = Wallet.generate({ provider });
const newlyLockedWallet = unlockedWallet.lock();

// You can create a wallet, without a provider
let unlockedWalletWithoutProvider: WalletUnlocked = Wallet.generate();
unlockedWalletWithoutProvider = Wallet.fromPrivateKey(
  unlockedWalletWithoutProvider.privateKey
);

// All non-provider dependent methods are available
unlockedWalletWithoutProvider.lock();

// All provider dependent methods will throw
await expect(() => unlockedWalletWithoutProvider.getCoins()).rejects.toThrow(
  /Provider not set/
);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/mnemonic-wallet.md.md

# Creating a wallet from mnemonic phrases

A mnemonic phrase is a cryptographically-generated sequence of words that's used to derive a private key. For instance: `"oblige salon price punch saddle immune slogan rare snap desert retire surprise";` would generate the address `0xdf9d0e6c6c5f5da6e82e5e1a77974af6642bdb450a10c43f0c6910a212600185`.

In addition to that, we also support [Hierarchical Deterministic Wallets](https://www.ledger.com/academy/crypto/what-are-hierarchical-deterministic-hd-wallets) and [derivation paths](https://learnmeabitcoin.com/technical/derivation-paths), allowing multiple wallets to be derived from a single root mnemonic. You may recognize a derivation path like:

```text
"m/44'/1179993420'/0'/0/0"
```

In simple terms, this structure enables the creation of multiple wallet addresses from the same mnemonic phrase.

The SDK gives you two wallets from mnemonic instantiation methods: one that takes a derivation path and one that uses the default derivation path, in case you don't want or don't need to configure that.

Here's how you can create wallets with both mnemonic phrases and derivation paths:

1 - Using the default derivation path `m/44'/1179993420'/0'/0/0`

```
const mnemonic =
  'oblige salon price punch saddle immune slogan rare snap desert retire surprise';

const wallet = Wallet.fromMnemonic(mnemonic);
```

2 - Using a Custom Derivation Path

```
const mnemonic =
  'oblige salon price punch saddle immune slogan rare snap desert retire surprise';

const path = "m/44'/60'/1'/0/0";

const wallet = Wallet.fromMnemonic(mnemonic, path);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/private-keys.md.md

# Creating a wallet from a private key

A new wallet with a randomly generated private key can be created by supplying `Wallet.generate`.

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
```

Alternatively, you can create a wallet from a Private Key:

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_ADDRESS,
  WALLET_PVT_KEY,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

// Generate a locked wallet
const lockedWallet: WalletLocked = Wallet.fromAddress(WALLET_ADDRESS, provider);

// Unlock an existing unlocked wallet
let unlockedWallet: WalletUnlocked = lockedWallet.unlock(WALLET_PVT_KEY);
// Or directly from a private key
unlockedWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY);
```

You can obtain an address to a private key using the `Signer` package

```
import { Signer } from 'fuels';

import { WALLET_PVT_KEY } from '../../../../env';

const signer = new Signer(WALLET_PVT_KEY);
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/signing.md.md

# Signing

## Signing Messages

Signing messages with a wallet is a fundamental security practice in a blockchain environment. It can be used to verify ownership and ensure the integrity of data.

Here's how to use the `wallet.signMessage` method to sign messages (as string):

```
import { hashMessage, Signer, WalletUnlocked } from 'fuels';

const wallet = WalletUnlocked.generate();

const message: string = 'my-message';
const signedMessage = await wallet.signMessage(message);
// Example output: 0x277e1461cbb2e6a3250fa8c490221595efb3f4d66d43a4618d1013ca61ca56ba

const hashedMessage = hashMessage(message);
// Example output: 0x40436501b686546b7c660bb18791ac2ae35e77fbe2ac977fc061922b9ec83766

const recoveredAddress = Signer.recoverAddress(hashedMessage, signedMessage);
// Example output: Address {
//   b256Address: '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
// }
```

The `signMessage` method internally:

- Hashes the message (via `hashMessage`)
- Signs the hashed message using the wallet's private key
- Returns the signature as a hex string

The `hashMessage` helper will:

- Performs a SHA-256 hash on the UTF-8 encoded message.

The `recoverAddress` method from the `Signer` class will take the hashed message and the signature to recover the signer's address. This confirms that the signature was created by the holder of the private key associated with that address, ensuring the authenticity and integrity of the signed message.

## Signing Personal Message

We can also sign arbitrary data, not just strings. This is possible by passing an object containing the `personalSign` property to the `hashMessage` and `signMessage` methods:

```
const message: string | Uint8Array = Uint8Array.from([0x01, 0x02, 0x03]);
const signedMessage = await wallet.signMessage({ personalSign: message });
// Example output: 0x0ca4ca2a01003d076b4044e38a7ca2443640d5fb493c37e28c582e4f2b47ada7

const hashedMessage = hashMessage({ personalSign: message });
// Example output: 0x862e2d2c46b1b52fd65538c71f7ef209ee32f4647f939283b3dd2434cc5320c5
```

The primary difference between this [personal message signing](#signing-personal-message) and [message signing](#signing-messages) is the underlying hashing format.

To format the message, we use a similar approach to a [EIP-191](https://eips.ethereum.org/EIPS/eip-191):

```console
\x19Fuel Signed Message:\n<message length><message>
```

> **Note**: We still hash using `SHA-256`, unlike Ethereum's [EIP-191](https://eips.ethereum.org/EIPS/eip-191) which uses `Keccak-256`.

## Signing Transactions

Signing a transaction involves using your wallet to sign the transaction ID (also known as [transaction hash](https://docs.fuel.network/docs/specs/identifiers/transaction-id/)) to authorize the use of your resources. Here's how it works:

1. `Generate a Signature`: Using the wallet to create a signature based on the transaction ID.

2. `Using the Signature on the transaction`: Place the signature in the transaction's `witnesses` array. Each Coin / Message input should have a matching `witnessIndex`. This index indicates your signature's location within the `witnesses` array.

3. `Security Mechanism`: The transaction ID is derived from the transaction bytes (excluding the `witnesses`). If the transaction changes, the ID changes, making any previous signatures invalid. This ensures no unauthorized changes can be made after signing.

The following code snippet exemplifies how a Transaction can be signed:

```
import {
  Address,
  Provider,
  ScriptTransactionRequest,
  Signer,
  Wallet,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiverAddress = Address.fromRandom();

const request = new ScriptTransactionRequest();

const transferAmount = 1000;

request.addCoinOutput(
  receiverAddress,
  transferAmount,
  await provider.getBaseAssetId()
);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: sender,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: await provider.getBaseAssetId(),
      account: sender,
      changeOutputAccount: sender,
    },
  ],
});

const signedTransaction = await sender.signTransaction(assembledRequest);
const transactionId = request.getTransactionId(await provider.getChainId());

const recoveredAddress = Signer.recoverAddress(
  transactionId,
  signedTransaction
);

request.updateWitnessByOwner(recoveredAddress, signedTransaction);

const tx = await provider.sendTransaction(request);
await tx.waitForResult();
```

Similar to the sign message example, the previous code used `Signer.recoverAddress` to get the wallet's address from the transaction ID and the signed data.

When using your wallet to submit a transaction with `wallet.sendTransaction()`, the SDK already handles these steps related to signing the transaction and adding the signature to the `witnesses` array. Because of that, you can skip this in most cases:

```
import { Address, Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiverAddress = Address.fromRandom();

const transferAmount = 1000;

const request = new ScriptTransactionRequest();

request.addCoinOutput(receiverAddress, 1000, await provider.getBaseAssetId());

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: sender,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: await provider.getBaseAssetId(),
      account: sender,
      changeOutputAccount: sender,
    },
  ],
});

const tx = await sender.sendTransaction(assembledRequest);
await tx.waitForResult();
```


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/wallet-manager.md.md

# Wallet Manager

The `WalletManager` is a robust tool designed for managing vaults of wallets. It offers robust management of vaults, including support for custom storage and powerful encryption of all held vaults.

## Key Features

### Managing Vaults with `WalletManager`

This includes adding new wallets to specific vaults, retrieving all wallets from a vault, exporting specific vaults, and exporting private keys. The `WalletManager` class currently supports two types of vaults: `PrivateKeyVault` and `MnemonicVault`.

### Custom Storage Solutions

The `WalletManager` supports defining a custom storage solution, allowing you to specify how and where the encrypted vaults are saved. With support for custom storage, you can make the `WalletManager` to fit your specific needs and security requirements.

### Locking and Unlocking `WalletManager`

The `WalletManager` implements an automatic encryption mechanism, securely saving the wallet's held vaults. This not only preserves the state of your vaults but also ensures robust protection of the stored information. When needed, you can easily unlock and decrypt the vaults using the previously defined password.

## Getting Started with `WalletManager`

This guide provides step-by-step instructions on how to use `WalletManager`.

### Instantiating `WalletManager`

The `WalletManager` constructor accepts an optional object to define its storage. The storage describes how and where the `WalletManager` will store its vaults of wallets. If storage is not provided, the `WalletManager` uses a default one that does not persist data.

For now, let's keep it simple and not worry about the storage. Later we will discuss it in more detail.

To instantiate a `WalletManager` you can simply:

```
// Initialize a WalletManager
const walletManager = new WalletManager();
```

### Setting `WalletManager` Password

By default, a `WalletManager` instance is locked when created. Before using it, you need to unlock it by setting a password. You can do this by calling the `unlock` method.

```
const password = 'my-password';

await walletManager.unlock(password);
```

Once your `WalletManager` is unlocked, it can manage your wallets.

### Managing Vaults with `WalletManager`

A vault in `WalletManager` serves as a secure container for wallets. The `WalletManager` manages wallets by interacting with these vaults, supporting operations such as `getAccounts`, which returns public information about all wallets stored in the vault, and `exportAccount`, which exports a private key for a given wallet address.

To add a vault, we utilize the `addVault` method. Here's how we can create a private key vault and add a private key from a wallet we own:

```
// Initialize a Provider
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet = Wallet.generate({
  provider,
});

const privateKey = myWallet.privateKey;

await walletManager.addVault({
  type: 'privateKey',
  secret: privateKey,
  title: 'My first private key vault',
});
```

The `addVault` method requires an object with three properties: `type`, `secret`, and `title`. The `WalletManager` currently supports two types of vaults: `privateKeyVault` and `mnemonicVault`. For the `secret`, we use our wallet's private key, and for the `title`, we can provide a custom name.

By running this code, `WalletManager` creates a new vault instance of the type `privateKey` and adds one account (our wallet) to this newly created vault.

A key feature of the `WalletManager` is its ability to manage multiple vaults, even of the same type. This implies that if you run the `addVault` method again, with the same parameters, `WalletManager` will create another vault of the type `privateKey`, holding the same wallet. Here's an example:

```
await walletManager.addVault({
  type: 'privateKey',
  secret: privateKey,
  title: 'My second private key vault',
});
```

After executing this, you will find that your `WalletManager` is managing two `privateKey` vaults, both storing the same wallet.

Remember, both `title` and `secret` are optional when adding vaults, but providing a `title` makes it easier to manage your vaults and wallets. If you add a vault without providing a `secret`, this will result in one new account (wallet) being generated by the vault it self.

### Using The `WalletManager`

With your `WalletManager` set up, you can now access your vaults and wallets. Here's how to retrieve the details of your vaults:

```
const vaults = walletManager.getVaults();
```

This will output something like this:

```
// [
//     {
//         title: 'My first private key vault',
//         type: 'privateKey',
//         vaultId: 0
//     },
//     {
//         title: 'My second private key vault',
//         type: 'privateKey',
//         vaultId: 1
//     }
// ]
```

As you can see, the `WalletManager` assigns unique `vaultIds` for each vault. The first vault you added has a `vaultId` of `0`, and the second one has a `vaultId` of `1`.

Let's retrieve your wallet instance with the `getWallet` method:

```
const retrievedWallet = walletManager.getWallet(myWallet.address);
```

This guide walked through the steps to instantiate a `WalletManager`, set up its first vault, and retrieve vault information. The following sections will explore more functionalities of `WalletManager`, and go deeper into the usage of its vaults and the details of its storage system.

## Locking and Unlocking `WalletManager`

This guide will walk you through the process of managing the lock state of your wallets using the `WalletManager`.

### Initializing and Unlocking the `WalletManager`

As mentioned earlier, a `WalletManager` instance begins in a locked state. Before usage, you need to unlock it by providing a password via the unlock method.

```
const password = '0b540281-f87b-49ca-be37-2264c7f260f7';

const walletManager = new WalletManager();

await walletManager.unlock(password);
```

### Locking the `WalletManager`

When you lock the `WalletManager` using the `lock` method, all its vaults and associated accounts (wallets) are cleared. This clearance is possible due to the encryption and saving of all data by the storage system. `WalletManager` frequently uses the storage system to preserve its state. Consequently, sensitive operations including exporting vaults, private keys, accessing wallets, and saving/loading the `WalletManager` state are not possible when it is locked.

```
await walletManager.lock();
```

Remember, it's crucial to lock your `WalletManager` when it's not in use to ensure the safety of your funds.

### Reaccessing Your Wallets by Unlocking the `WalletManager`

The `unlock` method requires the previously set password to unlock the `WalletManager` and all its vaults. The password decrypts the stored vaults, allowing `WalletManager` to load its saved data.

```
await walletManager.unlock(password);
```

Providing an incorrect password will result in an error. However, when unlocked successfully, `WalletManager` is ready for use again.

### Verifying the Lock State

You can confirm the current lock state of the `WalletManager` by using the `isLocked` method:

```
const isLocked = walletManager.isLocked;
```

### Updating the Password

To change the current password, invoke the `updatePassphrase` method, and provide both the old and new passwords:

```
const newPassword = 'my-new-password';

await walletManager.updatePassphrase(password, newPassword);
```

### Reminder: Always Lock Your `WalletManager`

Always ensure you lock the `WalletManager` after completing operations. This step is critical for securing your wallets.

```
await walletManager.unlock(newPassword);

// perform your tasks...

walletManager.lock(); // Always lock your WalletManager when you're done
```

By using `WalletManager` to manage lock and unlock states, you introduce an additional layer of security. Never forget to lock your `WalletManager` when it's not in use.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/guide/wallets/wallet-transferring.md.md

# Wallet Transferring

This guide provides instructions for transferring assets between wallets and contracts using the SDK. It includes methods to validate balances and initiate and configure transfer requests.

## Transferring Assets Between Accounts

The `transfer` method initiates a transaction request that transfers an asset from one wallet to another. This method requires three parameters:

1. The receiver's wallet address
2. The amount of the asset to be transferred
3. The ID of the asset to be transferred (optional - defaults to the base asset ID)

Upon execution, this function returns a promise that resolves to a transaction response. To wait for the transaction to be processed, call `response.waitForResult()`.

### Example

Here is an example of how to use the `transfer` function:

```
import { Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const destination = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const amountToTransfer = 500;

const response = await sender.transfer(
  destination.address,
  amountToTransfer,
  baseAssetId
);

await response.waitForResult();

// Retrieve balances
const balance = await destination.getBalance(baseAssetId);
```

In the previous example, we used the `transfer` method which creates a `ScriptTransactionRequest`, populates its data with the provided transfer information and submits the transaction.

However, there may be times when you need the Transaction ID before actually submitting it to the node. To achieve this, you can simply call the `createTransfer` method instead.

This method also creates a `ScriptTransactionRequest` and populates it with the provided data but returns the request object prior to submission.

```
import { Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const destination = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const amountToTransfer = 200;
const baseAssetId = await provider.getBaseAssetId();

const transactionRequest = await sender.createTransfer(
  destination.address,
  amountToTransfer,
  baseAssetId
);

const chainId = await provider.getChainId();

const transactionId = transactionRequest.getTransactionId(chainId);

const response = await sender.sendTransaction(transactionRequest);

// The transaction id is the same one returned by the code above.
const { id } = await response.wait();
```

> **Note**: Any changes made to a transaction request will alter the transaction ID. Therefore, you should only get the transaction ID after all modifications have been made.

```
import { bn, Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const destination = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const amountToTransfer = 200;
const baseAssetId = await provider.getBaseAssetId();

const transactionRequest = await sender.createTransfer(
  destination.address,
  amountToTransfer,
  baseAssetId
);

const chainId = await provider.getChainId();

const transactionId = transactionRequest.getTransactionId(chainId);

/**
 * Modifying any property of the transaction request, except for the number
 * of witnesses within the ".witnesses" array, will generate a new transaction
 * hash, resulting in a different transaction ID.
 */
transactionRequest.gasLimit = bn(1000);

const response = await sender.sendTransaction(transactionRequest);

// The transaction id here is NOT the same one returned above.
const { id } = await response.wait();
```

## Transferring Assets To Multiple Wallets

To transfer assets to multiple wallets, use the `Account.batchTransfer` method:

```
import type { TransferParams } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const recipient1 = Wallet.generate({ provider });
const recipient2 = Wallet.generate({ provider });

const someOtherAssetId =
  '0x0101010101010101010101010101010101010101010101010101010101010101';
const transfersToMake: TransferParams[] = [
  {
    amount: 100,
    assetId: baseAssetId,
    destination: recipient1.address,
  },
  {
    amount: 200,
    assetId: baseAssetId,
    destination: recipient2.address,
  },
  {
    amount: 300,
    assetId: someOtherAssetId,
    destination: recipient2.address,
  },
];

const tx = await sender.batchTransfer(transfersToMake);
await tx.waitForResult();
```

## Transferring Assets To Contracts

When transferring assets to a deployed contract, we use the `transferToContract` method, which shares a similar parameter structure with the `transfer` method.

However, instead of supplying the target wallet's address, as done in `destination.address` for the transfer method, we need to provide an instance of [Address](../types/address.md) created from the deployed contract id.

If you have the [Contract](../contracts/) instance of the deployed contract, you can simply use its `id` property. However, if the contract was deployed with `forc deploy` or not by you, you will likely only have its ID in a hex string format. In such cases, you can create an [Address](../types/address.md) instance from the contract ID using `new Address('0x123...')`.

Here's an example demonstrating how to use `transferToContract`:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const deploy = await CounterFactory.deploy(sender);
const { contract } = await deploy.waitForResult();

const amountToTransfer = 400;
const assetId = await provider.getBaseAssetId();
const contractId = contract.id;

const tx = await sender.transferToContract(
  contractId,
  amountToTransfer,
  assetId
);

await tx.waitForResult();
```

_Note: Use `transferToContract` exclusively for transfers to a contract. For transfers to an account address, use `transfer` instead._

## Transferring Assets To Multiple Contracts

Similar to the `Account.batchTransfer` method, you can transfer multiple assets to multiple contracts using the `Account.batchTransferToContracts` method. Here's how it works:

```
import type { ContractTransferParams } from 'fuels';
import { Provider, Wallet } from 'fuels';
import { TestAssetId } from 'fuels/test-utils';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory, EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const baseAssetId = await provider.getBaseAssetId();
const assetA = TestAssetId.A.value;

const deploy1 = await CounterFactory.deploy(sender);
const { contract: contract1 } = await deploy1.waitForResult();

const deploy2 = await EchoValuesFactory.deploy(sender);
const { contract: contract2 } = await deploy2.waitForResult();

const contractTransferParams: ContractTransferParams[] = [
  {
    contractId: contract1.id,
    amount: 999,
    assetId: baseAssetId,
  },
  {
    contractId: contract1.id,
    amount: 550,
    assetId: assetA,
  },
  {
    contractId: contract2.id,
    amount: 200,
    assetId: assetA,
  },
];

const transfer = await sender.batchTransferToContracts(contractTransferParams);
await transfer.waitForResult();
```

Always remember to call the `waitForResult()` function on the transaction response. That ensures the transaction has been mined successfully before proceeding.

_Note: Use `batchTransferToContracts` solely for transferring assets to contracts. Do not use account addresses with this method. For multiple account transfers, use `batchTransfer` instead._

## Checking Balances

Before you transfer assets, please make sure your wallet has enough funds. Attempting a transfer without enough funds will result in the error: `The transaction does not have enough funds to cover its execution.`

You can see how to check your balance at the [`checking-balances`](./checking-balances.md) page.


---

### File: docs/fuels-ts/fuels-ts/apps/docs/src/index.md.md

<script setup>
  import { data } from './versions.data'
  const { forc, fuels, fuelCore } = data
  const url = `https://docs.fuel.network/docs/forc/`
  const logoSrc = './fuel-logo.png'
</script>

# The Fuel TypeScript SDK

The Fuel TypeScript SDK provides methods and utilities in TypeScript, for developing on or interacting with the Fuel network and its [ecosystem](https://docs.fuel.network/docs/intro/what-is-fuel/).

Using the SDK you can:

- Deploy, interact with, and test [Sway](https://docs.fuel.network/docs/sway/) contracts.
- Bootstrap a dApp and local development environment using the [create fuels CLI](https://docs.fuel.network/docs/fuels-ts/creating-a-fuel-dapp/).
- Generate and import wallets from private key, mnemonic, or JSON and safely store them on the client.
- Craft custom transactions and mutate them by adding resources, policies and signers and submit them.
- Generate types for [Sway programs](https://docs.fuel.network/docs/sway/sway-program-types/) using [typegen](https://docs.fuel.network/docs/fuels-ts/fuels-cli/abi-typegen/) to give end-to-end type safety.

## Version

This documentation was generated using Fuels `v{{fuels}}`, Fuel Core `v{{fuelCore}}`, Sway `v{{forc}}`, and Forc `v{{forc}}`.

## API Documentation

The Complete API documentation for the SDK is available [here](DOCS_API_URL/).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/call-parameters.md.md

# Call Parameters

<!-- This section should explain call params -->
<!-- call_params:example:start -->

When interacting with contracts, you can configure specific parameters for contract calls using the `callParams` method. The available call parameters are:

1. `forward`
2. `gasLimit`
<!-- call_params:example:end -->

> **Note**: Setting transaction parameters is also available when calling contracts. More information on this can be found at [Transaction Parameters](../transactions/adding-parameters.md).

The contract in use in this section has the following implementation:

```
impl ReturnContext for Contract {
    #[payable]
    fn return_context_amount() -> u64 {
        msg_amount()
    }
}
```

## Forward Parameter

<!-- This section should explain the `forward` param -->
<!-- forward:example:start -->

The `forward` parameter allows the sending of a specific amount of coins to a contract when a function is called. This is useful when a contract function requires coins for its execution, such as transferring funds to another account or contract.

The forward parameter helps you control the resources allocated to the contract call and offers protection against potentially costly operations.

<!-- forward:example:end -->

```
const amountToForward = 10;
const baseAssetId = await provider.getBaseAssetId();

const { waitForResult } = await contract.functions
  .return_context_amount()
  .callParams({
    forward: [amountToForward, baseAssetId],
  })
  .call();

const { value } = await waitForResult();

console.log('forwarded amount:', value.toNumber());
// forwarded amount: 10
```

## Gas Limit Parameter

<!-- This section should explain the `gasLimit` param -->
<!-- gas_limit:example:start -->

The `gasLimit` refers to the maximum amount of gas that can be consumed specifically by the contract call itself, separate from the rest of the transaction.

<!-- gas_limit:example:end -->

```
try {
  await contract.functions
    .return_context_amount()
    .callParams({
      forward: [10, await provider.getBaseAssetId()],
      gasLimit: 1,
    })
    .call();
} catch (e) {
  console.log('error', e);
  // error _FuelError: The transaction reverted with reason: "OutOfGas"
}
```

## Call Parameter `gasLimit` vs Transaction Parameter `gasLimit`

The call parameter `gasLimit` sets the maximum gas allowed for the actual contract call, whereas the transaction parameter `gasLimit` _(see [Transaction Parameters](../transactions/adding-parameters.md))_ sets the maximum gas allowed for the entire transaction and constrains the `gasLimit` call parameter. If the call parameter `gasLimit` is set to a value greater than the _available_ transaction gas, then the entire available transaction gas will be allocated for the contract call execution.

If you don't set the `gasLimit` for the call, the transaction `gasLimit` will be applied.

## Setting Both Parameters

You can set both call parameters and transaction parameters within the same contract function call.

```
const contractCallGasLimit = 4_000;
const transactionGasLimit = 100_000;

const call = await contract.functions
  .return_context_amount()
  .callParams({
    forward: [10, await provider.getBaseAssetId()],
    gasLimit: contractCallGasLimit,
  })
  .txParams({
    gasLimit: transactionGasLimit,
  })
  .call();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/configurable-constants.md.md

# Configurable Constants

Sway introduces a powerful feature: configurable constants. When creating a contract, you can define constants, each assigned with a default value.

Before deploying the contract, you can then redefine the value for these constants, it can be all of them or as many as you need.

This feature provides flexibility for dynamic contract environments. It allows a high level of customization, leading to more efficient and adaptable smart contracts.

## Defining Configurable Constants

Below is an example of a contract in which we declare four configurable constants:

```
contract;

enum MyEnum {
    Checked: (),
    Pending: (),
}

struct MyStruct {
    x: u8,
    y: u8,
    state: MyEnum,
}

configurable {
    age: u8 = 25,
    tag: str[4] = __to_str_array("fuel"),
    grades: [u8; 4] = [3, 4, 3, 2],
    my_struct: MyStruct = MyStruct {
        x: 1,
        y: 2,
        state: MyEnum::Pending,
    },
}

abi EchoConfigurables {
    fn echo_configurables() -> (u8, str[4], [u8; 4], MyStruct);
}

impl EchoConfigurables for Contract {
    fn echo_configurables() -> (u8, str[4], [u8; 4], MyStruct) {
        (age, tag, grades, my_struct)
    }
}
```

In this contract, the function `echo_configurables` returns the values of the configurable constants, which we'll use for demonstrating the setting of configurables via the SDK.

## Setting New Values For Configurable Constants

During contract deployment, you can define new values for any/all of the configurable constants. The example below shows setting of one configurable constant, while the others will have default values.

```
const configurableConstants = {
  age: 10,
};

const deploy = await EchoConfigurablesFactory.deploy(wallet, {
  configurableConstants,
});
const { contract } = await deploy.waitForResult();

const {
  value: [age, tag, grades, myStruct],
} = await contract.functions.echo_configurables().get();

// age got updated
console.log('age', age); // 10
// while the rest are default values
console.log('tag', tag); // 'fuel'
console.log('grades', grades); // [3, 4, 3, 2]
console.log('myStruct', myStruct); // { x: 1, y: 2, state: 'Pending' }
```

Please note that when assigning new values for a `Struct`, all properties of the `Struct` must be defined. Failing to do so will result in an error:

```
const invalidConfigurables = {
  my_struct: {
    x: 10,
  },
};
try {
  await EchoConfigurablesFactory.deploy(wallet, {
    configurableConstants: invalidConfigurables,
  });
} catch (e) {
  console.log('error', e);
  // error: Error setting configurable constants on contract:
  // Invalid struct MyStruct. Field "y" not present.
}
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/contract-balance.md.md

# Contract Balance

When working with contracts, it's crucial to be aware of the available contract balance of an asset while paying for costly operations. This guide will explain the `getBalance` method in the [Contract](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) class, which allows you to check a contract's available balance.

## The `getBalance` Method

The [`Contract.getBalance`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html#getBalance) method retrieves the available balance of a specific asset on your contract. This method is particularly useful for determining the remaining balance after sending assets to a contract and executing contract calls.

It is important to note that this method returns the total available contract balance, regardless of how often assets have been sent to it or spent.

## Checking Contract Balance

Consider a simple contract that transfers a specified amount of a given asset to an address:

```
contract;

use std::asset::transfer;

abi TransferToAddress {
    #[payable]
    fn transfer(amount_to_transfer: u64, asset_id: AssetId, recipient: b256);
}

impl TransferToAddress for Contract {
    #[payable]
    fn transfer(amount_to_transfer: u64, asset_id: AssetId, recipient: b256) {
        let recipient_address = Address::from(recipient);

        transfer(
            Identity::Address(recipient_address),
            asset_id,
            amount_to_transfer,
        );
    }
}
```

The `transfer` function has three parameters:

1. `amount_to_transfer`: The amount that is being transferred.

2. `asset`: The address of the deployed contract token.

3. `recipient`: The address of the receiver's wallet.

The `transfer` function calls the built-in Sway function `transfer_to_address`, which does precisely what the name suggests.

Let's execute this contract and use the `getBalance` method to validate the remaining asset amount the contract has left to spend.

```
import type { AssetId } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { TransferToAddressFactory } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const { waitForResult: waitForDeploy } =
  await TransferToAddressFactory.deploy(wallet);
const { contract } = await waitForDeploy();

const amountToForward = 40;
const amountToTransfer = 10;
const baseAssetId = await provider.getBaseAssetId();

const recipient = Wallet.generate({
  provider,
});

const asset: AssetId = {
  bits: baseAssetId,
};

const { waitForResult } = await contract.functions
  .transfer(amountToTransfer, asset, recipient.address.toB256())
  .callParams({
    forward: [amountToForward, baseAssetId],
  })
  .call();

await waitForResult();

const contractBalance = await contract.getBalance(baseAssetId);
console.log(
  'contract balance reduced by amountToTransfer',
  contractBalance.toNumber() === amountToForward - amountToTransfer
);
```

In this example, we first forward an asset amount greater than the amount required for the transfer, and then we execute the contract call.

Finally, we use the `getBalance` method to confirm that the contract balance is precisely the total forwarded amount minus the transferred amount.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/custom-contract-calls.md.md

# Custom Contract Call

In certain scenarios, your use case may require more control over how contract calls are prepared and submitted.

For instance, imagine a liquidity pool contract where users can deposit a specific asset to receive some form of benefit. To enhance the experience and make it more attractive, one could use a predicate to cover the transaction fees. This way, users only need to provide the asset they wish to deposit without worrying about the fees.

There are two main ways to customize a contract call:

## Approach 1: Customize `assembleTx` Parameters

In most cases, this isn’t necessary. However, if you need precise control, you can specify the parameters passed to `assembleTx`, which is used internally to estimate and fund the transaction.

Here’s how it works:

```
// Create a new contract instance using the contract id
const liquidityPoolContract = new LiquidityPool(contractId, wallet);

// Execute the contract call manually specifying the assembleTx parameters
const { waitForResult } = await liquidityPoolContract.functions
  .deposit({ bits: wallet.address.toB256() })
  .callParams({
    forward: [1000, TestAssetId.A.value],
  })
  .assembleTxParams({
    feePayerAccount: predicate, // Using predicate as fee payer
    accountCoinQuantities: [
      {
        amount: 1000,
        assetId: TestAssetId.A.value,
        account: wallet,
        changeOutputAccount: wallet,
      },
    ],
  })
  .call();

const {
  transactionResult: { isStatusSuccess },
} = await waitForResult();
```

## Approach 2: Manually Call `assembleTx`

You can also retrieve the transaction request from the invocation scope and manually call `assembleTx` on it. Just like the approach 1 this gives you full control over how the transaction is assembled and funded.

```
// Create a new contract instance using the contract id
const liquidityPoolContract = new LiquidityPool(contractId, wallet);

// Create invocation scope to call the deposit function
const scope = liquidityPoolContract.functions
  .deposit({ bits: wallet.address.toB256() })
  .callParams({
    forward: [1000, TestAssetId.A.value],
  });

// Get the transaction request
const request = await scope.getTransactionRequest();

/**
 * Using "assembleTx" to estimate and fund the transaction.
 */
await provider.assembleTx({
  request,
  feePayerAccount: predicate, // Using predicate as fee payer
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: TestAssetId.A.value,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Use the "call" method to submit the transaction, skipping the "assembleTx" step
const response = await scope
  .fromRequest(request)
  .call({ skipAssembleTx: true });

const {
  transactionResult: { isStatusSuccess },
} = await response.waitForResult();
```

There are 2 details here that there are essential in this flow

1. `fromRequest`:
   This sets the transaction request extracted from the invocation scope. It ensures that any manual changes you’ve applied persist and are used when the transaction is executed.

1. `{ skipAssembleTx: true }` option:
   It tells the SDK to skip the automatic `assembleTx` step during the `.call()` execution, since we’ve already manually assembled and funded the transaction using `provider.assembleTx()`. Skipping this step prevents the SDK from re-estimating the transaction and ensures the custom logic remains intact, such as using a predicate as the fee payer.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/dependency-estimation.md.md

# Transaction Dependency Estimation

In [variable outputs](./variable-outputs.md), we mention that a contract call might require you to manually specify external contracts or variable outputs.

However, by default the SDK always automatically estimates these dependencies and double-checks if everything is in order whenever you invoke a contract function or attempt to send a transaction.

The SDK uses the [Provider.estimateTxDependencies](DOCS_API_URL/classes/_fuel_ts_account.Provider.html#estimateTxDependencies) method to set any missing dependencies identified during the estimation process. This requires simulating the transaction a few times in the background.

While relying on the SDK's automatic estimation is a decent default behavior, we recommend manually specifying the dependencies if they are known in advance to avoid the performance impact of the estimation process.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/deploying-contracts.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const indexUrl = `https://docs.fuel.network/docs/sway/introduction/`
  const jsonAbiUrl = `https://docs.fuel.network/docs/sway/introduction/sway_quickstart/`
</script>

# Deploying Contracts

To deploy a contract using the SDK, you can use the `ContractFactory`. This process involves collecting the contract artifacts, initializing the contract factory, and deploying the contract.

The SDK utilizes two different deployment processes, depending on the contract's size. The threshold for the contract size is dictated by the chain and can be queried:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const {
  consensusParameters: {
    contractParameters: { contractMaxSize },
  },
} = await provider.getChain();
```

It either uses a single create transaction to deploy the entire contract bytecode, or it splits the contract bytecode into multiple chunks, deploys them as blobs (on chain data accessible to the VM), and then generates a contract from the associated blob IDs. That generated contract is then deployed as a create transaction.

The `ContractFactory` offers the following methods for the different processes:

- `deploy` for deploying contacts of any size (will automatically choose the appropriate deployment process).
- `deployAsCreateTx` for deploying the entire contract bytecode in a single create transaction.
- `deployAsBlobTx` for deploying the contract in chunks as blobs, and then deploying the contract as a create transaction.

> **Note:** If the contract is deployed via blob deployments, multiple transactions will be required to deploy the contract.

## Deploying a Contract Guide

This guide will cover the process of deploying a contract using the `deploy` method, however all these methods can be used interchangeably dependent on the contract size. In the guide we use a contract factory that has been built using [Typegen](../fuels-cli/abi-typegen.md). This tool provided by the [Fuels CLI](../fuels-cli/index.md) provides a better developer experience and end to end type support for your smart contracts.

### 1. Setup

After writing a contract in Sway you can build the necessary deployment artifacts either by running `forc build` (<a :href="indexUrl" target="_blank" rel="noreferrer">read more</a> on how to work with Sway) or by using the [Fuels CLI](../fuels-cli/index.md) and running `fuels build` using your chosen package manager. We recommend using the Fuels CLI as it provides a more comprehensive usage including end to end type support.

Once you have the contract artifacts, it can be passed to the `ContractFactory` for deployment, like so:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { MyContractFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const factory = new MyContractFactory(wallet);
```

### 2. Contract Deployment

As mentioned earlier, there are two different processes for contract deployment handled by the `ContractFactory`. These can be used interchangeably, however, the `deploy` method is recommended as it will automatically choose the appropriate deployment process based on the contract size.

This call resolves as soon as the transaction to deploy the contract is submitted and returns three items: the `contractId`, a `waitForTransactionId` function and a `waitForResult` function.

```
// Deploy the contract
const { waitForResult, contractId, waitForTransactionId } =
  await factory.deploy();
// Retrieve the transactionId
const transactionId = await waitForTransactionId();
// Await it's deployment
const { contract, transactionResult } = await waitForResult();
```

The `contract` instance will be returned only after calling `waitForResult` and waiting for it to resolve. To avoid blocking the rest of your code, you can attach this promise to a hook or listener that will use the contract only after it is fully deployed. Similarly, the transaction ID is only available once the underlying transaction has been funded. To avoid blocking the code until the ID is ready, you can use the `waitForTransactionId` function to await it's retrieval.

### 3. Executing a Contract Call

Now that the contract is deployed, you can interact with it by submitting a contract call:

```
// Call the contract
const { waitForResult: waitForCallResult } = await contract.functions
  .test_function()
  .call();
// Await the result of the call
const { value } = await waitForCallResult();
```

## Deploying a Large Contract as Blobs

In the above guide we use the recommended `deploy` method. If you are working with a contract that is too large to be deployed in a single transaction, then the SDK will chunk the contract for you and submit it as blobs, to then be accessed later by a create transaction. This process is handled by the [`ContractFactory.deployAsBlobTx`](DOCS_API_URL/classes/_fuel_ts_contract.index.ContractFactory.html#deployAsBlobTx) method.

```
// Deploy the contract as blobs
const { waitForResult: waitForBlobsAndContractDeployment } =
  await factory.deployAsBlobTx({
    // setting chunk size multiplier to be 90% of the max chunk size
    chunkSizeMultiplier: 0.9,
  });

// Await its deployment
const { contract: contractFromBlobs } =
  await waitForBlobsAndContractDeployment();
```

In the above example, we also pass a `chunkSizeMultiplier` option to the deployment method. The SDK will attempt to chunk the contract to the most optimal about, however the transaction size can fluctuate and you can also be limited by request size limits against the node. By default we set a multiplier of 0.95, meaning the chunk size will be 95% of the potential maximum size, however you can adjust this to suit your needs and ensure the transaction passes. It must be set to a value between 0 and 1.

> **Note:** Deploying large contracts using blob transactions will take more time. Each transaction is dependent and has to wait for a block to be produced before it gets mined. Then a create transaction is submitted as normal. So you will need to wait longer than usual for the contract to be fully deployed and can be interacted with.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/index.md.md

# Contracts

In the Fuel Network, contracts play a crucial role in facilitating interactions between users and the decentralized applications built on top of the network. Once you've deployed a contract, you may want to perform various tasks such as:

1. Calling contract methods;
2. Configuring call and transaction parameters like gas price, byte price, and gas limit;
3. Forwarding coins and gas in your contract calls;
4. Reading and interpreting returned values and logs.

For instance, consider a Sway contract with two ABI methods called `echo_str_8(str[8])` and `echo_u8(u8)`. After deploying the contract, you can call the methods as follows:

```
const u8Value = 10;
const str8Value = 'fuel-sdk';

const res1 = await contract.functions.echo_u8(u8Value).simulate();
const res2 = await contract.functions.echo_str_8(str8Value).simulate();
```

The example above demonstrates a simple contract call using default configurations. The following sections will explore how to further configure various parameters for contract calls, allowing for more advanced interactions with your deployed contracts in the Fuel Network.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/inter-contract-calls.md.md

# Inter-Contract Calls with the SDK

This guide explains how to use the SDK to execute a contract call where one contract interacts with another contract. We will use a simple scenario involving a `SimpleToken` contract and a `TokenDepositor` contract.

## `SimpleToken` and `TokenDepositor` Contracts

In this example, we have a `SimpleToken` contract representing a basic token contract capable of holding balances for different addresses. We also have a `TokenDepositor` contract that deposits tokens into the `SimpleToken` contract.

### Contract: `SimpleToken`

Here's a simple token contract that allows holding balances:

```
contract;

use std::hash::*;
use simple_token_abi::SimpleToken;

storage {
    balances: StorageMap<b256, u64> = StorageMap {},
}

impl SimpleToken for Contract {
    #[storage(read, write)]
    fn deposit(address: b256, amount: u64) {
        let current_balance = storage.balances.get(address).try_read().unwrap_or(0);
        storage.balances.insert(address, current_balance + amount);
    }
    #[storage(read)]
    fn get_balance(address: b256) -> u64 {
        let balance = storage.balances.get(address).try_read().unwrap_or(0);
        balance
    }
}
```

### Contract: `TokenDepositor`

The `TokenDepositor` contract imports the `SimpleToken` contract and calls its `deposit` function to deposit tokens:

```
contract;

use std::auth::msg_sender;

use simple_token_abi::SimpleToken;

abi TokenDepositor {
    fn deposit_to_simple_token(contract_id: b256, amount: u64);
}

impl TokenDepositor for Contract {
    fn deposit_to_simple_token(contract_id: b256, amount: u64) {
        let simple_token_contract = abi(SimpleToken, contract_id);

        let sender = msg_sender().unwrap();

        let address: b256 = match sender {
            Identity::Address(sender_param) => sender_param.bits(),
            _ => revert(0),
        };

        simple_token_contract.deposit(address, amount);
    }
}
```

## Inter-contract calls using the SDK

Once both contracts are deployed, we can use the SDK to make the `TokenDepositor` contract to call the `SimpleToken` contract.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { SimpleTokenFactory, TokenDepositorFactory } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const { waitForResult: waitForSimpleToken } =
  await SimpleTokenFactory.deploy(wallet);

const { contract: simpleToken } = await waitForSimpleToken();

const { waitForResult: waitForTokenDepositor } =
  await TokenDepositorFactory.deploy(wallet);

const { contract: tokenDepositor } = await waitForTokenDepositor();

const amountToDeposit = 70;
const call1 = await simpleToken.functions
  .get_balance(wallet.address.toB256())
  .call();

const { value: initialBalance } = await call1.waitForResult();

const call2 = await tokenDepositor.functions
  .deposit_to_simple_token(simpleToken.id.toB256(), amountToDeposit)
  .addContracts([simpleToken])
  .call();

await call2.waitForResult();

const call3 = await simpleToken.functions
  .get_balance(wallet.address.toB256())
  .call();

const { value: finalBalance } = await call3.waitForResult();
```

Pay attention to the method `addContracts` called by the `TokenDepositor` contract. This method accepts an array of instances of deployed contracts. Without calling this method, the inter-contract call will not work.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/logs.md.md

# Working with Contract Logs

When you log a value within a contract method, you can generate a log entry that is added to the log receipt, and the variable type is recorded in the contract's ABI. The SDK enables you to parse these values into TypeScript types.

## Simple Logs

Consider the following example contract:

```
contract;

use log_simple_abi::LogSimple;

impl LogSimple for Contract {
    fn log_simple(val: str[9]) {
        log(val);
    }
}
```

To access the logged values in TypeScript, use the `logs` (typed as `Array<any>`) property from the response of a contract call.

```
const deploy = await LogSimpleFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const { waitForResult } = await contract.functions
  .log_simple('ContractA')
  .call();

const { logs } = await waitForResult();
// logs = [
//   'ContractA'
// ]
```

## Grouped Logs

We also provide a `groupedLogs` property that groups the logs by their program identifier. This is particularly useful when working with inter-contract or multi-calls.

We will use the same [`LogSimple`](#simple-logs) contract as in the previous example.

### Multi-call

We can make a multi-call to the contract

```
const deploy = await LogSimpleFactory.deploy(wallet);
const { contract: contractA } = await deploy.waitForResult();

const { waitForResult } = await contractA
  .multiCall([
    contractA.functions.log_simple('Contract1'),
    contractA.functions.log_simple('Contract2'),
  ])
  .call();

const { groupedLogs } = await waitForResult();
// groupedLogs = {
//   [contractA.id.toB256()]: ["Contract1", "Contract2"]
// }
```

### Inter-contract

Consider the following example contract:

In this example, we are making a call an inter-contract call to the [`LogSimple`](#simple-logs) contract from the previous example.

```
contract;

// Interface from the `LogSimple` contract
abi LogSimple {
    fn log_simple(val: str[9]);
}

// Interface for the contract
abi LogInterCalls {
    fn log_inter_call(contract_id: b256, simple_log_message: str[9]);
}

impl LogInterCalls for Contract {
    fn log_inter_call(contract_id: b256, simple_log_message: str[9]) {
        log("Starting inter-call");

        let logger = abi(LogSimple, contract_id);
        logger.log_simple(simple_log_message);

        log("Inter-call completed");
    }
}
```

The `log_inter_call` function makes a call to the `log_simple` function of the [`LogSimple`](#simple-logs) contract.

```
// First we make a simple contract that logs a value
const deploySimpleContract = await LogSimpleFactory.deploy(wallet);
const { contract: simpleContract } = await deploySimpleContract.waitForResult();

// Then we make an inter-contract that makes a multi-call to the simple contract
const deployInterContract = await LogInterCallsFactory.deploy(wallet);
const { contract: interContract } = await deployInterContract.waitForResult();

// We can then call the inter-contract function that makes call out to the simple contract
const { waitForResult } = await interContract.functions
  .log_inter_call(simpleContract.id.toB256(), 'ContractB')
  .call();

// We can then wait for the result and get the grouped logs
const { groupedLogs } = await waitForResult();
// groupedLogs = {
//   [simpleContract.id.toB256()]: ['ContractB'],
//   [interContract.id.toB256()]: ['Starting inter-call', 'Inter-call completed'],
// };
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/managing-deployed-contracts.md.md

# Managing Deployed Contracts

To interact with a deployed contract using the SDK without redeploying it, you only need the contract ID and its JSON ABI. This allows you to bypass the deployment setup.

## Contract ID

The `contractId` property from the [`Contract`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) class is an instance of the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class.

The [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class also provides a set of utility functions for easy manipulation and conversion between address formats along with one property; `b256Address`, which is a string encoded in [`B256`](../types/b256.md) format.

When you log the `contractId` property of an instantiated Contract using `console.log`, the output appears as follows:

```console
  Address {
    b256Address: '0xcd16d97c5c4e18ee2e8d6428447dd9c8763cb0336718b53652d049f8ec88b3ba'
  }
```

---

If you have already an instantiated and deployed contract in hands you can create another contract instance simply by using the `contractId` property and the contract JSON ABI:

```
const deployedEchoContract = new Contract(contractId, abi, wallet);

const { value: echoed10 } = await deployedEchoContract.functions
  .echo_u8(10)
  .simulate();
// value 10
```

The previous example assumes that you have a [`Contract`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) instance at hand. However, some Fuel tools and Sway use the [`B256`](../types/b256.md) type format, a hex-encoded string-like type, for contract IDs.

You might have this format instead, for example, if you have deployed your contract with `forc deploy`.

The process of instantiating a [`Contract`](DOCS_API_URL/classes/_fuel_ts_program.Contract.html) remains the same when using a contract ID of type `B256`:

```
const contract = new Contract(b256, abi, wallet);

const { value: echoed50 } = await contract.functions.echo_u8(50).simulate();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/methods.md.md

# Interacting With Contracts

There are 4 ways to interact with contracts: `get`, `dryRun`, `simulate`, `call`.

## `get`

The `get` method should be used to read data from the blockchain without using resources. It can be used with an unfunded wallet or even without a wallet at all:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Read from the blockchain
const { value } = await contract.functions.get_count().get();
// 0
```

## `dryRun`

The `dryRun` method should be used to dry-run a contract call. It does not spend resources and can be used with an unfunded wallet or even without a wallet at all:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Perform a dry-run of the transaction
const { value } = await contract.functions.increment_count(1).dryRun();
```

## `simulate`

The `simulate` method should be used to dry-run a contract call, ensuring that the wallet used has sufficient funds to cover the transaction fees, without consuming any resources.

A funded wallet it's required:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Simulate the transaction
const { value } = await contract.functions.increment_count(10).simulate();
```

## `call`

The `call` method submits a real contract call transaction to the node, resolving immediately upon submission and returning a `transactionId` along with a `waitForResult` callback to wait for transaction execution. This behavior aligns with the natural behaviour of blockchains, where transactions may take a few seconds before being recorded on the chain.

Real resources are consumed, and any operations executed by the contract function will be processed on the blockchain.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Perform the transaction
const { waitForResult } = await contract.functions.increment_count(10).call();

const { value } = await waitForResult();
```

## `isReadOnly` (utility)

If you want to figure out whether a function is read-only, you can use the `isReadOnly` method:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await CounterFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const isReadOnly = contract.functions.get_count.isReadOnly();

if (isReadOnly) {
  await contract.functions.get_count().get();
} else {
  const { waitForResult } = await contract.functions.get_count().call();
  await waitForResult();
}
```

If the function is read-only, you can use the `get` method to retrieve onchain data without spending gas.

If the function is not read-only you will have to use the `call` method to submit a transaction onchain which incurs a gas fee.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/minted-token-asset-id.md.md

# Minted Token Asset ID

The asset ID of a token on the Fuel network is determined by two factors:

- The ID of the contract that minted the token,
- A sub-identifier (Sub ID)

> Both of which are [B256](../types/b256.md) strings.

The process involves applying a SHA-256 hash algorithm to the combination of the Contract ID and the Sub ID, to derive an Asset ID - as explained [here](https://docs.fuel.network/docs/specs/identifiers/asset/#asset-id).

Consider the following simplified token contract:

```
contract;

use std::asset::{burn, mint, transfer};

abi Token {
    fn transfer_to_address(target: Address, asset_id: AssetId, coins: u64);
    fn transfer_to_contract(recipient: ContractId, asset_id: AssetId, coins: u64);
    fn mint_coins(sub_id: b256, mint_amount: u64);
    fn burn_coins(sub_id: b256, burn_amount: u64);
}

impl Token for Contract {
    // #region variable-outputs-1
    fn transfer_to_address(recipient: Address, asset_id: AssetId, amount: u64) {
        transfer(Identity::Address(recipient), asset_id, amount);
    }

    fn transfer_to_contract(target: ContractId, asset_id: AssetId, amount: u64) {
        transfer(Identity::ContractId(target), asset_id, amount);
    }
    // #endregion variable-outputs-1
    fn mint_coins(sub_id: b256, mint_amount: u64) {
        mint(sub_id, mint_amount);
    }

    fn burn_coins(sub_id: b256, burn_amount: u64) {
        burn(sub_id, burn_amount);
    }
}
```

Imagine that this contract is already deployed and we are about to mint some coins:

```
import { bn, getMintedAssetId, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { TokenFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await TokenFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Any valid B256 string can be used as a sub ID
const subID =
  '0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745';
const mintAmount = bn(1000);

const { waitForResult } = await contract.functions
  .mint_coins(subID, mintAmount)
  .call();
await waitForResult();

// Get the minted
const mintedAssetId = getMintedAssetId(contract.id.toB256(), subID);
```

## Obtaining the Asset ID

Since the asset ID depends on the contract ID, which is always dynamic (unlike the sub ID, which can be set to a fixed value), the helper `getMintedAssetId` can be used to easily obtain the asset ID for a given contract ID and sub ID.

## Create Asset Id

The SDK provides a helper named `createAssetId` which takes the contract ID and sub ID as parameters. This helper internally calls `getMintedAssetId` and returns the Sway native parameter [AssetId](DOCS_API_URL/types/_fuel_ts_address.AssetId.html), ready to be used in a Sway program invocation:

```
import type { AssetId, B256Address } from 'fuels';
import { createAssetId } from 'fuels';

const contractId: B256Address =
  '0x67eb6a384151a30e162c26d2f3e81ca2023dfa1041000210caed42ead32d63c0';
const subID: B256Address =
  '0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745';

const assetId: AssetId = createAssetId(contractId, subID);
// {
//   bits: '0x16c1cb95e999d0c74806f97643af158e821a0063a0c8ea61183bad2497b57478'
// }
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/multi-contract-calls.md.md

# Multiple Contract Calls

<!-- This section should explain making multiple contract calls -->
<!-- calls:example:start -->

You can execute multiple contract calls in a single transaction, either to the same contract or to different contracts. This can improve efficiency and reduce the overall transaction costs.

<!-- calls:example:end -->

## Same Contract Multi Calls

<!-- This section should explain how make multiple calls with the SDK -->
<!-- multicall:example:start -->

Use the `multiCall` method to call multiple functions on the same contract in a single transaction:

<!-- multicall:example:end -->

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractTx = await CounterFactory.deploy(deployer);
const { contract: counterContract } = await counterContractTx.waitForResult();

const { waitForResult } = await counterContract
  .multiCall([
    counterContract.functions.get_count(),
    counterContract.functions.increment_count(2),
    counterContract.functions.increment_count(4),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == 0
// results[1] == 2
// results[2] == 6
```

## Different Contracts Multi Calls

The `multiCall` method also allows you to execute multiple contract calls to distinct contracts within a single transaction:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory, EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractTx = await CounterFactory.deploy(deployer);
const { contract: counterContract } = await counterContractTx.waitForResult();
const echoContractTx = await EchoValuesFactory.deploy(deployer);
const { contract: echoContract } = await echoContractTx.waitForResult();

const { waitForResult } = await echoContract
  .multiCall([
    echoContract.functions.echo_u8(17),
    counterContract.functions.get_count(),
    counterContract.functions.increment_count(5),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == 17
// results[1] == BN <0>
// results[2] == BN <5>
```

You can also chain supported contract call methods, like `callParams`, for each contract call:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoValuesFactory, ReturnContextFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const echoContractTx = await EchoValuesFactory.deploy(deployer);
const { contract: echoContract } = await echoContractTx.waitForResult();
const returnContextTx = await ReturnContextFactory.deploy(deployer);
const { contract: returnContextContract } =
  await returnContextTx.waitForResult();

const { waitForResult } = await echoContract
  .multiCall([
    echoContract.functions.echo_u8(10),
    returnContextContract.functions.return_context_amount().callParams({
      forward: [100, await provider.getBaseAssetId()],
    }),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == 10
// results[1] == BN <100>
```

When using `multiCall`, the contract calls are queued and executed only after invoking one of the following methods: `.get`, `.simulate`, or `.call`.

## Using `multiCall` for Read-Only Contract Calls

When you need to read data from multiple contracts, the `multiCall` method can perform multiple [read-only](./methods.md#get) calls in a single transaction. This minimizes the number of requests sent to the network and consolidates data retrieval, making your dApp interactions more efficient.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory, EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractTx = await CounterFactory.deploy(deployer);
const { contract: counterContract } = await counterContractTx.waitForResult();
const echoContractTx = await EchoValuesFactory.deploy(deployer);
const { contract: echoContract } = await echoContractTx.waitForResult();

const { waitForResult } = await echoContract
  .multiCall([
    counterContract.functions.get_count(),
    echoContract.functions.echo_u8(10),
    echoContract.functions.echo_str('Fuel'),
  ])
  .call();

const { value: results } = await waitForResult();
// results[0] == BN <0>
// results[1] == 10
// results[2] == 'Fuel'
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/proxy-contracts.md.md

# Proxy Contracts

Automatic deployment of proxy contracts can be enabled in `Forc.toml`.

We recommend that you use [fuels deploy](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-deploy) to deploy and upgrade your contract using a proxy as it will take care of everything for you. However, if you want to deploy a proxy contract manually, you can follow the guide below.

## Manually Deploying and Upgrading by Proxy

As mentioned above, we recommend using [fuels deploy](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-deploy) to deploy and upgrade your contract because it will handle everything automatically. However, the guide below will explain this process in detail if you want to implement it yourself.

We recommend using the [SRC14 compliant owned proxy contract](https://github.com/FuelLabs/sway-standard-implementations/tree/174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb/src14/owned_proxy/contract/out/release) as the underlying proxy as that is the one we will use in this guide and the one used by [fuels deploy](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-deploy). A TypeScript implementation of this proxy is exported from the `fuels` package as `Src14OwnedProxy` and `Src14OwnedProxyFactory`.

The overall process is as follows:

1. Deploy your contract
1. Deploy the proxy contract
1. Set the target of the proxy contract to your deployed contract
1. Make calls to the contract via the proxy contract ID
1. Upgrade the contract by deploying a new version of the contract and updating the target of the proxy contract

> **Note**: When new storage slots are added to the contract, they must be initialized in the proxy contract before they can be read from. This can be done by first writing to the new storage slot in the proxy contract. Failure to do so will result in the transaction being reverted.

For example, lets imagine we want to deploy the following counter contract:

```
contract;

abi Counter {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64;

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
}

impl Counter for Contract {
    #[storage(read)]
    fn get_count() -> u64 {
        storage.counter.try_read().unwrap_or(0)
    }

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current + amount);
        storage.counter.read()
    }

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current - amount);
        storage.counter.read()
    }
}
```

Let's deploy and interact with it by proxy. First let's setup the environment and deploy the counter contract:

```
import {
  Provider,
  Wallet,
  Src14OwnedProxy,
  Src14OwnedProxyFactory,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import {
  Counter,
  CounterFactory,
  CounterV2,
  CounterV2Factory,
} from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const counterContractFactory = new CounterFactory(wallet);
const deploy = await counterContractFactory.deploy();
const { contract: counterContract } = await deploy.waitForResult();
```

Now let's deploy the [SRC14 compliant proxy contract](https://github.com/FuelLabs/sway-standard-implementations/tree/174f5ed9c79c23a6aaf5db906fe27ecdb29c22eb/src14/owned_proxy/contract/out/release) and initialize it by setting its target to the counter target ID.

```
/**
 * It is important to pass all storage slots to the proxy in order to
 * initialize the storage slots.
 */
const storageSlots = counterContractFactory.storageSlots.concat(
  Src14OwnedProxy.storageSlots
);
/**
 * These configurables are specific to our recommended SRC14 compliant
 * contract. They must be passed on deployment and then `initialize_proxy`
 * must be called to setup the proxy contract.
 */
const configurableConstants = {
  INITIAL_TARGET: { bits: counterContract.id.toB256() },
  INITIAL_OWNER: {
    Initialized: { Address: { bits: wallet.address.toB256() } },
  },
};

const proxyContractFactory = new Src14OwnedProxyFactory(wallet);
const proxyDeploy = await proxyContractFactory.deploy({
  storageSlots,
  configurableConstants,
});

const { contract: proxyContract } = await proxyDeploy.waitForResult();
const { waitForResult } = await proxyContract.functions
  .initialize_proxy()
  .call();

await waitForResult();
```

Finally, we can call our counter contract using the contract ID of the proxy.

```
/**
 * Make sure to use only the contract ID of the proxy when instantiating
 * the contract as this will remain static even with future upgrades.
 */
const proxiedContract = new Counter(proxyContract.id, wallet);

const incrementCall = await proxiedContract.functions.increment_count(1).call();
await incrementCall.waitForResult();

const { value: count } = await proxiedContract.functions.get_count().get();
```

Now let's make some changes to our initial counter contract by adding an additional storage slot to track the number of increments and a new get method that retrieves its value:

```
contract;

abi Counter {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(read)]
    fn get_increments() -> u64;

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64;

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
    increments: u64 = 0,
}

impl Counter for Contract {
    #[storage(read)]
    fn get_count() -> u64 {
        storage.counter.try_read().unwrap_or(0)
    }

    #[storage(read)]
    fn get_increments() -> u64 {
        storage.increments.try_read().unwrap_or(0)
    }

    #[storage(write, read)]
    fn increment_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current + amount);

        let current_iteration: u64 = storage.increments.try_read().unwrap_or(0);
        storage.increments.write(current_iteration + 1);

        storage.counter.read()
    }

    #[storage(write, read)]
    fn decrement_count(amount: u64) -> u64 {
        let current = storage.counter.try_read().unwrap_or(0);
        storage.counter.write(current - amount);
        storage.counter.read()
    }
}
```

We can deploy it and update the target of the proxy like so:

```
const deployV2 = await CounterV2Factory.deploy(wallet);
const { contract: contractV2 } = await deployV2.waitForResult();

const updateTargetCall = await proxyContract.functions
  .set_proxy_target({ bits: contractV2.id.toB256() })
  .call();

await updateTargetCall.waitForResult();
```

Then, we can instantiate our upgraded contract via the same proxy contract ID:

```
/**
 * Again, we are instantiating the contract with the same proxy ID
 * but using a new contract instance.
 */
const upgradedContract = new CounterV2(proxyContract.id, wallet);

const incrementCall2 = await upgradedContract.functions
  .increment_count(1)
  .call();

await incrementCall2.waitForResult();

const { value: increments } = await upgradedContract.functions
  .get_increments()
  .get();

const { value: count2 } = await upgradedContract.functions.get_count().get();
```

For more info, please check these docs:

- [Proxy Contracts](https://docs.fuel.network/docs/forc/plugins/forc_client/#proxy-contracts)
- [Sway Libs / Upgradability Library](https://docs.fuel.network/docs/sway-libs/upgradability/#upgradability-library)
- [Sway Standards / SRC-14 - Simple Upgradable Proxies](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/#src-14-simple-upgradeable-proxies)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/storage-slots.md.md

# Storage Slots

When deploying a contract, you can specify the custom storage slots that you want to use.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import {
  StorageTestContract,
  StorageTestContractFactory,
} from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploymentTx = await StorageTestContractFactory.deploy(deployer, {
  storageSlots: StorageTestContract.storageSlots,
});

await deploymentTx.waitForResult();
```

## Using plain JavaScript

In the above example, we directly imported the storage slots from a JSON file generated by the Sway compiler.

Instead of importing from a file, you can also specify the custom storage slots directly in your code:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { StorageTestContractFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploymentTx = await StorageTestContractFactory.deploy(deployer, {
  storageSlots: [
    {
      key: '02dac99c283f16bc91b74f6942db7f012699a2ad51272b15207b9cc14a70dbae',
      value: '0000000000000001000000000000000000000000000000000000000000000000',
    },
    {
      key: '6294951dcb0a9111a517be5cf4785670ff4e166fb5ab9c33b17e6881b48e964f',
      value: '0000000000000001000000000000003200000000000000000000000000000000',
    },
    {
      key: 'b48b753af346966d0d169c0b2e3234611f65d5cfdb57c7b6e7cd6ca93707bee0',
      value: '000000000000001e000000000000000000000000000000000000000000000000',
    },
    {
      key: 'de9090cb50e71c2588c773487d1da7066d0c719849a7e58dc8b6397a25c567c0',
      value: '0000000000000014000000000000000000000000000000000000000000000000',
    },
    {
      key: 'f383b0ce51358be57daa3b725fe44acdb2d880604e367199080b4379c41bb6ed',
      value: '000000000000000a000000000000000000000000000000000000000000000000',
    },
  ],
});

await deploymentTx.waitForResult();
```

## Auto-load of Storage Slots

Code generated using [Typegen](../fuels-cli/generating-types.md) automatically [load](../fuels-cli/using-generated-types.md#autoloading-of-storage-slots) Storage Slots for you.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/transferring-assets.md.md

# Transferring assets

Consider a scenario where you're interacting with a smart contract and need to transfer assets to a recipient's wallet. The `addTransfer` enables you to combine these actions into a single transaction seamlessly.

The `addTransfer` method allows you to append an asset transfer to your contract call transaction. You can use it is shown in the following example:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await EchoValuesFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const recipient = Wallet.generate({ provider });

const { waitForResult } = await contract.functions
  .echo_u64(100)
  .addTransfer({
    destination: recipient.address,
    amount: 100,
    assetId: await provider.getBaseAssetId(),
  })
  .call();

await waitForResult();
```

In the previous example, we first use a contract call to the `echo_u64` function. Following this, `addTransfer` is added to chain call to include a transfer of `100` units of the `BaseAssetId` in the transaction.

## Batch Transfer

You can add a batch of transfers into a single transaction by using `addBatchTransfer`:

```
import type { TransferParams } from 'fuels';
import { Provider, Wallet } from 'fuels';
import { ASSET_A, ASSET_B } from 'fuels/test-utils';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await EchoValuesFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const recipient1 = Wallet.generate({ provider });
const recipient2 = Wallet.generate({ provider });

const transferParams: TransferParams[] = [
  {
    destination: recipient1.address,
    amount: 100,
    assetId: await provider.getBaseAssetId(),
  },
  { destination: recipient1.address, amount: 400, assetId: ASSET_A },
  { destination: recipient2.address, amount: 300, assetId: ASSET_B },
];

const { waitForResult } = await contract.functions
  .echo_u64(100)
  .addBatchTransfer(transferParams)
  .call();

await waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/understanding-the-fuelvm-binary-file.md.md

# Understanding the FuelVM Binary File

When you compile your Sway code using the `forc build` command, it generates a bytecode file. This binary file contains the compiled code that the Fuel Virtual Machine (FuelVM) will interpret and execute.

For example, consider the following smart contract:

```
contract;

use std::b512::B512;

abi EchoValues {
    fn echo_u8(value: u8) -> u8;

    fn echo_str_8(value: str[8]) -> str[8];

    fn echo_str(value: str) -> str;

    fn echo_tuple(tuple: (u8, bool, u64)) -> (u8, bool, u64);

    fn echo_b512(input: B512) -> B512;

    fn echo_u64(value: u64) -> u64;

    fn echo_u64_array(u64_array: [u64; 2]) -> [u64; 2];
}

impl EchoValues for Contract {
    fn echo_u8(value: u8) -> u8 {
        value
    }

    fn echo_str(value: str) -> str {
        value
    }

    fn echo_str_8(value: str[8]) -> str[8] {
        value
    }

    // #region tuples-2
    fn echo_tuple(tuple: (u8, bool, u64)) -> (u8, bool, u64) {
        tuple
    }
    // #endregion tuples-2

    // #region b512-3
    fn echo_b512(input: B512) -> B512 {
        input
    }
    // #endregion b512-3
    fn echo_u64(value: u64) -> u64 {
        value
    }

    // #region arrays-2
    fn echo_u64_array(u64_array: [u64; 2]) -> [u64; 2] {
        u64_array
    }
    // #endregion arrays-2
}
```

After running `forc build`, a binary file will be generated with the following content:

```sh
$ cat out/debug/echo-values.bin
�GT]����]@`I]G�I@sH]G�I@sHr�{6�]D`J]C�%E]@`J$@Ͼ{RD�^�%
```

At first glance, the content appears unreadable. However, `forc` provides a helpful interpreter for this bytecode: the `forc parse-bytecode` command. This command takes the binary data and outputs the equivalent FuelVM assembly:

```sh
$ forc parse-bytecode out/debug/echo-values.bin
half-word   byte   op                raw           notes
        0   0      JI(4)             90 00 00 04   jump to byte 16
        1   4      NOOP              47 00 00 00
        2   8      Undefined         00 00 00 00   data section offset lo (0)
        3   12     Undefined         00 00 00 34   data section offset hi (52)
        4   16     LW(63, 12, 1)     5d fc c0 01
        5   20     ADD(63, 63, 12)   10 ff f3 00
        6   24     LW(17, 6, 73)     5d 44 60 49
        7   28     LW(16, 63, 1)     5d 43 f0 01
        8   32     EQ(16, 17, 16)    13 41 14 00
        9   36     JNZI(16, 11)      73 40 00 0b   conditionally jump to byte 44
       10   40     RVRT(0)           36 00 00 00
       11   44     LW(16, 63, 0)     5d 43 f0 00
       12   48     RET(16)           24 40 00 00
       13   52     Undefined         00 00 00 00
       14   56     Undefined         00 00 00 01
       15   60     Undefined         00 00 00 00
       16   64     XOR(20, 27, 53)   21 51 bd 4b
```

When deploying your smart contract using the SDK, the binary file plays a crucial role. It is sent to the FuelVM in a transaction, allowing the FuelVM to interpret and execute your smart contract.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/using-different-wallets.md.md

# Making Calls with Different Wallets or Providers

This guide demonstrates how to make contract calls using different wallets and providers by passing either an [`Account`](DOCS_API_URL/classes/_fuel_ts_account.Account.html) or a [`Provider`](DOCS_API_URL/classes/_fuel_ts_account.Provider.html) to the contract on instantiation.

## Changing Wallets

To change the wallet associated with a contract instance, assign a new wallet to the instance's `account` property. This allows you to make contract calls with different wallets in a concise manner:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnContextFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await ReturnContextFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

// Update the wallet
const newWallet = Wallet.generate({ provider });
contract.account = newWallet;
```

## Changing Providers

Similarly, you can assign a custom provider to a contract instance by modifying its provider property. This enables you to use a provider wrapper of your choice:

<!-- TODO: Replace with a proper snippet. We lost this snippet because this test had to be removed/changed -->

```ts
const newProvider = new Provider(NEW_URL);
deployedContract.provider = newProvider;
```

> **Note:** When connecting a different wallet to an existing contract instance, the provider used to deploy the contract takes precedence over the newly set provider. If you have two wallets connected to separate providers (each communicating with a different fuel-core instance), the provider assigned to the deploying wallet will be used for contract calls. This behavior is only relevant when multiple providers (i.e. fuel-core instances) are present and can be ignored otherwise.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/contracts/variable-outputs.md.md

# Variable Outputs

Sway includes robust functions for transferring assets to wallets and contracts.

When using these transfer functions within your Sway projects, it is important to be aware that each call will require an [Output Variable](https://docs.fuel.network/docs/specs/tx-format/output#outputvariable) within the [Outputs](https://docs.fuel.network/docs/specs/tx-format/output) of the transaction.

For instance, if a contract function calls a Sway transfer function 3 times, it will require 3 Output Variables present within the list of outputs in your transaction.

## Example: Sway functions that requires `Output Variable`

```
    fn transfer_to_address(recipient: Address, asset_id: AssetId, amount: u64) {
        transfer(Identity::Address(recipient), asset_id, amount);
    }

    fn transfer_to_contract(target: ContractId, asset_id: AssetId, amount: u64) {
        transfer(Identity::ContractId(target), asset_id, amount);
    }
```

## Adding Variable Outputs to the contract call

When your contract invokes any of these functions, or if it calls a function that leads to another contract invoking these functions, you need to add the appropriate number of Output Variables.

This can be done as shown in the following example:

```
import { Provider, Wallet, getMintedAssetId, getRandomB256 } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { TokenFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const deployer = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployContract = await TokenFactory.deploy(deployer);
const { contract } = await deployContract.waitForResult();

const subId = getRandomB256();

const call1 = await contract.functions.mint_coins(subId, 100).call();
await call1.waitForResult();

const address = { bits: Wallet.generate().address.toB256() };
const assetId = { bits: getMintedAssetId(contract.id.toB256(), subId) };

const { waitForResult } = await contract.functions
  .transfer_to_address(address, assetId, 100)
  .txParams({
    variableOutputs: 1,
  })
  .call();

await waitForResult();
```

In the TypeScript SDK, the Output Variables are automatically added to the transaction's list of outputs.

This process is done by a brute-force strategy, performing sequential dry runs until no errors are returned. This method identifies the number of Output Variables required to process the transaction.

However, this can significantly delay the transaction processing. Therefore, it is **highly recommended** to manually add the correct number of Output Variables before submitting the transaction.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/combining-utxos.md.md

# Combining UTXOs

When performing a funding operation or calling `getResourcesToSpend`, you may encounter the `INSUFFICIENT_FUNDS_OR_MAX_COINS` error if the number of coins fetched per asset exceeds the maximum limit allowed by the chain.

You may also want to do this if you want to reduce the number of inputs in your transaction, which can be useful if you are trying to reduce the size of your transaction or you are receiving the `MAX_INPUTS_EXCEEDED` error.

## Using the Account's `consolidateCoins` Method

The SDK provides a built-in method to consolidate your base asset UTXOs:

```
const baseAssetId = await provider.getBaseAssetId();

// By default, this will combine UTXOs into a single output (outputNum = 1)
const result = await wallet.consolidateCoins({
  assetId: baseAssetId,
  // Optional: 'parallel' (default) or 'sequential' execution mode
  mode: 'parallel',
  // Optional: number of output UTXOs to create (default is 1)
  outputNum: 1,
});

// Check the transaction results and any errors
console.log('Successful transactions:', result.txResponses);
console.log('Failed transactions:', result.errors);

// Verify the reduced number of UTXOs
const { coins: consolidatedCoins } = await wallet.getCoins(baseAssetId);
console.log('Consolidated Coins Length', consolidatedCoins.length);
```

### Configuration Options

The `consolidateCoins` method accepts the following parameters:

- `assetId`: The ID of the asset to consolidate

- `mode` (optional): How to submit consolidation transactions
  - `'parallel'` (default): Submit all transactions simultaneously for faster processing
  - `'sequential'`: Submit transactions one after another, waiting for each to complete
- `outputNum` (optional): Number of output UTXOs to create (default is 1)

## Max Inputs and Outputs

It's also important to note that depending on the chain configuration, you may be limited on the number of inputs and/or outputs that you can have in a transaction. These amounts can be queried via the [TxParameters](https://docs.fuel.network/docs/graphql/reference/objects/#txparameters) GraphQL query.

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const { maxInputs, maxOutputs } = (await provider.getChain())
  .consensusParameters.txParameters;
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/custom-transactions-from-contract-calls.md.md

# Custom Transactions From Contract Calls

In the previous example we demonstrated how you can instantiate a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html) to customize and build out a more complex transaction via a script. The same can be done using contracts, but this allows us to utilize functions available in the contract and access on-chain state. Allowing us to harness all of the power from an invocation scope and a transaction request.

This cookbook demonstrates how we can utilize a contract call to build out a custom transaction, allowing us to update on-chain state and transfer assets to a recipient address.

```
import { bn, buildFunctionResult, Contract, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CounterFactory } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const deploy = await CounterFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const receiverWallet = Wallet.generate({ provider });

const amountToRecipient = bn(10_000); // 0x2710
// Connect to the contract
const contractInstance = new Contract(contract.id, contract.interface, wallet);
// Create an invocation scope for the contract function you'd like to call in the transaction
const scope = contractInstance.functions.increment_count(amountToRecipient);

// Build a transaction request from the invocation scope
const request = await scope.getTransactionRequest();
// Add coin output for the recipient
request.addCoinOutput(receiverWallet.address, amountToRecipient, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: amountToRecipient,
      assetId: baseAssetId,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Submit the transaction
const response = await wallet.sendTransaction(assembledRequest);
await response.waitForResult();
// Get result of contract call
const { value } = await buildFunctionResult({
  funcScope: scope,
  isMultiCall: false,
  program: contract,
  transactionResponse: response,
});

console.log('value', value);
// <BN: 0x2710>
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/custom-transactions.md.md

# Custom Transactions

There may be scenarios where you need to build out transactions that involve multiple program types and assets; this can be done by instantiating a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html). This class allows you to a append multiple program types and assets to a single transaction.

Consider the following script that transfers multiple assets to a contract:

```
script;

use std::asset::transfer;

fn main(
    contract_address: b256,
    asset_a: AssetId,
    amount_asset_a: u64,
    asset_b: AssetId,
    amount_asset_b: u64,
) -> bool {
    let wrapped_contract = ContractId::from(contract_address);
    let contract_id = Identity::ContractId(wrapped_contract);
    transfer(contract_id, asset_a, amount_asset_a);
    transfer(contract_id, asset_b, amount_asset_b);
    true
}
```

This script can be executed by creating a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html), appending the resource and contract inputs/outputs and then sending the transaction, as follows:

```
// 1. Create a script transaction using the script binary
const request = new ScriptTransactionRequest({
  ...defaultTxParams,
  gasLimit: 3_000_000,
  script: ScriptTransferToContract.bytecode,
});

// 2. Instantiate the script main arguments
const scriptArguments = [
  contract.id.toB256(),
  { bits: ASSET_A },
  new BN(1000),
  { bits: ASSET_B },
  new BN(500),
];

// 3. Populate the script data and add the contract input and output
request
  .setData(ScriptTransferToContract.abi, scriptArguments)
  .addContractInputAndOutput(contract.id);

// 4. Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: ASSET_A,
      account: wallet,
      changeOutputAccount: wallet,
    },
    {
      amount: 500,
      assetId: ASSET_B,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// 5. Send the transaction
const tx = await wallet.sendTransaction(assembledRequest);
await tx.waitForResult();

const contractFinalBalanceAssetA = await contract.getBalance(ASSET_A);
const contractFinalBalanceAssetB = await contract.getBalance(ASSET_B);
```

## Full Example

For a full example, see below:

```
import { BN, ScriptTransactionRequest, coinQuantityfy } from 'fuels';
import { ASSET_A, ASSET_B, launchTestNode } from 'fuels/test-utils';

import { EchoValuesFactory } from '../../../typegend/contracts/EchoValuesFactory';
import { ScriptTransferToContract } from '../../../typegend/scripts/ScriptTransferToContract';

using launched = await launchTestNode({
  contractsConfigs: [{ factory: EchoValuesFactory }],
});
const {
  contracts: [contract],
  wallets: [wallet],
  provider,
} = launched;

const defaultTxParams = {
  gasLimit: 10000,
};

// #region custom-transactions-2

// 1. Create a script transaction using the script binary
const request = new ScriptTransactionRequest({
  ...defaultTxParams,
  gasLimit: 3_000_000,
  script: ScriptTransferToContract.bytecode,
});

// 2. Instantiate the script main arguments
const scriptArguments = [
  contract.id.toB256(),
  { bits: ASSET_A },
  new BN(1000),
  { bits: ASSET_B },
  new BN(500),
];

// 3. Populate the script data and add the contract input and output
request
  .setData(ScriptTransferToContract.abi, scriptArguments)
  .addContractInputAndOutput(contract.id);

// 4. Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: ASSET_A,
      account: wallet,
      changeOutputAccount: wallet,
    },
    {
      amount: 500,
      assetId: ASSET_B,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// 5. Send the transaction
const tx = await wallet.sendTransaction(assembledRequest);
await tx.waitForResult();

const contractFinalBalanceAssetA = await contract.getBalance(ASSET_A);
const contractFinalBalanceAssetB = await contract.getBalance(ASSET_B);
// #endregion custom-transactions-2
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/deposit-and-withdraw.md.md

# Deposit And Withdraw

Consider the following contract:

```
contract;

use std::{asset::{mint_to, transfer}, call_frames::msg_asset_id, context::msg_amount};
abi LiquidityPool {
    #[payable]
    fn deposit(recipient: Address);
    #[payable]
    fn withdraw(recipient: Address);
}
configurable {
    TOKEN: AssetId = AssetId::from(0x0000000000000000000000000000000000000000000000000000000000000000),
}
impl LiquidityPool for Contract {
    #[payable]
    fn deposit(recipient: Address) {
        assert(TOKEN == msg_asset_id());
        assert(0 < msg_amount());
        // Mint two times the amount.
        let amount_to_mint = msg_amount() * 2;
        // Mint some LP token based upon the amount of the base token.
        mint_to(Identity::Address(recipient), b256::zero(), amount_to_mint);
    }
    #[payable]
    fn withdraw(recipient: Address) {
        assert(0 < msg_amount());
        // Amount to withdraw.
        let amount_to_transfer = msg_amount() / 2;
        // Transfer base token to recipient.
        transfer(Identity::Address(recipient), TOKEN, amount_to_transfer);
    }
}
```

As the name implies, this contract represents a simplified version of a liquidity pool. The `deposit()` method allows you to supply an arbitrary amount of `BASE_TOKEN`. In response, it mints twice the amount of the liquidity asset to the caller's address. Similarly, the `withdraw()` method transfers half the amount of the `BASE_TOKEN` back to the caller's address.

Now, let's deposit some tokens into the liquidity pool contract. Since this requires forwarding assets to the contract, we need to pass the appropriate values to `callParams` when creating a contract call.

```
import { getMintedAssetId, Provider, Wallet, ZeroBytes32 } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { LiquidityPoolFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploy = await LiquidityPoolFactory.deploy(wallet, {
  configurableConstants: {
    TOKEN: { bits: await provider.getBaseAssetId() },
  },
});

const { contract } = await deploy.waitForResult();

const depositAmount = 100_000;
const liquidityOwner = Wallet.generate({ provider });

// the subId used to mint the new asset is a zero b256 on the contract
const subId = ZeroBytes32;
const contractId = contract.id.toB256();

const assetId = getMintedAssetId(contractId, subId);

const { waitForResult } = await contract.functions
  .deposit({ bits: liquidityOwner.address.toB256() })
  .callParams({ forward: [depositAmount, await provider.getBaseAssetId()] })
  .txParams({ variableOutputs: 1 })
  .call();

await waitForResult();

const liquidityAmount = await liquidityOwner.getBalance(assetId);
```

As a final demonstration, let's use all our liquidity asset balance to withdraw from the pool and confirm we retrieved the initial amount. For this, we get our liquidity asset balance and supply it to the `withdraw()` function via `callParams`.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { LiquidityPoolFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploy = await LiquidityPoolFactory.deploy(wallet, {
  configurableConstants: {
    TOKEN: { bits: await provider.getBaseAssetId() },
  },
});

const { contract } = await deploy.waitForResult();

const depositAmount = 100_000;
const liquidityOwner = Wallet.generate({ provider });

const { waitForResult } = await contract.functions
  .withdraw({ bits: liquidityOwner.address.toB256() })
  .callParams({ forward: [depositAmount, await provider.getBaseAssetId()] })
  .txParams({ variableOutputs: 1 })
  .call();

await waitForResult();

const baseAssetAfterWithdraw = await liquidityOwner.getBalance(
  await provider.getBaseAssetId()
);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/generate-fake-resources.md.md

# Generate Fake Resources

When working with an unfunded account, you can generate fake resources to perform a dry-run on your transactions. This is useful for testing purposes without the need for real funds.

Below is an example script that returns the value `1337`. You can use fake resources to execute a dry-run of this script and obtain the returned value.

```
script;

fn main() -> u64 {
    return 1337;
}
```

To execute a dry-run, use the `Provider.dryRun` method. Ensure you set the `utxo_validation` flag to true, as this script uses fake UTXOs:

```
import type { TransactionResultReturnDataReceipt } from 'fuels';
import {
  bn,
  Provider,
  ReceiptType,
  ScriptTransactionRequest,
  Wallet,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ReturnScript } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const baseAssetId = await provider.getBaseAssetId();

const transactionRequest = new ScriptTransactionRequest({
  gasLimit: bn(62_000),
  maxFee: bn(60_000),
  script: ReturnScript.bytecode,
});

const resources = wallet.generateFakeResources([
  {
    amount: bn(100_000),
    assetId: baseAssetId,
  },
]);

transactionRequest.addResources(resources);

const dryrunResult = await provider.dryRun(transactionRequest);

const returnReceipt = dryrunResult.receipts.find(
  (receipt) => receipt.type === ReceiptType.ReturnData
) as TransactionResultReturnDataReceipt;

const { data: returnedValue } = returnReceipt;
```

By setting `utxo_validation` to `true`, you can successfully execute the dry-run and retrieve the returned value from the script without requiring actual funds.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/graphql-integration.md.md

# GraphQL Integration

The Fuel Network provides a [GraphQL API](https://docs.fuel.network/docs/graphql/overview/) to query the blockchain. To get a better understanding of the underlying schema and other operations, you can visit the [playground](https://testnet.fuel.network/v1/playground) for an interactive deep dive.

## Operations

For its own purposes, the SDK creates custom operations based off of the API's schema and auto-generates TypeScript client code via codegen tools.
The end result of this code generation are the operations available on the [`Provider`](../provider/index.md), of which some are shown below:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// Create the provider
const provider = new Provider(LOCAL_NETWORK_URL);

const chain = await provider.operations.getChain();
const nodeInfo = await provider.operations.getNodeInfo();
```

Note that these operations primarily serve the needs of the SDK and the `Provider`'s methods which can encapsulate calls to multiple operations, parse the responses, etc.

If your querying needs exceed what the `Provider` provides, we suggest you follow this same process and write your own custom query operations, e.g.:

```gql
query getChain {
  latestBlock {
    transactions {
      id
    }
  }
}
```

### Mutations and subscriptions

For mutations and subscriptions, we strongly suggest that you communicate with the node via the `Provider` and do not write your own custom GraphQL operations because, in its methods, the `Provider` does additional processing before and after sending them to the node which might require detailed knowledge of various Fuel domain-specific topics.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/index.md.md

# Cookbook

This section covers more advanced use cases that can be satisfied by combining various features of the SDK. As such, it assumes that you have already made yourself familiar with the previous chapters of this book.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/optimized-react-example.md.md

# Optimized React Example

This example implements the strategies outlined in [Optimizing Frontend Apps](../transactions/optimizing-frontend-apps.md) and demonstrates how to improve the perceived speed of transactions in a React application.

```tsx
import { Provider, Wallet, ScriptTransactionRequest } from "fuels";
import { useEffect, useState } from "react";

import { TestContract } from "./typegend";
import contractIds from "./typegend/contract-ids.json";

function App() {
  const [request, setRequest] = useState<ScriptTransactionRequest | null>(null);

  // Initialize the provider and wallet
  const NETWORK_URL = "https://mainnet.fuel.network/v1/graphql";
  const provider = new Provider(NETWORK_URL);
  const wallet = Wallet.fromAddress("0x...", provider);

  /**
   * Here we'll prepare our transaction upfront on page load, so that
   * by the time the user interacts with your app (i.e. clicking a btn),
   * the transaction is ready to be submitted
   */
  useEffect(() => {
    const onPageLoad = async () => {
      // 1. Connect to the contract
      const contractInstance = new TestContract(
        contractIds.testContract,
        wallet,
      );

      // 2. Invoke the contract function whilst estimating and funding the
      // call, which gives us the transaction request
      const preparedRequest = await contractInstance.functions
        .increment_counter(1)
        .fundWithRequiredCoins();

      setRequest(preparedRequest);
    };

    onPageLoad();
  }, []);

  /**
   * By the time user user clicks the submit button, we only need to
   * submit the transaction to the network
   */
  const handleSubmit = async () => {
    if (!request) return;

    // 1. Submit the transaction to the network
    const response = await wallet.sendTransaction(request);

    // 2. Wait for the transaction to settle and get the result
    const result = await response.waitForResult();

    console.log("result", result);
  };

  return (
    <div>
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );
}

export default App;
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/resubmitting-failed-transactions.md.md

# Resubmitting Failed Transactions

In certain scenarios, you might need to implement a solution to resubmit failed transactions to the Fuel Network. While this approach can be effective, there are important considerations to remember.

## Submission and Processing

When submitting a transaction, you will first get a response.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const baseAssetId = await provider.getBaseAssetId();

const transferAmount = 1000;

const transactionRequest = await wallet.createTransfer(
  wallet.address,
  transferAmount,
  baseAssetId
);

const response = await wallet.sendTransaction(transactionRequest);
```

If the `sendTransaction` method resolves without an error, we know that the transaction was successfully submitted and accepted by the network. However, this does not guarantee that the transaction has been processed; it only indicates that the transaction has been accepted and placed in a queue for processing.

To determine whether the transaction has been processed, you must call `waitForResult`, which will either resolve (with the processed transaction) or reject with an error.

```
const result = await response.waitForResult();
```

In other words:

- If `sendTransaction` is rejected with an error, the transaction was not accepted by the network and is not processed.
- If `waitForResult` is rejected with an error, the transaction was accepted but reverted during processing.

## Resources Spent When a Transaction Is Processed

If a transaction is reverted during processing, the Fuel VM will still consume the funded resources to cover the gas used up to the point of failure. After deducting the gas cost, the remaining funds will be added to a new UTXO (Unspent Transaction Output) addressed to the owner.

Attempting to resubmit the same transaction request that failed during processing will likely result in an error, as the initially spent resources no longer exist.

```
const transactionRequest = await wallet.createTransfer(
  wallet.address,
  transferAmount,
  baseAssetId
);

// Set the gasLimit to 0 to force revert with OutOfGas error
transactionRequest.gasLimit = bn(0);

// Transaction will be successfully submitted
const response = await wallet.sendTransaction(transactionRequest);
// let error: FuelError | undefined;
try {
  await response.waitForResult();
} catch (error) {
  if (/OutOfGas/.test((<FuelError>error).message)) {
    transactionRequest.gasLimit = bn(1000);

    // Re-submission will fail
    await wallet.sendTransaction(transactionRequest).catch((error2) => {
      console.log('error2', error2);
    });
  }
}
```

The attempt from the above snippet will result in the error:

```console
FuelError: Transaction is not inserted. UTXO does not exist: {{utxoId}}
```

To safely retry a transaction that failed during processing, you should reassemble the request from scratch and resubmit it.

```
try {
  await response.waitForResult();
} catch (error) {
  if (/OutOfGas/.test((<FuelError>error).message)) {
    const transactionRequest2 = await wallet.createTransfer(
      wallet.address,
      transferAmount,
      baseAssetId
    );

    await wallet.sendTransaction(transactionRequest2);
  }
}
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/splitting-utxos.md.md

# Splitting UTXOs

There may be times when you want to split one large UTXO into multiple smaller UTXOs. This can be useful if you want to send multiple concurrent transactions without having to wait for them to be processed sequentially.

> **Note:** Depending on how many smaller UTXOs you want to create, you may need to fund the wallet with additional funds to cover the fees. As we see in the example below, we fund the sending wallet with 500 to cover the fees for the batch transfer.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();
// This is the wallet that will fund the sending wallet
const fundingWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// This is the wallet that will send the funds
const wallet = Wallet.generate({ provider });
// This is the wallet that will receive the funds
const destinationWallet = Wallet.generate({ provider });

// Let's fund the sending wallet with 1000 of the base asset
const fundingTx = await fundingWallet.transfer(
  wallet.address,
  1000,
  baseAssetId
);
await fundingTx.waitForResult();

// We can fetch the coins to see how many UTXOs we have and confirm it is 1
const { coins: initialCoins } = await wallet.getCoins(baseAssetId);
console.log('Initial Coins Length', initialCoins.length);
// 1

// Now we can split the large 1000 UTXO into 5 UTXOs of 200 each,
// Including the address to send the funds to and the assetId we want to send
const splitTxns = new Array(5).fill({
  amount: 200,
  assetId: baseAssetId,
  destination: destinationWallet.address,
});

// We will also need add some funds to the wallet to cover the fee
// We could have also spent less than 200 for each UTXO, but this is just an example
const fundTx = await fundingWallet.transfer(wallet.address, 500, baseAssetId);
await fundTx.waitForResult();

console.log('Split UTXOs', splitTxns);
// [
//   { amount: 200, assetId: '0x0', destination	: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' },
//   { amount: 200, assetId: '0x0', destination: '0x...' }
// ]

// Then we can send the transactions using the batchTransfer function
const batchTx = await wallet.batchTransfer(splitTxns);
await batchTx.waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/sway-script-with-signature-validation.md.md

# Sway Script With Signature Validation

This guide explains how to work with a Script that rely on in-code signature validation. This is particularly useful when you need to verify that a transaction was authorized by a specific account.

## Example Sway Script

Here's an example of a Sway script that validates signatures:

```
script;

use std::{b512::B512, ecr::ec_recover_address, tx::{tx_id, tx_witness_data}};

fn main(signer: b256, witness_index: u64) -> bool {
    let witness_data: B512 = tx_witness_data(witness_index).unwrap();
    let address: b256 = ec_recover_address(witness_data, tx_id()).unwrap().bits();
    return address == signer;
}
```

This script:

1. Takes 2 parameters; an account address and an witness index
2. Recovers the entry witness from the transaction's witnesses array using the given index
3. Validates if the signature was generated by the given account address
4. Returns `true` or `false` based on the validation result

## Understanding Signature Validation in Fuel

On Fuel, transaction signing involves using a wallet's private key to create a hash based on the transaction ID (which is the same as the [transaction hash](https://docs.fuel.network/docs/specs/identifiers/transaction-id/)). The transaction ID is generated by hashing the transaction bytes themselves.

Important considerations:

- Any modification to the transaction after signing will invalidate the signature (modification within the witnesses array do not invalidate the signature)
- This is because the transaction ID changes when the transaction is modified
- The signature is typically the last thing added to a transaction, after estimation and funding

## Special Considerations for Estimation

When working with Sway programs that have in-code signature validation, the estimation process becomes more complex because:

1. A valid signature is required during the estimation process
2. The signature must be valid for both during the transaction estimation and later when submitting the transaction
3. The transaction may be modified during the estimation and funding process, which will result in invalidating any previously added signature

## Implementation Example

Here's how to properly implement a transaction with signature validation for this specific Sway script:

```
// Instantiate the script
const script = new ScriptSigning(signer);

/**
 * Witness index in which we will add the signature, since there will only be
 * one witness in this transaction request
 */
const witnessIndex = 0;

// Creating the scope invocation to be used later
const scope = script.functions.main(signer.address.toB256(), witnessIndex);

// Creating the scope invocation to be used later
const request = await scope.getTransactionRequest();

// Signing the transaction request before estimation
let signature = await signer.signTransaction(request);

// Adding the signature to the transaction request
request.addWitness(signature);

/**
 * Uses `assembleTx` to estimate and fund the transaction request.
 * Because the transaction only requires enough to cover the fee, there's no
 * need to pass any `accountCoinQuantities` to the `assembleTx` function.
 */
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: signer,
});
// Signing the request again as the it was modified during estimation and funding
signature = await signer.signTransaction(assembledRequest);

// Updating the signature in the assembled request
assembledRequest.updateWitness(witnessIndex, signature);

// Sending the transaction request
const { waitForResult } = await scope.call({ skipAssembleTx: true });

// Getting the result of the transaction
const {
  transactionResult: { isStatusSuccess },
} = await waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/cookbook/wallet-sdk-and-react-hooks.md.md

# Wallet SDK and React Hooks

This guide will show you how you can use the [Fuel Wallet](https://wallet.fuel.network/) SDK and its [React Hooks](https://wallet.fuel.network/docs/dev/hooks-reference/) to build a simple React application that lets users connect their wallet to your application and see their balance.

## Setup

The first thing we will do is setup a Next.js project.

::: code-group

```sh [npm]
npm create next-app my-fuel-app
```

```sh [pnpm]
pnpm create next-app my-fuel-app
```

```sh [bun]
bun create next-app my-fuel-app
```

:::

Next, we will install the Fuel Wallet React SDK and the Fuel TypeScript SDK.

::: code-group

```sh [npm]
npm install fuels @fuels/connectors @fuels/react @tanstack/react-query
```

```sh [pnpm]
pnpm add fuels @fuels/connectors @fuels/react @tanstack/react-query
```

```sh [bun]
bun add fuels @fuels/connectors @fuels/react @tanstack/react-query
```

:::

## The Provider

In order to make use of the React hooks provided by the Fuel Wallet SDK, we need to wrap our application in a `FuelProvider` component. This component will provide the hooks with the necessary context to interact with the Fuel Wallet SDK. Add the following to your `pages/_app.tsx` file:

<!-- prettier-ignore -->
```
"use client";

import { defaultConnectors } from "@fuels/connectors";
import { FuelProvider } from "@fuels/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { Inter } from "next/font/google";
import React from "react";

import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

const queryClient = new QueryClient();

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <React.StrictMode>
      <html>
        <QueryClientProvider client={queryClient}>
          <FuelProvider
            fuelConfig={{ connectors: defaultConnectors({ devMode: true }) }}
          >
            <body className={inter.className}>{children}</body>
          </FuelProvider>
        </QueryClientProvider>
      </html>
    </React.StrictMode>
  );
}
```

## Building the UI

Go to your `pages/index.tsx` file and replace the contents with the following:

```
"use client";

import {
  useAccount,
  useBalance,
  useConnect,
  useConnectors,
  useDisconnect,
  useIsConnected,
} from "@fuels/react";
import { useState } from "react";

export default function Home() {
  const [connector, setConnector] = useState("");
  const { connectors } = useConnectors();
  const { connect } = useConnect();
  const { disconnect } = useDisconnect();
  const { isConnected } = useIsConnected();
  const { account } = useAccount();
  const { balance } = useBalance({
    address: account as string,
  });

  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 10,
        padding: 10,
        maxWidth: 300,
      }}
    >
      <select
        onChange={(e) => {
          setConnector(e.target.value);
        }}
      >
        <option value="">Select a connector</option>
        {connectors.map((c) => (
          <option key={c.name} value={c.name}>
            {c.name}
          </option>
        ))}
      </select>
      <button disabled={!connector} onClick={() => connect(connector)}>
        Connect to {connector}
      </button>
      <button disabled={!connector} onClick={() => disconnect()}>
        Disconnect from {connector}
      </button>
      <p>{isConnected ? "Connected" : ""}</p>
      {account && <p>Account: {account}</p>}
      {balance && <p>Balance: {balance.toString()}</p>}
    </div>
  );
}
```

Let's break down what's happening here.

The `useConnectors` hook returns a list of available wallet connectors.

Once a connector has been selected by the user, the `useConnect` hook will return a `connect` function that can be used to connect the user's wallet to your application.

The `useAccount` hook returns information about the user's account, if they are connected.

The `useBalance` hook returns the user's ETH balance on the [`testnet` network](https://testnet.fuel.network/v1/playground), if they are connected.

## Further Reading

- [Wallet SDK React Hooks Reference](https://wallet.fuel.network/docs/dev/hooks-reference/)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/deploying-a-dapp-to-testnet.md.md

# Deploying a dApp to Testnet

In this guide, we will deploy a full-stack dApp bootstrapped with `npm create fuels` to the Fuel testnet.

> Make sure you have already bootstrapped a dApp using `npm create fuels`. If you haven't, please follow [this guide](./index.md).

There are mainly two steps to get our dApp live on the testnet:

1. Deploying the Contract to the Testnet
2. Deploying the Frontend to the Cloud

## Deploying the Contract

We will be using [`forc`](https://docs.fuel.network/docs/forc/) to deploy our contracts to the testnet. `forc` is a part of the Fuel Toolchain.

> If you don't have the Fuel Toolchain installed, follow [this guide](https://docs.fuel.network/guides/installation/) to install it.

The first step is to `cd` into the directory containing your contract:

```sh
cd sway-programs/contract
```

And then, run the following command and follow the instructions to deploy the contract to the testnet:

```sh
forc deploy --testnet
```

> You can check out [this guide](https://docs.fuel.network/docs/intro/quickstart-contract/#deploy-to-testnet) for more information on deploying a contract to the testnet.

You should see a message similar to this:

```md
Contract deploy-to-testnet Deployed!

Network: https://testnet.fuel.network
Contract ID: 0x8342d413de2a678245d9ee39f020795800c7e6a4ac5ff7daae275f533dc05e08
Deployed in block 0x4ea52b6652836c499e44b7e42f7c22d1ed1f03cf90a1d94cd0113b9023dfa636
```

Copy the contract ID and save it for later use.

## Deploying the Frontend

Let's now prepare our frontend so that we can deploy it to the cloud.

Go to your `.env.local` file and add a new variable named `VITE_TESTNET_CONTRACT_ID`. Set its value to the contract ID you had copied earlier after deploying your contract.

```md
VITE_TESTNET_CONTRACT_ID=0x8342d413de2a678245d9ee39f020795800c7e6a4ac5ff7daae275f533dc05e08
```

If you are curious, this environment variable is used here in the `src/lib.tsx` file to set the contract ID:

```
export const localContractId = contractIds.testContract;
export const testnetContractId = process.env.VITE_TESTNET_CONTRACT_ID as string;
export const contractId = isLocal ? localContractId : testnetContractId;
```

You will notice that this piece of code is getting the contract ID depending on the current environment. If the environment is `local`, it will use the contract ID from the auto-generated `contract-ids.json` file. Otherwise, for a testnet deployment, it will use the contract ID provided by you.

The `CURRENT_ENVIRONMENT` variable is defined in the `lib.tsx` file:

```
export const environments = { LOCAL: 'local', TESTNET: 'testnet' };
export const environment = process.env.VITE_DAPP_ENVIRONMENT || environments.LOCAL;
export const isLocal = environment === environments.LOCAL;
export const isTestnet = environment === environments.TESTNET;
```

As you can see, it depends on the `VITE_DAPP_ENVIRONMENT` environment variable. If you go to your `.env.local` file, you will see that it is set to `local` by default. If you change this value to `testnet`, the frontend will now be connected to the testnet instead of your local node.

Go ahead and change the `VITE_DAPP_ENVIRONMENT` value to `testnet` in your `.env.local` file.
If you run your frontend now, you should be able to interact with your contract on the testnet.

To deploy your frontend to the cloud, you can use any service like [Vercel](https://vercel.com/). Make sure that you setup your environment variables correctly and that your contract ID is correct. Your environment variables should look something like this:

```md
VITE_DAPP_ENVIRONMENT=testnet
VITE_TESTNET_CONTRACT_ID=0x8342d413de2a678245d9ee39f020795800c7e6a4ac5ff7daae275f533dc05e08

(the rest of the environment variables are optional)
```

## Conclusion

Congratulations! You have successfully deployed your Fuel dApp to the testnet.

To recap, to deploy your dApp to the testnet, you need to:

1. Deploy your contract to the testnet using `forc deploy --testnet`.
2. Specify this contract ID in your frontend's environment variables. (`VITE_TESTNET_CONTRACT_ID`)
3. Set the `VITE_DAPP_ENVIRONMENT` environment variable to `testnet`.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Creating a Fuel dApp

`npm create fuels` is a command line tool that helps you scaffold a new full-stack Fuel dApp. In this guide, we will create a new counter dApp using `npm create fuels` and add decrement functionality to it. The final result will look like this:

![End result of this guide](../../public/creating-a-fuel-dapp-create-fuels-end-result.png)

You can also check it live, deployed to the Testnet:

- [https://create-fuels-template.vercel.app/](https://create-fuels-template.vercel.app/)

## Initializing the project

The first step is to run the command:

::: code-group

```sh-vue [npm]
npm create fuels@{{fuels}}
```

```sh-vue [pnpm]
pnpm create fuels@{{fuels}}
```

```sh-vue [bun]
bun create fuels@{{fuels}}
```

:::

Once you run the command, you will be asked to choose a name for your project:

```md
◇ What is the name of your project?
│ my-fuel-project
└
```

The tool will scaffold the project and install the necessary dependencies for you. You will then be greeted with this message:

```md
⚡️ Success! Created a fullstack Fuel dapp at my-fuel-project

To get started:

- cd into the project directory: cd my-fuel-project
- Start a local Fuel dev server: pnpm fuels:dev
- Run the frontend: pnpm dev

-> TS SDK docs: https://docs.fuel.network/docs/fuels-ts/
-> Sway docs: https://docs.fuel.network/docs/sway/
-> If you have any questions, check the Fuel forum: https://forum.fuel.network/
```

## Directory Structure

The project scaffolded by `npm create fuels` has roughly the following directory structure:

```md
my-fuel-project
├── src
│ ├── components
│ │ └── ...
│ ├── hooks
│ │ └── ...
│ ├── lib.tsx
│ ├── App.tsx
│ └── ...
├── sway-programs
│ ├── contract
│ │ └── ...
│ └── ...
├── public
│ └── ...
├── fuels.config.ts
├── package.json
└── ...
```

It is a Vite project with a few extra files and folders. Let's take a closer look at some of the important ones:

### `./fuels.config.ts`

This is the configuration file for the [`fuels` CLI](../fuels-cli/index.md), the CLI and tooling that powers this project under the hood. It makes sure that all of your Sway programs are continuously compiled and deployed to your local Fuel node. You can read more about the `fuels.config.ts` file in the [Fuels CLI documentation](../fuels-cli/config-file.md).

### `./sway-programs/contract/src/main.sw`

This is where our Sway contract lives. Out of the box, it is a simple counter contract that can only be incremented. We will add a decrement functionality to it in the next step.

### `./src/App.tsx`

This file contains the source code for the frontend of our dApp.

### `./src/components/Contract.tsx`

This file contains the source code for the 'Contract' tab in the UI, this is where the contract calling logic is implemented.

### Dev Environment Setup

Now that we have our project scaffolded, let's set up our development environment.

Let's first start our Fuel Dev server. This will start a local Fuel node and continuously compile and deploy our Sway programs to it.

::: code-group

```sh [npm]
npm fuels:dev
```

```sh [pnpm]
pnpm fuels:dev
```

```sh [bun]
bun run fuels:dev
```

:::

Once the server is up and running, we can start our Next.js development server in another terminal.

::: code-group

```sh [npm]
pnpm dev
```

```sh [pnpm]
pnpm dev
```

```sh [bun]
bun run dev
```

:::

You should now be able to see the dApp running at `http://localhost:5173`. Go ahead and connect a wallet to the dApp. You can choose the Burner Wallet from the list if you don't want to connect a wallet.

![Available Wallet Connectors](../../public/creating-a-fuel-dapp-wallet-list.png)

Now, you can try changing the contents of the `./sway-programs/contract/src/main.sw` file and see the changes reflected in the 'Contract' tab in the UI without having to restart the server.

![Fullstack Fuel Dev Workflow](../../public/creating-a-fuel-dapp-create-fuels-split-view.png)

**Note:** You may wish to learn more about how you could create a Fuel dApp that uses predicates, check out our [Working with Predicates](./working-with-predicates.md) guide.

## Adding Decrement Functionality

To add decrement functionality to our counter, we will have to do two things: 1. Add a `decrement_counter` function to our Sway contract, and 2. Modify the `./src/components/Contract.tsx` file to add a button that calls this function.

### 1. Modifying the Sway Contract

To add a `decrement_counter` function to our Sway contract, we will modify the `./sway-programs/contract/src/main.sw` file.

There are two steps when adding a new function to a Sway program. The first step is to specify the function's ABI.

Towards the top of the file, you will find the ABI section for the contract. Let's add a new function to it:

```
// The abi defines the blueprint for the contract.
abi Counter {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(write, read)]
    fn increment_counter(amount: u64) -> u64;

    #[storage(write, read)]
    fn decrement_counter(amount: u64) -> u64;
}
```

The second step is to implement the function.

We will add the implementation of the `decrement_counter` function right below the `increment_counter` function.

```
impl Counter for Contract {
    // The `get_count` function returns the current value of the counter.
    #[storage(read)]
    fn get_count() -> u64 {
        storage.counter.read()
    }

    // The `increment_counter` function increments the counter by the given amount.
    #[storage(write, read)]
    fn increment_counter(amount: u64) -> u64 {
        let current = storage.counter.read();
        storage.counter.write(current + amount);
        storage.counter.read()
    }

    #[storage(write, read)]
    fn decrement_counter(amount: u64) -> u64 {
        let current = storage.counter.read();
        storage.counter.write(current - amount);
        storage.counter.read()
    }
}
```

### 2. Modifying the Frontend

We will now add a new button to the frontend that will call the `decrement_counter` function when clicked. To do this, we will modify the `./src/App.tsx` file.

First, we will add a function called `decrementCounter` similar to the `incrementCounter` function:

```
  async function decrementCounter() {
    if (!wallet || !contract) return;
    setIsLoading(true);

    try {
      const call = await contract.functions.decrement_counter(1).call();
      transactionSubmitNotification(call.transactionId);
      const result = await call.waitForResult();
      transactionSuccessNotification(result.transactionId);
      setCounter(result.value.toNumber());
    } catch (error) {
      console.error(error);
      errorNotification("Error decrementing counter");
    }
    setIsLoading(false);
  }
```

Second, we will add a new button to the UI that will call the `decrementCounter` function when clicked:

<!-- TODO: our docs engine currently does not detect comments in JSX -->

```tsx
<Button onClick={onDecrementPressed} className="mt-6">
  Decrement Counter
</Button>
```

Congratulations! You should now be able to see the counter dApp running at `http://localhost:5173` with our newly added decrement functionality.

You can find the complete source code of the dApp we built [here](https://github.com/FuelLabs/fuels-ts/tree/master/apps/create-fuels-counter-guide).

![End result of this guide](../../public/creating-a-fuel-dapp-create-fuels-end-result.png)

Whenever you want to add a new feature to your dApp and quickly prototype things, you can follow the same steps we followed in this guide.

### 3. Extending the contract testing suite (Optional)

Testing our smart contract is a good practice to ensure that our implementation is working as expected. It also give assurances down the line if we decide to change the implementation of our contract.

We write our test in the `#[test]` macro within our Sway contract, these can be inline within our Sway contract or in a separate file.

For the guide, we'll add a test for our new `decrement_counter` function in the `./sway-programs/contract/src/main.sw` file:

```
#[test]
fn test_decrement_counter() {
    let contract_instance = abi(Counter, CONTRACT_ID);
    let _ = contract_instance.increment_counter(5);

    let count_before = contract_instance.get_count();
    let count_after = contract_instance.decrement_counter(1);
    assert(count_after == count_before - 1);
}
```

After writing our test, we can run either using `forc test` or via PNPM using `pnpm test:forc`.

### 4. Extending the integration test suite (Optional)

Testing the integration with your smart contract isn't essential, but it's good practice to ensure that your application is working as expected. It also gives you the ability to test your application in a controlled environment against a local node.

We've provided some examples for each program type in the `./test` directory of your project. But let's also add a test for our new `decrement_counter` function in the `./test/contract.test.ts` file:

```
import { Wallet, Provider } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CounterFactory } from '../../../typegend/contracts';

// Let's create our provider from the network URL.
const provider = new Provider(LOCAL_NETWORK_URL);
// Let's create our wallet from the private key.
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Then we can deploy the contract.
const { waitForResult } = await CounterFactory.deploy(wallet);
const { contract } = await waitForResult();

// Lets setup some values to use in our example.
const initialCount = 0;
const incrementedValue = 5;
const decrementedValue = 2;

// We can now call the contract functions and test the results. Lets assert the initial value of the counter.
const { waitForResult: getCountWaitForResult } = await contract.functions
  .get_count()
  .call();
const { value: initialGetCountValue } = await getCountWaitForResult();

console.log('Initial value', initialGetCountValue);

// Next we'll increment the counter, so that we can decrement it.
const { waitForResult: incWaitForResult } = await contract.functions
  .increment_count(5)
  .call();
const { value: incValue } = await incWaitForResult();

console.log('Incremented value', incValue);

// Next, we'll decrement the counter by 3 and assert the new value.
const { waitForResult: decWaitForResult } = await contract.functions
  .decrement_count(3)
  .call();
const { value: decValue } = await decWaitForResult();

console.log('Decremented value', decValue);

// Finally, we'll test the get count function again to ensure parity.
const { waitForResult: finalWaitForResult } = await contract.functions
  .get_count()
  .call();
const { value: finalValue } = await finalWaitForResult();

console.log('Final value', finalValue);
```

The template also comes with a UI testing setup using [Playwright](https://playwright.dev/). We can add a test for our new `decrement_counter` function in the `./test/ui/ui.test.ts` file:

```
test('counter contract - decrement function call works properly', async ({ page }) => {
  await setup({ page });

  const topUpWalletButton = page.getByText('Transfer 5 ETH', { exact: true });
  await topUpWalletButton.click();

  await page.waitForTimeout(2000); // These timeouts are needed to ensure that we wait for transactions to be mined

  const contractTab = page.getByText('Contract');
  await contractTab.click();

  const initialCounterValue = +page.getByTestId('counter').textContent;

  const decrementButton = page.getByText('Decrement', { exact: true });
  await decrementButton.click();

  const counterValueAfterDecrement = +page.getByTestId('counter').textContent;
  expect(counterValueAfterDecrement).toEqual(initialCounterValue - 1);
});
```

## Next Steps

- Now that you have a basic counter dApp running and have the `npm create fuels` workflow powering you, you can start building more complex dApps using the Fuel Stack. A good place to start for ideas and reference code is the [Sway Applications Repo](https://github.com/FuelLabs/sway-applications).

- As you may have noticed, there are different types of programs in your dApp, feel free to explore [Predicates](https://docs.fuel.network/docs/fuels-ts/predicates/) and [Scripts](https://docs.fuel.network/docs/fuels-ts/scripts/), which are both important differentiators in the Fuel Stack.

- If you want to deploy your dApp to the testnet, check out our [Deploying a dApp to Testnet](./deploying-a-dapp-to-testnet.md) guide.

- If you want to further validate the functionality of your dApp and program types, check out the `test` directory in your `create fuels` project. Couple this with our [testing guide](https://docs.fuel.network/docs/fuels-ts/testing/) to get a better understanding of how to test your dApp.

- If you have any questions or need help, feel free to reach out to us on the [Official Fuel Forum](https://forum.fuel.network/).

- If you want to learn more about the Fuel Stack, check out the [Fuel Docs](https://docs.fuel.network/).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/options.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Options

The `npm create fuels` command has several command-line options that you can use to customize your project.

::: code-group

```sh-vue [pnpm]
pnpm create fuels@{{fuels}} [project-name] [options]
```

```sh-vue [npm]
npm create fuels@{{fuels}} -- [project-name] [options]
```

```sh-vue [bun]
bun create fuels@{{fuels}} [project-name] [options]
```

:::

## `--template <template-name>`

Specifies the template to use for your project. The available templates are: `vite` and `nextjs`. The default template is `vite`.

## `--verbose`

Enables verbose logging. Useful when debugging issues with the tool.

## `-h, --help`

Displays a help message with all available options.

## `-V, --version`

Displays the version number of the `npm create fuels` command.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/creating-a-fuel-dapp/working-with-predicates.md.md

# Working with Predicates

This guide builds on the [Creating a Fuel dApp](./index.md) guide. Once you've gotten the dApp there up and running, then you can continue here via clicking the Predicate Example link. We will modify the predicate we created in the previous guide. The final result will look like this:

![End result of this guide](../../public/working-with-predicates-end-result.png)

You can also check it live, deployed to the Testnet:

- [https://create-fuels-template.vercel.app/](https://create-fuels-template.vercel.app/)

## Adding a Configurable pin

The current predicate functionality we have is a simple one that checks if the user has a pin. We will modify this predicate to accept a configurable pin. This will allow the user to set their own pin.

1. Modifying the Predicate Contract

The first step is to modify the predicate contract to accept a configurable pin. We will use the [`configurable`](https://docs.fuel.network/guides/intro-to-predicates/configurables/#configurables) keyword to create an updatable constant to store the pin. We will also modify the main function to check this constant instead of a hardcoded pin.

```
predicate;

configurable {
    PIN: u64 = 1337,
}

fn main(pin: u64) -> bool {
    return PIN == pin;
}
```

2. Modifying the Frontend

We will now add new button to the frontend that will update the `pin` in the predicate when clicked. To do this, we will modify the `./src/components/Predicate.tsx` file.

We will add a function called `changePin`, which will use the current pin in state to update the pin in the predicate as well as transfer 1000 to the predicate.

```
  const changePin = async () => {
    if (!wallet || !predicate) return;
    setIsLoading(true);

    try {
      const configurableConstants = { PIN: bn(predicatePin) };
      const newPredicate = new TestPredicate({
        provider: wallet.provider,
        data: [configurableConstants.PIN],
        configurableConstants,
      });

      const tx = await wallet.transfer(newPredicate.address, bn(2_000_000));
      transactionSubmitNotification(tx.id);
      await tx.waitForResult();
      transactionSuccessNotification(tx.id);
    } catch (error) {
      console.error(error);
      errorNotification(
        "Error changing pin.",
      );
    }
    setIsLoading(false);
    refetch();
  };
```

It would also be useful to change the placeholder text.

```tsx
<input
  type="text"
  value={predicatePin}
  onChange={(e) => setPredicatePin(e.target.value)}
  className="w-1/2 bg-gray-800 rounded-md px-2 py-1 mr-3 truncate font-mono"
  placeholder="Enter current or new pin"
/>
```

Finally, we will add a button that calls the `changePin` function when clicked.

```tsx
<Button onClick={changePin} className="w-full" disabled={isLoading}>
  Change Pin
</Button>
```

Congratulations! That's all. You should now be able to see the modified predicate dApp running at `http://localhost:5173` with our newly added change pin functionality.

You can find the complete source code of the dApp we built [here](https://github.com/FuelLabs/fuels-ts/tree/master/apps/create-fuels-counter-guide).

## Next Steps

- Now that you have a predicate dApp running and have the `npm create fuels` workflow powering you, you can start building more complex dApps using the Fuel Stack. A good place to start for ideas and reference code is the [Sway Applications Repo](https://github.com/FuelLabs/sway-applications).

- If you have any questions or need help, feel free to reach out to us on the [Official Fuel Forum](https://forum.fuel.network/).

- If you want to learn more about the Fuel Stack, check out the [Fuel Docs](https://docs.fuel.network/).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/encoding/encode-and-decode.md.md

# Encode and Decode

To interact with the FuelVM, types must be encoded and decoded per the [argument encoding specification](https://docs.fuel.network/docs/specs/abi/argument-encoding/). The SDK provides the `Interface` class to encode and decode data.

The relevant methods of `Interface` are:

- `encodeType`
- `decodeType`

The `Interface` class requires you to pass the [ABI](https://docs.fuel.network/docs/specs/abi/json-abi-format/) on initialization. Both methods accept a `concreteTypeId`, which must exist in the ABI's `concreteTypes` array. After that, a suitable coder will be assigned to encode/decode that type.

Imagine we are working with the following script that returns the sum of two `u32` integers:

```
script;

configurable {
    AMOUNT: u32 = 10,
}

fn main(inputted_amount: u32) -> u32 {
    inputted_amount + AMOUNT
}
```

When you build this script, using:

```sh
forc build
```

It will produce the following ABI:

```
{
  "programType": "script",
  "specVersion": "1",
  "encodingVersion": "1",
  "concreteTypes": [
    {
      "type": "u32",
      "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
    },
  ],
  "metadataTypes": [],
  "functions": [
    {
      "inputs": [
        {
          "name": "inputted_amount",
          "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
        },
      ],
      "name": "main",
      "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
      "attributes": null,
    },
  ],
  "loggedTypes": [],
  "messagesTypes": [],
  "configurables": [
    {
      "name": "AMOUNT",
      "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc",
      "offset": 968,
    },
  ],
}
```

Now, let's prepare some data to pass to the `main` function to retrieve the combined integer. The function expects and returns a `u32` integer. So here, we will encode the `u32` to pass it to the function and receive the same `u32` back, as bytes, that we'll use for decoding. We can do both of these with the `Interface`.

First, let's prepare the transaction:

```
import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ScriptSum } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// First we need to build out the transaction via the script that we want to encode.
// For that we'll need the ABI and the bytecode of the script
const abi: JsonAbi = ScriptSum.abi;
const bytecode = ScriptSum.bytecode;

// Create the invocation scope for the script call, passing the initial
// value for the configurable constant
const script = new Script(bytecode, abi, wallet);
const initialValue = 10;
script.setConfigurableConstants({ AMOUNT: initialValue });
const invocationScope = script.functions.main(0);

// Create the transaction request, this can be picked off the invocation
// scope so the script bytecode is preset on the transaction
const request = await invocationScope.getTransactionRequest();
```

Now, we can encode the script data to use in the transaction:

```
// Now we can encode the argument we want to pass to the function. The argument is required
// as a function parameter for all abi functions and we can extract it from the ABI itself
const argument = abi.functions
  .find((f) => f.name === 'main')
  ?.inputs.find((i) => i.name === 'inputted_amount')?.concreteTypeId as string;

// The `Interface` class (imported from `fuels`) is the entry point for encoding and decoding all things abi-related.
// We will use its `encodeType` method and create the encoding required for
// a u32 which takes 4 bytes up of property space.

const abiInterface = new Interface(abi);
const argumentToAdd = 10;
const encodedArguments = abiInterface.encodeType(argument, [argumentToAdd]);
// Therefore the value of 10 will be encoded to:
// Uint8Array([0, 0, 0, 10]

// The encoded value can now be set on the transaction via the script data property
request.scriptData = encodedArguments;

// Now we can use 'assembleTx' to estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: '0', // Using 0 as the only amount required will be the fee
      assetId: await provider.getBaseAssetId(),
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Finally, submit the built transaction
const response = await wallet.sendTransaction(request);
await response.waitForResult();
```

Finally, we can decode the result:

```
// Get result of the transaction, including the contract call result. For this we'll need
// the previously created invocation scope, the transaction response and the script
const invocationResult = await buildFunctionResult({
  funcScope: invocationScope,
  isMultiCall: false,
  program: script,
  transactionResponse: response,
});

// The decoded value can be destructured from the `FunctionInvocationResult`
const { value } = invocationResult;

// Or we can decode the returned bytes ourselves, by retrieving the return data
// receipt that contains the returned bytes. We can get this by filtering on
// the returned receipt types
const returnDataReceipt = invocationResult.transactionResult.receipts.find(
  (r) => r.type === ReceiptType.ReturnData
) as TransactionResultReturnDataReceipt;

// The data is in hex format so it makes sense to use arrayify so that the data
// is more human readable
const returnData = arrayify(returnDataReceipt.data);
// returnData = new Uint8Array([0, 0, 0, 20]

// And now we can decode the returned bytes in a similar fashion to how they were
// encoded, via the `Interface`
const [decodedReturnData] = abiInterface.decodeType(argument, returnData);
// 20

const totalValue = argumentToAdd + initialValue;
```

A similar approach can be taken with [Predicates](../predicates/index.md); however, you must set the encoded values to the `predicateData` property.

[Contracts](../contracts/index.md) require more care. Although you can utilize the `scriptData` property, the arguments must be encoded as part of the [contract call script](https://docs.fuel.network/docs/sway/sway-program-types/smart_contracts/#calling-a-smart-contract-from-a-script). Therefore, it is recommended to use a `FunctionInvocationScope` when working with contracts which will be instantiated for you when [submitting a contract function](../contracts/methods.md), and therefore handles all the encoding.

## Full Example

Here is the full example of the encoding and decoding methods:

```
import type { JsonAbi, TransactionResultReturnDataReceipt } from 'fuels';
import {
  buildFunctionResult,
  ReceiptType,
  arrayify,
  Script,
  Interface,
  Provider,
  Wallet,
} from 'fuels';

// #region encode-and-decode-3
import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ScriptSum } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// First we need to build out the transaction via the script that we want to encode.
// For that we'll need the ABI and the bytecode of the script
const abi: JsonAbi = ScriptSum.abi;
const bytecode = ScriptSum.bytecode;

// Create the invocation scope for the script call, passing the initial
// value for the configurable constant
const script = new Script(bytecode, abi, wallet);
const initialValue = 10;
script.setConfigurableConstants({ AMOUNT: initialValue });
const invocationScope = script.functions.main(0);

// Create the transaction request, this can be picked off the invocation
// scope so the script bytecode is preset on the transaction
const request = await invocationScope.getTransactionRequest();
// #endregion encode-and-decode-3

// #region encode-and-decode-4

// Now we can encode the argument we want to pass to the function. The argument is required
// as a function parameter for all abi functions and we can extract it from the ABI itself
const argument = abi.functions
  .find((f) => f.name === 'main')
  ?.inputs.find((i) => i.name === 'inputted_amount')?.concreteTypeId as string;

// The `Interface` class (imported from `fuels`) is the entry point for encoding and decoding all things abi-related.
// We will use its `encodeType` method and create the encoding required for
// a u32 which takes 4 bytes up of property space.

const abiInterface = new Interface(abi);
const argumentToAdd = 10;
const encodedArguments = abiInterface.encodeType(argument, [argumentToAdd]);
// Therefore the value of 10 will be encoded to:
// Uint8Array([0, 0, 0, 10]

// The encoded value can now be set on the transaction via the script data property
request.scriptData = encodedArguments;

// Now we can use 'assembleTx' to estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: '0', // Using 0 as the only amount required will be the fee
      assetId: await provider.getBaseAssetId(),
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Finally, submit the built transaction
const response = await wallet.sendTransaction(request);
await response.waitForResult();
// #endregion encode-and-decode-4

// #region encode-and-decode-5

// Get result of the transaction, including the contract call result. For this we'll need
// the previously created invocation scope, the transaction response and the script
const invocationResult = await buildFunctionResult({
  funcScope: invocationScope,
  isMultiCall: false,
  program: script,
  transactionResponse: response,
});

// The decoded value can be destructured from the `FunctionInvocationResult`
const { value } = invocationResult;

// Or we can decode the returned bytes ourselves, by retrieving the return data
// receipt that contains the returned bytes. We can get this by filtering on
// the returned receipt types
const returnDataReceipt = invocationResult.transactionResult.receipts.find(
  (r) => r.type === ReceiptType.ReturnData
) as TransactionResultReturnDataReceipt;

// The data is in hex format so it makes sense to use arrayify so that the data
// is more human readable
const returnData = arrayify(returnDataReceipt.data);
// returnData = new Uint8Array([0, 0, 0, 20]

// And now we can decode the returned bytes in a similar fashion to how they were
// encoded, via the `Interface`
const [decodedReturnData] = abiInterface.decodeType(argument, returnData);
// 20

const totalValue = argumentToAdd + initialValue;
// #endregion encode-and-decode-5
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/encoding/index.md.md

# Encoding

Encoding is the process of serializing data into a format that is suitable for transmission or storage. This is important for blockchains as it enables state minimization and efficiency, as well as for generating proofs.

Fortunately, if you are working with [program types](https://docs.fuel.network/docs/sway/sway-program-types/) on the Fuel network such as [calling contracts](https://docs.fuel.network/docs/fuels-ts/contracts/), the SDK will handle encoding for you automatically. It will adhere to the [argument encoding specification](https://docs.fuel.network/docs/specs/abi/argument-encoding/), so you can work with data in its expected format rather than as bytecode.

However, there may be scenarios where you want to manipulate call or return data yourself or even implement your own serialization specification. This guide will cover how to encode and decode data using the SDK.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/encoding/working-with-bytes.md.md

# Working with Bytes

This guide aims to give a high-level overview of how to work with bytes in the SDK and the structures we expect them to take. For a complete overview of ABI Encoding generally, within the Fuel network, we recommend you see the [ABI Encoding documentation](https://docs.fuel.network/docs/specs/abi/).

## Core Types

We know the sizes of all core types at compile time. They are the building blocks of the more complex types and are the most common types you will encounter.

### Unsigned Integer (`u8` / `u16` / `u32` / `u64` / `u128` / `u256`)

Each type will only contain the number of bits specified in the name. For example, a `u8` will contain 8 bits, and a `u256` will contain 256 bits and take up the exact property space with no additional padding.

```
const u8Coder = new NumberCoder('u8');
const encodedU8 = u8Coder.encode(255);

const u16Coder = new NumberCoder('u16');
const encodedU16 = u16Coder.encode(255);

const u32Coder = new NumberCoder('u32');
const encodedU32 = u32Coder.encode(255);

const u64Coder = new BigNumberCoder('u64');
const encodedU64 = u64Coder.encode(255);

const u256Coder = new BigNumberCoder('u256');
const encodedU256 = u256Coder.encode(255);
```

### Boolean

A boolean is encoded as a single byte like a `u8`, its value being either `0` or `1`.

```
const booleanCoder = new BooleanCoder();
const encodedTrue = booleanCoder.encode(true);

const encodedFalse = booleanCoder.encode(false);
```

### Fixed Length String

A fixed-length string's size is known at compile time due to the argument declaration of `str[n]` with `n` denoting its length. Each character in the string is encoded as a `utf-8` bit.

```
const stringCoder = new StringCoder(5);
const encoded = stringCoder.encode('hello');
```

### `B256` / `B512`

These are fixed-length byte arrays, with `B256` containing 256 bits and `B512` containing 512 bits. You can use them for address and signature formats.

```
const b256Coder = new B256Coder();
const encodedB256 = b256Coder.encode(hexlify(randomBytes(32)));
const b512Coder = new B512Coder();
const encodedB512 = b512Coder.encode(hexlify(randomBytes(64)));
```

## Automatically Encoded Types

These are the types that will contain nested types and no additional encoding is required other than the encoding of the nested types. This is relevant to `array`s, `tuple`s, and `struct`s and `enum`s. The only caveat here, is an `enum` will also contain a `u64` representing the `enum` case value. `option`s are encoded in the same way as `enum`s.

```
const tupleCoder = new TupleCoder([
  new NumberCoder('u8'),
  new NumberCoder('u16'),
]);
const encodedTuple = tupleCoder.encode([255, 255]);

const structCoder = new StructCoder('struct', {
  a: new NumberCoder('u8'),
  b: new NumberCoder('u16'),
});
const encodedStruct = structCoder.encode({ a: 255, b: 255 });

const arrayCoder = new ArrayCoder(new NumberCoder('u8'), 4);
const encodedArray = arrayCoder.encode([255, 0, 255, 0]);

const enumCoder = new EnumCoder('enum', { a: new NumberCoder('u32') });
const encodedEnum = enumCoder.encode({ a: 255 });
```

## Heap types

Heap types are types with a dynamic length that we do not know at compile time. These are `Vec`, `String`, and `raw_slice`. These types are encoded with a `u64` representing the length of the data, followed by the data itself.

```
const vecCoder = new VecCoder(new NumberCoder('u8'));
const encodedVec = vecCoder.encode([255, 0, 255]);

const stdStringCoder = new StdStringCoder();
const encodedStdString = stdStringCoder.encode('hello');

const rawSliceCoder = new RawSliceCoder();
const encodedRawSlice = rawSliceCoder.encode([1, 2, 3, 4]);
```

## Full Example

Here is the full example of the working with bytes functions:

```
import { randomBytes } from 'crypto';
import {
  ArrayCoder,
  B256Coder,
  B512Coder,
  BigNumberCoder,
  BooleanCoder,
  EnumCoder,
  NumberCoder,
  RawSliceCoder,
  StdStringCoder,
  StringCoder,
  StructCoder,
  TupleCoder,
  VecCoder,
  hexlify,
} from 'fuels';

// #region working-with-bytes-1
const u8Coder = new NumberCoder('u8');
const encodedU8 = u8Coder.encode(255);

const u16Coder = new NumberCoder('u16');
const encodedU16 = u16Coder.encode(255);

const u32Coder = new NumberCoder('u32');
const encodedU32 = u32Coder.encode(255);

const u64Coder = new BigNumberCoder('u64');
const encodedU64 = u64Coder.encode(255);

const u256Coder = new BigNumberCoder('u256');
const encodedU256 = u256Coder.encode(255);
// #endregion working-with-bytes-1

// #region working-with-bytes-2
const booleanCoder = new BooleanCoder();
const encodedTrue = booleanCoder.encode(true);

const encodedFalse = booleanCoder.encode(false);

// #endregion working-with-bytes-2

// #region working-with-bytes-3
const stringCoder = new StringCoder(5);
const encoded = stringCoder.encode('hello');
// #endregion working-with-bytes-3

// #region working-with-bytes-4
const b256Coder = new B256Coder();
const encodedB256 = b256Coder.encode(hexlify(randomBytes(32)));
const b512Coder = new B512Coder();
const encodedB512 = b512Coder.encode(hexlify(randomBytes(64)));
// #endregion working-with-bytes-4

// #region working-with-bytes-5
const tupleCoder = new TupleCoder([
  new NumberCoder('u8'),
  new NumberCoder('u16'),
]);
const encodedTuple = tupleCoder.encode([255, 255]);

const structCoder = new StructCoder('struct', {
  a: new NumberCoder('u8'),
  b: new NumberCoder('u16'),
});
const encodedStruct = structCoder.encode({ a: 255, b: 255 });

const arrayCoder = new ArrayCoder(new NumberCoder('u8'), 4);
const encodedArray = arrayCoder.encode([255, 0, 255, 0]);

const enumCoder = new EnumCoder('enum', { a: new NumberCoder('u32') });
const encodedEnum = enumCoder.encode({ a: 255 });
// #endregion working-with-bytes-5

// #region working-with-bytes-6
const vecCoder = new VecCoder(new NumberCoder('u8'));
const encodedVec = vecCoder.encode([255, 0, 255]);

const stdStringCoder = new StdStringCoder();
const encodedStdString = stdStringCoder.encode('hello');

const rawSliceCoder = new RawSliceCoder();
const encodedRawSlice = rawSliceCoder.encode([1, 2, 3, 4]);
// #endregion working-with-bytes-6
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/errors/index.md.md

# Errors

All errors thrown from the SDK are instances of the `FuelError` class which will have an accompanying `ErrorCode`.

## Error Codes

Here is a list of the expected error codes the SDK can throw. These error codes are used to help understand the error that has been thrown with potential resolutions.

### `ABI_MAIN_METHOD_MISSING`

When your ABI does not have a `main` method.

This can be resolved by adding a `main` method to your ABI. This is prevalent in scripts and predicates that must contain a `main` method.

### `ABI_TYPES_AND_VALUES_MISMATCH`

When the arguments supplied to the function do not match the minimum required input length.

Check that the arguments supplied to the function match the required type.

### `ACCOUNT_REQUIRED`

When an [`Account`](DOCS_API_URL/classes/_fuel_ts_account.Account.html) is required for an operation. This will usually be in the form of a [`Wallet`](../wallets/index.md).

It could be caused during the deployments of contracts when an account is required to sign the transaction. This can be resolved by following the deployment guide [here](../contracts/deploying-contracts.md).

### `ASSET_BURN_DETECTED`

When you are trying to send a transaction that will result in an asset burn.

Add relevant coin change outputs to the transaction, or enable asset burn in the transaction request.

### `CONFIG_FILE_NOT_FOUND`

When a configuration file is not found. This could either be a `fuels.config.[ts,js,mjs,cjs]` file or a TOML file.

Ensure that the configuration file is present in the root directory of your project.

### `CONFIG_FILE_ALREADY_EXISTS`

When a configuration file already exists in the root directory of your project.

You can not run `fuels init` more than once for a given project. Either remove the existing configuration file or update it.

### `CONVERTING_FAILED`

When converting a big number into an incompatible format.

Ensure that the value you've supplied to the big number is compatible with the value you are converting to.

### `CONTRACT_SIZE_EXCEEDS_LIMIT`

When the contract size exceeds the maximum contract size limit.

Ensure that the contract size is less than the maximum contract size limit, of 100 KB. This can be validated by checking the bytecode length of the contract.

### `DUPLICATED_POLICY`

When there are more than policies with the same type, for a transaction.

Ensure that there are no duplicate (by type) policies for a transaction.

### `ERROR_BUILDING_BLOCK_EXPLORER_URL`

When more than one of the following options is passed: `path`, `address`, `txId`, `blockNumber`.

Check that only one of the above is passed.

### `FUNCTION_NOT_FOUND`

When the function with the given name, signature or selector is not found in the ABI.

Check that the function name, signature or selector is correct and exits on the ABI.

### `FUNDS_TOO_LOW`

When the funds in the account are lower than the required amount.

Ensure that the account has enough funds to cover the transaction.

### `GAS_LIMIT_TOO_LOW`

When the gas limit is lower than the minimum gas limit.

Increase the gas limit to be greater than the minimum gas limit.

### `GAS_PRICE_TOO_LOW`

When the gas price is lower than the minimum gas price.

Increase the gas price to be greater than the minimum gas price.

### `HD_WALLET_ERROR`

A hardware wallet will throw for unsupported configurations.

The error message will determine which element of the configuration is incorrect. It could be due to the public or private key or when configuring to/from an extended key.

### `INVALID_CHECKSUM`

Checksum validation failed for the provided mnemonic.

Ensure that the mnemonic is correct.

### `INVALID_CHUNK_SIZE_MULTIPLIER`

When the chunk size multiplier is not between 0 and 1.

Ensure that the chunk size multiplier is a number that it is between 0 and 1.

### `INVALID_CONFIGURABLE_CONSTANTS`

When the program type either: does _not_ have configurable constants to be set; or the provided configurable constant does not belong to the program type, as defined by its ABI.

Ensure the configurable constants provided are correct and are defined in ABI.

### `INVALID_COMPONENT`

When an expected component is not found in the ABI or is malformed.

Ensure that you have correctly formed Sway types for [Arrays](../types/arrays.md) and [Vectors](../types/vectors.md).

### `INVALID_CREDENTIALS`

When the password provided is incorrect.

Ensure that the password is correct.

### `INVALID_DATA`

When the value being passed is not considered valid, as defined by the function.

Check the function signature and ensure that the passed value is valid.

### `INVALID_ENTROPY`

When the entropy is not: between 16 and 32 bytes; a multiple of 4.

Ensure that the entropy is between 16 and 32 bytes and a multiple of 4.

### `INVALID_EVM_ADDRESS`

When the provided EVM address is invalid.

Ensure that the [EVM address](../types/evm-address.md) is valid.

### `INVALID_INPUT_PARAMETERS`

When the provided input parameters are _not_ valid.

The error message will determine which parameter is missing. It could be that the provided program type is not one of the following `contract`, `script`, or `predicate`.

### `INVALID_MNEMONIC`

When the supplied mnemonic is invalid.

Check the message for more details. It could be that the mnemonic phrase word length is _not_ one of the following: 12, 15, 18, 21, or 24 lengths.

### `INVALID_PASSWORD`

When the provided password is incorrect.

Ensure that the password is correct.

### `INVALID_POLICY_TYPE`

When the supplied policy type is invalid for the given Script.

Check the policy type is defined in `PolicyType`.

### `INVALID_PROVIDER`

When unable to connect to the `Provider` or `Network` supplied to a method on the [`Fuel`](../wallets/connectors.md) class.

Check that the `Provider` or `Network` is supplied correctly.

### `INVALID_PUBLIC_KEY`

When the provided public key is invalid.

Ensure that the public key is valid.

### `INVALID_RECEIPT_TYPE`

When the receipt type is invalid.

Check the type is within `ReceiptType`.

### `INVALID_REQUEST`

When the request to the Fuel node fails, error messages are propagated from the Fuel node.

Check the error message from the Fuel node.

### `INVALID_SEED`

When the seed length is not between 16 and 64 bytes.

Ensure that the seed length is between 16 and 64 bytes.

### `INVALID_TRANSACTION_INPUT`

When the input type is invalid.

Check the type is within `InputType`.

### `INVALID_TRANSACTION_OUTPUT`

When the output type is invalid.

Check the type is within `OutputType`.

### `INVALID_TRANSACTION_STATUS`

When the transaction status received from the node is unexpected.

Check the status received is within `TransactionStatus`.

### `UNSUPPORTED_TRANSACTION_TYPE`

When the transaction type from the Fuel Node is _not_ supported.

The type is within [`TransactionType`](DOCS_API_URL/enums/_fuel_ts_account.TransactionType.html).

### `INVALID_TTL`

When the TTL is less than or equal to zero.

Ensure that the TTL is a number and that the TTL is greater than zero.

### `INVALID_WORD_LIST`

When the word list length is not equal to 2048.

The word list provided to the mnemonic length should be equal to 2048.

### `INVALID_URL`

When the URL provided is invalid.

Ensure that the URL is valid.

### `JSON_ABI_ERROR`

When an ABI type does not conform to the correct format.

It is usually caused by an incorrect type/s within your program, check our type [docs](../types/index.md) here for information on the types we support and their expected format.

### `LOG_TYPE_NOT_FOUND`

When the log type ID supplied can not be found in the ABI.

Check that the log type ID is correct and exists in the ABI.

### `MISSING_CONNECTOR`

A connector is missing when it's required for a given operation.

Ensure that a connector has been supplied to the `Account` or `Wallet`.

### `MISSING_PROVIDER`

A provider is missing when it's required for a given operation.

It could be caused by the provider not being set for either an [`Account`](DOCS_API_URL/modules/_fuel_ts_account.html) or a [`Wallet`](../wallets/index.md) - use the `connect` method to attach a provider.

### `MISSING_REQUIRED_PARAMETER`

When a required parameter has not been supplied to a given method.

The error message will determine which parameter is missing. This could be caused during type generation when neither `inputs` nor `filepaths` are supplied (at least one is required).

### `NODE_INFO_CACHE_EMPTY`

When the Fuel Node info cache is empty; This is usually caused by not being connected to the Fuel Node.

Ensure that the provider has connected to a Fuel Node successfully.

### `INSUFFICIENT_FUNDS_OR_MAX_COINS`

This error can occur during a funding operation or when calling the `getResourcesToSpend` method. It indicates one of the following issues:

`Insufficient Balance`: The specified account does not have enough balance to cover the required amount.

`UTXO Limit Exceeded`: Although the account has enough total funds, the funds are spread across too many UTXOs (coins). The blockchain limits how many UTXOs can be used in a single transaction, and exceeding this limit prevents the transaction from being processed.

First, to be sure what the real reason is, you can fetch the [balance](../wallets/checking-balances.md) of the `assetId` to ensure that the account has enough funds to cover the amount. After knowing the reason, to solve you can:

`For Insufficient Balance`: Acquire additional funds in the required asset to meet the amount needed.

`For UTXO Limit Exceeded`: Combine UTXOs to reduce their number and meet the network's requirements. You can follow [this guide](../cookbook/combining-utxos.md) to learn how to combine UTXOs effectively.

### `TIMEOUT_EXCEEDED`

When the timeout has been exceeded for a given operation.

Check that you're connected to the network and that the network is stable.

### `TYPE_NOT_FOUND`

When the type with the given type ID is not found in the ABI.

Check that the type ID is correct and exists in the ABI.

### `TYPE_NOT_SUPPORTED`

When an unexpected type has been detected - the error message will determine which type is incorrect.

Check the type against your ABI and ensure that it is correct. You can find a list of all our types [here](../types/index.md).

### `UNSUPPORTED_FUEL_CLIENT_VERSION`

When the version of the Fuel Node you are targeting is not supported by the client you are accessing it from.

Check the version of the Fuel Node and use a compatible version of the SDK to target it.

### `WALLET_MANAGER_ERROR`

A wallet manager will throw for a multitude of reasons. The error message will determine which element of the configuration is incorrect.

It could be that the passphrase is incorrect and/or the wallet does _not_ exist in the manager.

### `WORKSPACE_NOT_DETECTED`

When the workspace is not detected in the directory indicated in the message.

Ensure that the workspace is present in the directory specified.

### `UNKNOWN`

In cases where the error hasn't been mapped yet, this code will be used.

If you believe you found a bug, please report the [issue](https://github.com/FuelLabs/fuels-ts/issues/new/choose) to the team.

### `MAX_INPUTS_EXCEEDED`

When the number of transaction inputs exceeds the maximum limit allowed by the blockchain.

### `MAX_OUTPUTS_EXCEEDED`

When the number of transaction outputs exceeds the maximum limit allowed by the blockchain.

### `CHANGE_OUTPUT_COLLISION`

This error occurs when there's a conflict between the change output specified in the transaction request and the one specified in the `assembleTx` parameters:

1. The transaction request already has a change output set for a specific asset ID and address
2. The `assembleTx` parameters specify a different change output for the same asset ID

### `DUPLICATE_CHANGE_OUTPUT_ACCOUNT`

This error occurs when there are duplicate entries for the same asset ID with different `changeOutputAccount` values in the `accountCoinQuantities` parameter of the `assembleTx` method:

1. The `accountCoinQuantities` parameter contains multiple entries for the same asset ID
2. Each entry specifies a different `changeOutputAccount` for the same asset ID

### `RESPONSE_BODY_EMPTY`

This error occurs when the response from the server has an empty body. The issue will generally lie with the connection setup from your environment and the RPC.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/fuel-asm/index.md.md

# Fuel ASM

Instruction set for the [FuelVM](https://github.com/FuelLabs/fuel-specs).

---

This is a wrapped WASM version of the [`fuel-asm`](https://crates.io/crates/fuel-asm) Rust crate:

- https://crates.io/crates/fuel-asm
- https://github.com/FuelLabs/fuel-vm/tree/master/fuel-asm

## Usage

This example demonstrates how to use the `FuelAsm` to create a program, represented as a vector of instructions, and then convert it to bytes.

```
import { FuelAsm } from 'fuels';

// @ts-expect-error method reference missing in DTS
await FuelAsm.initWasm();

const programBytes = Uint8Array.from([
  ...FuelAsm.move_(0x10, 0x01).to_bytes(), // set r[0x10] := $one
  ...FuelAsm.slli(0x20, 0x10, 5).to_bytes(), // set r[0x20] := `r[0x10] << 5 == 32`
  ...FuelAsm.slli(0x21, 0x10, 6).to_bytes(), // set r[0x21] := `r[0x10] << 6 == 64`
  ...FuelAsm.aloc(0x21).to_bytes(), // alloc `r[0x21] == 64` to the heap
  ...FuelAsm.addi(0x10, 0x07, 1).to_bytes(), // set r[0x10] := `$hp + 1` (allocated heap)
  ...FuelAsm.move_(0x11, 0x04).to_bytes(), // set r[0x11] := $ssp
  ...FuelAsm.add(0x12, 0x04, 0x20).to_bytes(), // set r[0x12] := `$ssp + r[0x20]`
  ...FuelAsm.eck1(0x10, 0x11, 0x12).to_bytes(), // recover public key in memory[r[0x10], 64]
  ...FuelAsm.ret(0x01).to_bytes(), // return `1`
]);

console.log('Bytes', programBytes);
```

## Reference

The above usage is the `Typescript` equivalent of the [original example](https://crates.io/crates/fuel-asm) in `Rust`.

```
[Error reading file: /home/runner/work/docs-hub/docs-hub/docs/nightly/fuels-ts/apps/fuel-asm-example/src/main.rs]
```

## See Also

- [FuelVM Specs](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/)
- [FuelVM Semantics](https://docs.fuel.network/docs/specs/fuel-vm/#semantics)
- [Inline Assembly in Sway](https://docs.fuel.network/docs/sway/advanced/assembly)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/fuels-cli/abi-typegen.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const abiUrl = `
    https://docs.fuel.network/docs/sway/sway-program-types/smart_contracts/#the-abi-declaration
  `
  const contractsUrl = `
    https://docs.fuel.network/docs/sway/sway-program-types/smart_contracts/
  `
  const scriptsUrl = `
    https://docs.fuel.network/docs/sway/sway-program-types/scripts/
  `
</script>

# ABI Typegen

## The JSON ABI file

Whether you want to deploy or connect to a pre-existing smart contract, the <a :href="abiUrl" target="_blank" rel="noreferrer">JSON ABI</a> file is what makes it possible.

It tells the SDK about the <a :href="abiUrl" target="_blank" rel="noreferrer">ABI methods</a> in your <a :href="contractsUrl" target="_blank" rel="noreferrer">Smart Contracts</a> and <a :href="scriptsUrl" target="_blank" rel="noreferrer">Scripts</a>

Given the following Sway smart contract:

<!-- TODO: stop using hard-coded snippets -->

```rust:line-numbers
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

The JSON ABI file would look something like this:

```json
$ cat out/debug/my-test-abi.json
[
  {
    "type": "function",
    "inputs": [],
    "name": "test_function",
    "outputs": [
      {
        "name": "",
        "type": "bool",
        "components": null
      }
    ]
  }
]
```

See also:

- [Generating Types](./generating-types.md)
- [Using Generated Types](./using-generated-types.md)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/fuels-cli/commands.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels, forc, fuelCore } = data
</script>

# Commands

The `fuels` CLI consists of a couple of commands.

## `fuels init`

```console-vue
npx fuels@{{fuels}} help init
```

```console
Options:
  --path <path>                Path to project root (default: current directory)
  -w, --workspace <path>       Relative dir path to Forc workspace
  -c, --contracts [paths...]   Relative paths to Contracts
  -s, --scripts [paths...]     Relative paths to Scripts
  -p, --predicates [paths...]  Relative paths to Predicates
  -o, --output <path>          Relative dir path for Typescript generation output
  --forc-path <path>           Path to the `forc` binary
  --fuel-core-path <path>      Path to the `fuel-core` binary
  --auto-start-fuel-core       Auto-starts a `fuel-core` node during `dev` command
  --fuel-core-port <port>      Port to use when starting a local `fuel-core` node for dev mode
  -h, --help                   Display help
```

Creating a sample `fuel.config.ts` file:

```console-vue
npx fuels@{{fuels}} init --contracts ./my-contracts/* --output ./src/sway-contracts-api
```

Using [Forc workspaces](https://docs.fuel.network/docs/forc/workspaces/)? Try this instead:

```console-vue
npx fuels@{{fuels}} init --workspace ./sway-programs --output ./src/sway-programs-api
```

This will give you a minimal configuration:

```
import { createConfig } from 'fuels';

export default createConfig({
  workspace: './sway-programs', // forc workspace
  output: './src/sway-programs-api',
});
```

In a nutshell:

```sh
.
├── sway-programs # <— forc workspace
├── src
│   └── sway-programs-api # <— output
├── fuels.config.ts
└── package.json
```

### See more

- [Forc workspaces](https://docs.fuel.network/docs/forc/workspaces/)

## `fuels build`

```console-vue
npx fuels@{{fuels}} help build
```

```console
Options:
  --path <path>  Path to project root (default: "/Users/anderson/Code/fuel/fuels-ts/apps/docs")
  -d, --deploy       Deploy contracts after build (auto-starts a `fuel-core` node if needed)
  -h, --help         Display help
```

Examples:

```console-vue
npx fuels@{{fuels}} build
```

1.  Build all Sway programs under your `workspace` using `forc` <sup>[1](https://docs.fuel.network/docs/forc/commands/forc_build/)</sup>
1.  Generate types for them using `fuels-typegen` <sup>[2](#fuels-typegen)</sup>

```console-vue
npx fuels@{{fuels}} build --deploy
```

Using the `--deploy` flag will additionally:

1. Auto-start a short-lived `fuel-core` node if _needed_ ([docs](./config-file.md#autostartfuelcore))
1. Run `deploy` on that node

> _This is useful when working with contracts because a contract's ID is generated only on deployment._

## `fuels deploy`

```console-vue
npx fuels@{{fuels}} deploy
```

The `fuels deploy` command does two things:

1. Deploy all Sway contracts under `workspace`.
1. Saves their deployed IDs to:
   - _`./src/sway-programs-api/contract-ids.json`_

```json
{
  "myContract1": "0x..",
  "myContract2": "0x.."
}
```

Use it when instantiating your contracts:

```
    // #context import { Sample } from './sway-programs-api';
    // #context import contractsIds from './sway-programs-api/contract-ids.json';

    // #context /**
    // #context   * Get IDs using:
    // #context   *   contractsIds.<my-contract-name>
    // #context   */

    // #context const wallet = new Wallet.fromPrivateKey(process.env.PRIVATE_KEY);
    const contract = new Sample(contractsIds.sample, wallet);

    const { value } = await contract.functions.return_input(1337).dryRun();

    expect(value.toHex()).toEqual(toHex(1337));
```

For a complete example, see:

- [Using Generated Types](./using-generated-types.md)

### Proxy Contracts Deployment

Automatic deployment of proxy contracts can be enabled in `Forc.toml`.

For more info, please check these docs:

- [Proxy Contracts](https://docs.fuel.network/docs/forc/plugins/forc_client/#proxy-contracts)
- [Sway Libs / Upgradability Library](https://docs.fuel.network/docs/sway-libs/upgradability/#upgradability-library)
- [Sway Standards / SRC-14 - Simple Upgradable Proxies](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/#src-14-simple-upgradeable-proxies)

## `fuels dev`

```console-vue
npx fuels@{{fuels}} dev
```

The `fuels dev` command does three things:

1. Auto-start a short-lived `fuel-core` node ([docs](./config-file.md#autostartfuelcore))
1. Runs `build` and `deploy` once at the start
1. Watches your Forc workspace and repeats the previous step on every change

> _In `dev` mode, every time you update a contract on your Forc `workspace`, we re-generate type definitions and factory classes for it, following your pre-configured [`output`](./config-file.md#output) directory. If it's part of another build system running in dev mode (i.e. `next dev`), you can expect it to re-build / auto-reload as well._

## `fuels node`

```console-vue
npx fuels@{{fuels}} node
```

Starts a short-lived `fuel-core` node and requires a `fuels.config.ts` config file.

Generate one with [`fuels init`](#fuels-init):

```
import { createConfig } from 'fuels';

export default createConfig({
  workspace: './sway-programs', // forc workspace
  output: './src/sway-programs-api',
});
```

## `fuels typegen`

Manually generates type definitions and factory classes from ABI JSON files.

```console-vue
npx fuels@{{fuels}} help typegen
```

```console
Options:
  -i, --inputs <path|glob...>  Input paths/globals to your Abi JSON files
  -o, --output <dir>           Directory path for generated files
  -c, --contract               Generate types for Contracts [default]
  -s, --script                 Generate types for Scripts
  -p, --predicate              Generate types for Predicates
  -S, --silent                 Omit output messages
```

For more info, check:

- [Generating Types from ABI](./generating-types.md)

## `fuels versions`

Check for version incompatibilities between your [Fuel Toolchain](https://docs.fuel.network/docs/sway/introduction/fuel_toolchain/#the-fuel-toolchain) component versions, matching them against the ones supported by the Typescript SDK version that you have.

```console-vue
npx fuels@{{fuels}} versions
```

```console-vue
┌───────────┬───────────┬────────────────┬─────────────┐
│           │ Supported │ Yours / System │ System Path │
├───────────┼───────────┼────────────────┼─────────────┤
│ Forc      │ {{forc}}    │ {{forc}}         │ forc        │
├───────────┼───────────┼────────────────┼─────────────┤
│ Fuel-Core │ {{fuelCore}}    │ {{fuelCore}}         │ fuel-core   │
└───────────┴───────────┴────────────────┴─────────────┘

You have all the right versions! ⚡
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/fuels-cli/config-file.md.md

# Config File

Here, you can learn more about all configuration options.

## `workspace`

Relative directory path to Forc workspace.

```
  workspace: './sway-programs',
```

> _The property `workspace` is incompatible with [`contracts`](#contracts), [`predicates`](#predicates), and [`scripts`](#scripts)._

## `contracts`

List of relative directory paths to Sway contracts.

```
  contracts: ['./sway-programs/contracts'],
```

> _The property `contracts` is incompatible with [`workspace`](#workspace)._

## `predicates`

List of relative directory paths to Sway predicates.

```
  predicates: ['./sway-programs/predicates'],
```

> _The property `predicates` is incompatible with [`workspace`](#workspace)._

## `scripts`

List of relative directory paths to Sway scripts.

```
  scripts: ['./sway-programs/scripts'],
```

> _The property `scripts` is incompatible with [`workspace`](#workspace)._

## `output`

Relative directory path to use when generating Typescript definitions.

```
  output: './src/sway-programs-api',
```

## `providerUrl`

The URL to use when deploying contracts.

```
  // Default: http://127.0.0.1:4000/v1/graphql
  providerUrl: 'http://network:port/v1/graphql',
```

> _When [`autostartFuelCore`](#autostartfuelcore) property is set to `true`, the `providedUrl` is overridden by that of the local short-lived `fuel-core` node started by the [`fuels dev`](./commands.md#fuels-dev) command._

## `privateKey`

Wallet private key, used when deploying contracts.

This property should ideally come from env — `process.env.MY_PRIVATE_KEY`.

```
  privateKey: '0xa449b1ffee0e2205fa924c6740cc48b3b473aa28587df6dab12abc245d1f5298',
```

> _When [`autostartFuelCore`](#autostartfuelcore) property is set to `true`, the `privateKey` is overridden with the `consensusKey` of the local short-lived `fuel-core` node started by the [`fuels dev`](./commands.md#fuels-dev) command._

## `snapshotDir`

> - _Used by [`fuels dev`](./commands.md#fuels-dev) only_.

Relative path to directory containing custom configurations for `fuel-core`, such as:

- `chainConfig.json`
- `metadata.json`
- `stateConfig.json`

This will take effect only when [`autoStartFuelCore`](#autostartfuelcore) is `true`.

```
  snapshotDir: './my/snapshot/dir',
```

## `autoStartFuelCore`

> - _Used by [`fuels dev`](./commands.md#fuels-dev) only_.

When set to `true`, it will automatically:

1. Starts a short-lived `fuel-core` node as part of the [`fuels dev`](./commands.md#fuels-dev) command
1. Override property [`providerUrl`](#providerurl) with the URL for the recently started `fuel-core` node

```
  autoStartFuelCore: true,
```

If set to `false`, you must spin up a `fuel-core` node by yourself and set the URL for it via [`providerUrl`](#providerurl).

## `fuelCorePort`

> - _Used by [`fuels dev`](./commands.md#fuels-dev) only_.
> - _Ignored when [`autoStartFuelCore`](#autostartfuelcore) is set to `false`._

Port to use when starting a local `fuel-core` node.

```
  // Default: first free port, starting from 4000
  fuelCorePort: 4000,
```

## `forcBuildFlags`

> - _Used by [`fuels build`](./commands.md#fuels-build) and [`fuels deploy`](./commands.md#fuels-deploy)_.

Sway programs are compiled in `debug` mode by default.

Here you can customize all build flags, e.g. to build programs in `release` mode.

```
  // Default: []
  forcBuildFlags: ['--release'],
```

Check also:

- [Forc docs](https://docs.fuel.network/docs/forc/commands/forc_build/#forc-build)

## `deployConfig`

You can supply a ready-to-go deploy configuration object:

```
  deployConfig: {},
```

Or use a function for crafting dynamic deployment flows:

- If you need to fetch and use configs or data from a remote data source
- If you need to use IDs from already deployed contracts — in this case, we can use the `options.contracts` property to get the necessary contract ID. For example:

```
  deployConfig: async (options: ContractDeployOptions) => {
    // ability to fetch data remotely
    await Promise.resolve(`simulating remote data fetch`);

    // get contract by name
    const { contracts } = options;

    const contract = contracts.find(({ name }) => {
      const found = name === MY_FIRST_DEPLOYED_CONTRACT_NAME;
      return found;
    });

    if (!contract) {
      throw new Error('Contract not found!');
    }

    return {
      storageSlots: [
        {
          key: '0x..',
          /**
           * Here we could initialize a storage slot,
           * using the relevant contract ID.
           */
          value: contract.contractId,
        },
      ],
    };
  },
```

## `onBuild`

A callback function that is called after a build event has been successful.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)

```
  onBuild: (config: FuelsConfig): void | Promise<void> => {
    console.log('fuels:onBuild', { config });
  },
```

## `onDeploy`

A callback function that is called after a deployment event has been successful.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)
- `data` — The data (an array of deployed contracts)

```
  onDeploy: (config: FuelsConfig, data: DeployedData): void | Promise<void> => {
    console.log('fuels:onDeploy', { config, data });
  },
```

## `onDev`

A callback function that is called after the [`fuels dev`](./commands.md#fuels-dev) command has successfully restarted.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)

```
  onDev: (config: FuelsConfig): void | Promise<void> => {
    console.log('fuels:onDev', { config });
  },
```

## `onNode`

A callback function that is called after the [`fuels node`](./commands.md#fuels-node) command has successfully refreshed.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)

```
  onNode: (config: FuelsConfig): void | Promise<void> => {
    console.log('fuels:onNode', { config });
  },
```

## `onFailure`

Pass a callback function to be called in case of errors.

Parameters:

- `config` — The loaded config (`fuels.config.ts`)
- `error` — Original error object

```
  onFailure: (config: FuelsConfig, error: Error): void | Promise<void> => {
    console.log('fuels:onFailure', { config, error });
  },
```

## `forcPath`

Path to the `forc` binary.

When not supplied, will default to using the `system` binaries (`forc`).

```
  // Default: 'forc',
  forcPath: '~/.fuelup/bin/forc',
```

## `fuelCorePath`

Path to the `fuel-core` binary.

When not supplied, will default to using the `system` binaries (`fuel-core`).

```
  // Default: 'fuel-core'
  fuelCorePath: '~/.fuelup/bin/fuel-core',
```

## Loading environment variables

If you want to load environment variables from a `.env` file, you can use the `dotenv` package.

First, install it:

::: code-group

```sh [pnpm]
pnpm install dotenv
```

```sh [npm]
npm install dotenv
```

```sh [bun]
bun install dotenv
```

:::

Then, you can use it in your `fuels.config.ts` file:

```
import { createConfig } from 'fuels';
import dotenv from 'dotenv';
import { providerUrl } from './src/lib';

dotenv.config({
  path: ['.env.local', '.env'],
});

// If your node is running on a port other than 4000, you can set it here
const fuelCorePort = +(process.env.VITE_FUEL_NODE_PORT as string) || 4000;

export default createConfig({
  workspace: './sway-programs', // Path to your Sway workspace
  output: './src/sway-api', // Where your generated types will be saved
  fuelCorePort,
  providerUrl,
  forcPath: 'fuels-forc',
  fuelCorePath: 'fuels-core',
});
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/fuels-cli/generating-types.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Generating Types from ABI

## Installation

First we install `fuels` to our project:

```console-vue
pnpm add fuels@{{fuels}}
```

## Help

A first glance at the docs:

```console
$ pnpm fuels typegen -h

Usage: fuels typegen [options]

Generate Typescript from Sway ABI JSON files

Options:
  -i, --inputs <path|glob...>  Input paths/globals to your ABI JSON files
  -o, --output <dir>           Directory path for generated files
  -c, --contract               Generate types for Contracts [default]
  -s, --script                 Generate types for Scripts
  -p, --predicate              Generate types for Predicates
  -S, --silent                 Omit output messages
  -h, --help                   Display help
```

## Generating Types for Contracts

You can generate types for a Sway contract using the command below:

<!-- This section should have the command to generate types for a Sway contract -->
<!-- gen_types:example:start -->

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types
```

<!-- gen_types:example:end -->

<!-- This section should explain the flags used in the typegen command -->
<!-- flags:example:start -->

The path after the input flag `-i` should point to the file ending in `-abi.json` produced when the contract was built.

The path after the output flag `-o` will be the output directory for the generated types.

You can omit the `--contract` option here since it's the default.

<!-- flags:example:end -->

## Generating Types for Scripts

To generate types for a Sway script, use the `--script` flag:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --script
```

## Generating Types for Predicates

To generate types for a Sway predicate, use the `--predicate` flag:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --predicate
```

---

See also:

- [Using Generated Contract Types](./using-generated-types.md#contract)
- [Using Generated Script Types](./using-generated-types.md#script)
- [Using Generated Predicate Types](./using-generated-types.md#predicate)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/fuels-cli/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Fuels CLI

The quickest way to build full stack Fuel dApps.

- [`fuels init`](./commands.md#fuels-init) — Creates a new `fuels.config.ts` file
- [`fuels build`](./commands.md#fuels-build) — Build `forc` workspace and generate Typescript types for everything
- [`fuels deploy`](./commands.md#fuels-deploy) — Deploy workspace contracts and save their IDs to JSON file
- [`fuels dev`](./commands.md#fuels-dev) — Start local Fuel Core _node_ and `build` + `deploy` on every file change

## Getting started

Imagine you have this file structure:

```sh
my-fuel-dapp # NextJS app or similar
├── sway-programs # Forc's workspace
│   ├── src
│   ├── ...
│   └── Forc.toml
├── public
│   └── ...
├── src
│   ├── app
│   ├── ...
├   └── sway-programs-api # Type-safe generated API
└── package.json
```

## Prerequisites

The [Fuel Toolchain](https://docs.fuel.network/docs/sway/introduction/fuel_toolchain/#the-fuel-toolchain) and its components (namely `forc` and `fuel-core`) are pre-requisite for several operations with the Fuels CLI. For example:

- Building out contracts using [`fuels build`](./commands.md#fuels-build) requires `forc`.
- Deploying contracts locally using [`fuels deploy`](./commands.md#fuels-deploy) requires `fuel-core`.

Follow the [installation guide](https://docs.fuel.network/guides/installation/) if you don't have them installed already.

## Installation

Add it to your `my-fuel-dapp` project:

::: code-group

```console-vue [npm]
npm install fuels@{{fuels}} --save
```

```console-vue [pnpm]
pnpm add fuels@{{fuels}}
```

```console-vue [bun]
bun add fuels@{{fuels}}
```

:::

## Double-checking

```console-vue
npx fuels@{{fuels}} -v
```

## Next Step

Use [`fuels init`](./commands.md#fuels-init) to create a [`fuel.config.ts`](./config-file.md) file.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/fuels-cli/using-generated-types.md.md

<!-- TODO: Replace plan-text by code-snippets -->

# Using Generated Types

After generating types via:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types
```

We can use these files like so:

```
    // #context import { DemoContract } from './sway-programs-api';

    const contractInstance = new DemoContract(contractId, wallet);
    const call2 = await contractInstance.functions.return_input(1337).call();
    const { value: v2 } = await call2.waitForResult();
```

## Contract

Let's use the Contract class to deploy a contract:

```
    // #context import { DemoContract } from './sway-programs-api';

    // Deploy
    const deploy = await DemoContractFactory.deploy(wallet);
    const { contract } = await deploy.waitForResult();
```

### Autoloading of Storage Slots

Typegen tries to resolve, auto-load, and embed the [Storage Slots](../contracts/storage-slots.md) for your Contract within the `MyContract` class. Still, you can override it alongside other options from [`DeployContractOptions`](https://github.com/FuelLabs/fuels-ts/blob/a64b67b9fb2d7f764ab9151a21d2266bf2df3643/packages/contract/src/contract-factory.ts#L19-L24), when calling the `deploy` method:

```
    // #context import { DemoContractFactory } from './sway-programs-api';

    const { waitForResult } = await DemoContractFactory.deploy(wallet, {
      storageSlots,
    });

    const { contract } = await waitForResult();
```

## Script

After generating types via:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --script
```

We can use these files like so:

```
  // #context import { Script } from './sway-programs-api';

  const script = new DemoScript(wallet);
  const { waitForResult } = await script.functions.main().call();
  const { value } = await waitForResult();
```

## Predicate

After generating types via:

```console
pnpm fuels typegen -i ./abis/*-abi.json -o ./types --predicate
```

We can use these files like so:

```
  // #context import type { PredicateInputs } from './sway-programs-api';
  // #context import { Predicate } from './sway-programs-api';

  // In this exchange, we are first transferring some coins to the predicate
  using launched = await launchTestNode();

  const {
    provider,
    wallets: [wallet],
  } = launched;

  const receiver = Wallet.fromAddress(Address.fromRandom(), provider);

  const predicateData: DemoPredicateInputs = [];
  const predicate = new DemoPredicate({
    provider,
    data: predicateData,
  });

  const tx = await wallet.transfer(predicate.address, 200_000, await provider.getBaseAssetId());
  const { isStatusSuccess } = await tx.wait();

  // Then we are transferring some coins from the predicate to a random address (receiver)
  const tx2 = await predicate.transfer(receiver.address, 50_000, await provider.getBaseAssetId());
  await tx2.wait();

  expect((await receiver.getBalance()).toNumber()).toEqual(50_000);
  expect(isStatusSuccess).toBeTruthy();
```

See also:

- [Generating Types for Contracts](./generating-types.md#generating-types-for-contracts)
- [Generating Types for Scripts](./generating-types.md#generating-types-for-scripts)
- [Generating Types for Predicates](./generating-types.md#generating-types-for-predicates)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/getting-started/cdn-usage.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# CDN Usage (browser only)

```html-vue
<script type="module">
  import {
    Wallet,
    Provider,
  } from "https://cdn.jsdelivr.net/npm/fuels@{{fuels}}/dist/browser.min.mjs";

  const main = async () => {
    const provider = new Provider(
      "https://mainnet.fuel.network/v1/graphql",
    );
    const { name } = await provider.getChain();
    console.log(name);
  };

  main();
</script>
```

# More

- [React Example](./react-example.md)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/getting-started/connecting-to-the-network.md.md

# Connecting to the Network

After [installing](./installation.md) the `fuels` package, it's easy to connect to the Network:

```
import { Provider } from 'fuels';

const NETWORK_URL = 'https://mainnet.fuel.network/v1/graphql';

const provider = new Provider(NETWORK_URL);

const baseAssetId = await provider.getBaseAssetId();
const chainId = await provider.getChainId();
const gasConfig = await provider.getGasConfig();

console.log('chainId', chainId);
console.log('baseAssetId', baseAssetId);
console.log('gasConfig', gasConfig);
```

# RPC URLs

These are our official RPC URLs:

| Network   | URL                                                         |
| --------- | ----------------------------------------------------------- |
| Mainnet   | `https://mainnet.fuel.network/v1/graphql`                   |
| Testnet   | `https://testnet.fuel.network/v1/graphql`                   |
| Localhost | [Running a local Fuel node](./running-a-local-fuel-node.md) |

# Resources

Access all our apps directly:

|          | Mainnet                                    | Testnet                                    |
| -------- | ------------------------------------------ | ------------------------------------------ |
| Faucet   | —                                          | https://faucet-testnet.fuel.network/       |
| Explorer | https://app.fuel.network                   | https://app-testnet.fuel.network           |
| Bridge   | https://app.fuel.network/bridge            | https://app-testnet.fuel.network/bridge    |
| GraphQL  | https://mainnet.fuel.network/v1/playground | https://testnet.fuel.network/v1/playground |


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/getting-started/index.md.md

# Getting Started

Welcome to `fuels` Typescript SDK!

We prepared some guides to walk you through your first steps:

1. [Installation](./installation.md)
1. [Connecting to the Network](./connecting-to-the-network.md)
1. [Running a local Fuel node](./running-a-local-fuel-node.md)
1. [React Example](./react-example.md)
1. [CDN Usage](./cdn-usage.md)
1. [Next Steps](./next-steps.md)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/getting-started/installation.md.md

<script setup>
  import { data } from '../../versions.data'
  const { fuels } = data
</script>

# Installation

You must install the [Fuel Toolchain](https://docs.fuel.network/guides/installation/) before using this library.

Then add the `fuels` dependency to your project:

::: code-group

```sh-vue [bun]
bun add fuels@{{fuels}}
```

```sh-vue [pnpm]
pnpm add fuels@{{fuels}}
```

```sh-vue [npm]
npm install fuels@{{fuels}} --save
```

:::

Now you are ready to:

- [Connect to the Network](./connecting-to-the-network.md)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/getting-started/next-steps.md.md

# Done!

Wait no more, let's build your first Fuel dApp!

- [Creating a Fuel dApp](../creating-a-fuel-dapp/)

## Further Resources

For a more in-depth, step-by-step guide on working with the wider Fuel ecosystem, check out the [Developer Quickstart](https://docs.fuel.network/guides/quickstart/), which uses a more procedural and detailed approach:

1. Installing all tools needed to develop with the Fuel ecosystem
1. Writing your first Sway Project
1. Deploying your contract
1. Building a simple front-end dApp to interact with your deployed contract


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/getting-started/react-example.md.md

# React Example

<!-- TODO: Create properly code snippet on new package: `app/react-app` after https://github.com/FuelLabs/fuels-ts/pull/827 got merged -->

```tsx
import { BN, Provider, Wallet } from "fuels";
import { useEffect, useState } from "react";

function App() {
  const [balance, setBalance] = useState(0);

  useEffect(() => {
    const onPageLoad = async () => {
      const provider = new Provider("https://mainnet.fuel.network/v1/graphql");

      const wallet = Wallet.fromAddress("0x...", provider);
      const { balances } = await wallet.getBalances();

      setBalance(new BN(balances[0].amount).toNumber());
    };

    onPageLoad();
  }, []);

  return <div>My Balance: {balance}</div>;
}

export default App;
```

# See Also

- [Optimized React Example](../cookbook/optimized-react-example.md)
- [CDN Usage](./cdn-usage.md)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/getting-started/running-a-local-fuel-node.md.md

# Running a local Fuel node

Remember to first install the [Fuel Toolchain](https://docs.fuel.network/guides/installation/).

Check the online docs:

|             | Command      | Documentation                                                                                          |
| ----------- | ------------ | ------------------------------------------------------------------------------------------------------ |
| Fuel Binary | `fuel-core`  | [docs](https://docs.fuel.network/docs/node-operator/fuel-ignition/local-node/) — Running a local node  |
| TS SDK      | `fuels node` | [docs](https://docs.fuel.network/docs/fuels-ts/fuels-cli/commands/#fuels-node) — Using the `fuels` CLI |

<!-- | Forc | `forc node` | [docs](https://docs.fuel.network/docs/forc/commands/forc_node/) | -->

# Utilities

## Testing

You can run a Fuel node from within your `.ts` unit tests:

- [Launching a test node](../testing/launching-a-test-node.md)

## Developing

Configure your project for the `fuels` CLI using a `fuels.config.ts` file:

- [Using the `fuels init` command](../fuels-cli/commands.md#fuels-init)

It makes development easier with a hot-reload experience:

- [Using the `fuels dev` command](../fuels-cli/commands.md#fuels-dev)

# More

- [React Example](./react-example.md)
- [CDN Usage](./cdn-usage.md)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/predicates/configurable-constants.md.md

# Predicate With Configurable Constants

Predicates, much like [contracts](../contracts/configurable-constants.md) and [scripts](../scripts/configurable-constants.md), also supports configurable constants. This enables Predicates to suit specific use cases and enhance their functionality.

## Example: Asset Transfer Validation

Let's consider an example where a predicate is used to validate an asset transfer. In this case, the transfer will only be executed if the recipient's address is on a pre-approved whitelist.

The following snippet illustrates how this could be implemented:

```
predicate;

configurable {
    WHITELISTED: b256 = 0xa703b26833939dabc41d3fcaefa00e62cee8e1ac46db37e0fa5d4c9fe30b4132,
}

fn main(address: b256) -> bool {
    WHITELISTED == address
}
```

In this example, you'll notice the use of a configurable constant named `WHITELISTED`. This constant has a default value that represents the default approved address.

## Modifying The Whitelist

If there is a need to whitelist another address, the `WHITELISTED` constant can be easily updated. The following snippet demonstrates how to set a new value for the `WHITELISTED` constant and to make the predicate execute the transfer:

```
import { Wallet, Provider } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_ADDRESS,
  WALLET_PVT_KEY_2,
} from '../../../../env';
import { WhitelistedAddressPredicate } from '../../../../typegend/predicates/WhitelistedAddressPredicate';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const whitelisted = Wallet.fromAddress(WALLET_ADDRESS, provider);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);
const recipient = Wallet.generate({ provider });

const configurable = { WHITELISTED: whitelisted.address.toB256() };

// Instantiate predicate with configurable constants
const predicate = new WhitelistedAddressPredicate({
  provider,
  data: [configurable.WHITELISTED],
  configurableConstants: configurable,
});

// Transferring funds to the predicate
const tx1 = await sender.transfer(predicate.address, 200_000, baseAssetId, {
  gasLimit: 1000,
});

await tx1.waitForResult();

const amountToTransfer = 100;

// Transferring funds from the predicate to destination if predicate returns true
const tx2 = await predicate.transfer(
  recipient.address,
  amountToTransfer,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

await tx2.waitForResult();
```

By ensuring that the updated `WHITELISTED` address matches the intended recipient's address, the predicate will validate the transfer successfully.

## Default Whitelist Address

In scenarios where the default whitelisted address is already the intended recipient, there's no need to update the `WHITELISTED` constant. The predicate will validate the transfer based on the default value. Here's how this scenario might look:

```
import { Wallet, Provider } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { WhitelistedAddressPredicate } from '../../../../typegend/predicates/WhitelistedAddressPredicate';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient = Wallet.generate({ provider });

// Instantiate predicate without configurable constants (will use the address defined in Sway)
const predicate = new WhitelistedAddressPredicate({
  provider,
  data: ['0xa703b26833939dabc41d3fcaefa00e62cee8e1ac46db37e0fa5d4c9fe30b4132'],
});

// Transferring funds to the predicate
const tx1 = await sender.transfer(predicate.address, 200_000, baseAssetId, {
  gasLimit: 1000,
});

await tx1.waitForResult();

const amountToTransfer = 100;

// Transferring funds from the predicate to destination if predicate returns true
const tx2 = await predicate.transfer(
  recipient.address,
  amountToTransfer,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

await tx2.waitForResult();
```

This ability to configure constants within predicates provides a flexible mechanism for customizing their behavior, thereby enhancing the robustness and versatility of our asset transfer process.

It's important to note that these customizations do not directly modify the original predicate. The address of a predicate is a hash of its bytecode. Any change to the bytecode, including altering a constant value, would generate a different bytecode, and thus a different hash. This leads to the creation of a new predicate with a new address.

This doesn't mean that we're changing the behavior of the original predicate. Instead, we're creating a new predicate with a different configuration.

Therefore, while configurable constants do indeed enhance the flexibility and robustness of predicates, it is achieved by creating new predicates with different configurations, rather than altering the behavior of existing ones.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/predicates/custom-transactions.md.md

# Custom Transactions

Utilizing predicate logic unlocks a wide range of possibilities for your dApps when creating transactions. Therefore, pairing predicates with custom transactions can help you achieve more complex use cases. This can be achieved by instantiating a custom transaction, appending the predicate resources, and submitting the transaction via a successfully validated predicate.

Custom transactions can be shaped via a `ScriptTransactionRequest` instance. For more information on crafting custom transactions and the methods available to them, please refer to the [Transaction Request](../transactions/modifying-the-request.md) guide.

However, this guide will demonstrate how to use a predicate in a custom transaction. Consider the following predicate, where a configurable pin must be used to validate the predicate and unlock the funds:

```
predicate;

configurable {
    PIN: u64 = 1337,
}

fn main(pin: u64) -> bool {
    return PIN == pin;
}
```

We can interact with the above and include it in a custom transaction like so:

```
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ConfigurablePin } from '../../../typegend';
import type { ConfigurablePinInputs } from '../../../typegend/predicates/ConfigurablePin';

// Setup
const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });
const assetId = await provider.getBaseAssetId();
const amountToFundPredicate = 300_000;
const amountToReceiver = 100_000;

// Instantiate the predicate using valid predicate data, aka the pin we need
// to send the funds to the receiver
const data: ConfigurablePinInputs = [1337];
const predicate = new ConfigurablePin({ provider, data });

// Fund the predicate, so that we can send these funds via predicate logic
// to the receiver
const fundPredicateTx = await sender.transfer(
  predicate.address,
  amountToFundPredicate,
  assetId
);
await fundPredicateTx.waitForResult();
const initialPredicateBalance = await predicate.getBalance(assetId);

// Instantiate the script request
const request = new ScriptTransactionRequest();

// Adding the OutputCoin that represents the funds that we want to send to the receiver
request.addCoinOutput(receiver.address, amountToReceiver, assetId);

// Estimate the transaction cost and fund accordingly
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: predicate,
  accountCoinQuantities: [
    {
      amount: amountToReceiver,
      assetId,
      account: predicate,
      changeOutputAccount: predicate,
    },
  ],
});

// Submit the transaction and await it's result
const predicateTx = await predicate.sendTransaction(assembledRequest);
await predicateTx.waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/predicates/deploying-predicates.md.md

# Deploying Predicates

In order to optimize the cost of your recurring predicate executions, we recommend first deploying your predicate. This can be done using the [Fuels CLI](../fuels-cli/index.md) and running the [deploy command](../fuels-cli/commands.md#fuels-deploy).

By deploying the predicate, its bytecode is stored on chain as a blob. The SDK will then produce bytecode that can load the blob on demand to execute the original predicate. This far reduces the repeat execution cost of the predicate.

## How to Deploy a Predicate

To deploy a predicate, we can use the [Fuels CLI](../fuels-cli/index.md) and execute the [deploy command](../fuels-cli/commands.md#fuels-deploy).

This will perform the following actions:

1. Compile the predicate using your `forc` version
1. Deploy the built predicate binary to the chain as a blob
1. Generate a new, smaller predicate that loads the deployed predicate's blob
1. Generate types for both the predicate and the loader that you can use in your application

We can then utilize the above generated types like so:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import {
  ConfigurablePin,
  ConfigurablePinLoader,
} from '../../../typegend/predicates';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });
const baseAssetId = await provider.getBaseAssetId();

// We can deploy dynamically or via `fuels deploy`
const originalPredicate = new ConfigurablePin({
  provider,
  data: [1337],
});

const { waitForResult: waitForDeploy } = await originalPredicate.deploy(wallet);
await waitForDeploy();

// First, we will need to instantiate the script via it's loader bytecode.
// This can be imported from the typegen outputs that were created on `fuels deploy`.
// Then we can use the predicate as we would normally, such as overriding the configurables.
const loaderPredicate = new ConfigurablePinLoader({
  data: [23],
  provider,
  configurableConstants: {
    PIN: 23,
  },
});

// Now, let's fund the predicate
const fundTx = await wallet.transfer(
  loaderPredicate.address,
  100_000,
  baseAssetId
);
await fundTx.waitForResult();

// Then we'll execute the transfer and validate the predicate
const transferTx = await loaderPredicate.transfer(
  receiver.address,
  1000,
  baseAssetId
);
const { isStatusSuccess } = await transferTx.waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/predicates/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const introUrl = `https://docs.fuel.network/docs/sway/introduction/`
  const debugUrl = `https://docs.fuel.network/docs/sway/sway-program-types/predicates/#debugging-predicates`
</script>

# Predicates

Predicates in Sway are specific types of programs that return a boolean value, meaning they function like rules that a transaction must follow to be valid.

They don't have access to the information written on the blockchain – they make decisions based solely on the received parameters.

These predicates are pure functions, which means they don't cause any unintended side effects.

The key difference here is that instead of checking these rules directly on the blockchain, we check them 'off' the blockchain first. Once we're confident they're valid, we then record the transaction on the blockchain.

This method is not only more efficient but also helps to prevent traffic jams on the network and makes transactions cheaper. It does so by reducing the need for repetitive calculations on the blockchain.

## Working with Predicates

Users can send assets to the predicate address as they would to any other address on the blockchain. To spend funds stored at the predicate address, users must provide the original byte code of the predicate and, if required, the predicate data.

The predicate data relates to the parameters received by the predicate's `main` function. This data comes into play during the byte code's execution. If the `main` function does not have any parameters then there is no data to be provided, therefore we do not provide the predicate data.

If the predicate is validated successfully, the funds will be accessible. Otherwise, the SDK will throw a validation error.

In the next section, we provide a step-by-step guide on how to interact with a predicate to validate your transactions.

## Debugging Predicates

Currently there is no way to <a :href="debugUrl" target="_blank" rel="noreferrer">debug a predicate</a> yet. In the meantime, a practical workaround is to initially write, test, and debug your predicate as a script, which has more debugging tools available. Once it's working as expected, you can then convert it back into a predicate.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/predicates/instantiating-a-predicate.md.md

# Instantiating predicates

A predicate in Sway can be as simple as the following:

```
predicate;

fn main() -> bool {
    true
}
```

In this minimal example, the `main` function does not accept any parameters and simply returns true.

Just like contracts in Sway, once you've created a predicate, you can compile it using `forc build`. For more information on working with Sway, refer to the <a :href="introUrl" target="_blank" rel="noreferrer">Sway documentation</a>.

After compiling, you will obtain the binary of the predicate and its JSON ABI (Application Binary Interface). Using these, you can instantiate a predicate in TypeScript as shown in the code snippet below:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);

const predicate = new ReturnTruePredicate({
  provider,
});
```

The created [`Predicate`](DOCS_API_URL/classes/_fuel_ts_account.Predicate.html) instance, among other things, has three important properties: the predicate `bytes` (byte code), the `chainId`, and the predicate `address`.

This address, generated from the byte code, corresponds to the Pay-to-Script-Hash (P2SH) address used in Bitcoin.

## Predicate with multiple arguments

You can pass more than one argument to a predicate. For example, this is a predicate that evaluates to `true` if the two arguments are not equal:

```
predicate;

fn main(arg1: u64, arg2: u64) -> bool {
    return arg1 != arg2;
}
```

You can pass the two arguments to this predicate like this:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { PredicateMultiArgs } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);

const predicate = new PredicateMultiArgs({ provider, data: [20, 30] });
```

## Predicate with a Struct argument

You can also pass a struct as an argument to a predicate. This is one such predicate that expects a struct as an argument:

```
predicate;

struct Validation {
    has_account: bool,
    total_complete: u64,
}

fn main(received: Validation) -> bool {
    let expected_has_account: bool = true;
    let expected_total_complete: u64 = 100;

    received.has_account == expected_has_account && received.total_complete == expected_total_complete
}
```

You can pass a struct as an argument to this predicate like this:

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { PredicateMainArgsStruct } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);

const predicate = new PredicateMainArgsStruct({
  provider,
  data: [{ has_account: true, total_complete: 100 }],
});
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/predicates/methods.md.md

# Interacting With Predicates

The `Predicate` class extends the [`Account`](DOCS_API_URL/modules/_fuel_ts_account.html) class, inheriting all its methods. Therefore, there are multiple ways to interact with predicates, but broadly speaking, we can think about three:

- `Checking Balances`
- `Transactions`
- `Transfers`

## Checking Balances

### `getBalances`

This will return the balances of all assets owned by the predicate.

See also: [Checking Wallet Balances](https://docs.fuel.network/docs/fuels-ts/wallets/checking-balances/#getting-a-wallets-balance)

### `getResourcesToSpend`

This will return the resources owned by a predicate so that they can be added to a transaction request.

This method is called under the hood when using [`transfer`](./methods.md#transfer) or [`createTransfer`](./methods.md#createtransfer).

You may want to use this method when using a predicate in an existing transaction request.

```
import { bn, Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

// Fund the predicate
const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

// Instantiate the transaction request.
const transactionRequest = new ScriptTransactionRequest({
  gasLimit: 2000,
  maxFee: bn(0),
});

// Get the resources available to send from the predicate.
const predicateCoins = await predicate.getResourcesToSpend([
  { amount: 2000, assetId: baseAssetId },
]);

// Add the predicate input and resources.
transactionRequest.addResources(predicateCoins);
```

## Transactions

### `setData`

The `setData` method can be used to update the predicate data (i.e., predicate arguments) after the predicate has already been instantiated. Since the predicate data is initially set during instantiation, `setData` provides a way to modify it afterward if needed.

```
const predicate = new ConfigurablePin({
  provider,
  data: [1000], // This is the initial set data
});

predicate.setData([1337]); // This is the new set data
```

> Note: Using `setData` only updates the predicate data inside the predicate instance itself. It does not affect predicate data already embedded in a transaction request that includes predicate UTXOs. This is because each predicate UTXO carries its own copy of the predicate data.

```
const predicate = new ConfigurablePin({
  provider,
  data: [1000],
});

// Fund the predicate
const fundPredicate = await funder.transfer(predicate.address, 100_000_000);
await fundPredicate.waitForResult();

const transactionRequest = await predicate.createTransfer(
  receiver.address,
  100_000,
  baseAssetId
);

// The data will not be modified within the transaction request
predicate.setData([1337]);
```

If you need to modify the predicate data within a transaction request, use the `populateTransactionPredicateData` method after setting the new data.

```
const predicate = new ConfigurablePin({
  provider,
  data: [1000],
});

// Fund the predicate
const fundPredicate = await funder.transfer(predicate.address, 100_000_000);
await fundPredicate.waitForResult();

const transactionRequest = await predicate.createTransfer(
  receiver.address,
  100_000,
  baseAssetId
);

predicate.setData([1337]);

predicate.populateTransactionPredicateData(transactionRequest);
```

### `sendTransaction`

This is used to send a transaction to the node.

```
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

// Fund the predicate
const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);

await fundPredicate.waitForResult();

// Instantiate the transaction request.
const request = new ScriptTransactionRequest();

// Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: predicate,
  accountCoinQuantities: [
    {
      amount: '0',
      assetId: baseAssetId,
      account: predicate,
      changeOutputAccount: predicate,
    },
  ],
});

// Send the transaction using the predicate
const result = await predicate.sendTransaction(assembledRequest);

await result.waitForResult();
```

### `simulateTransaction`

You can use the `simulateTransaction` method to dry-run a predicate call without consuming resources. A typical use case of a dry-run call is to validate that sufficient funds are available to cover the transaction fees.

```
import {
  bn,
  Provider,
  ReceiptType,
  ScriptTransactionRequest,
  Wallet,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });

const predicate = new ReturnTruePredicate({
  provider,
});

const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

// Instantiate the transaction request.
const request = new ScriptTransactionRequest();

const amount = bn(1_000_000);

request.addCoinOutput(receiver.address, amount, baseAssetId);

// Estimate and fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: predicate,
  accountCoinQuantities: [
    {
      amount,
      assetId: baseAssetId,
      account: predicate,
      changeOutputAccount: predicate,
    },
  ],
});

const result = await predicate.simulateTransaction(assembledRequest);
```

## Transfers

### `createTransfer`

The `createTransfer` method creates a transaction request with all the necessary transfer details. It automatically estimates the transaction costs via a dry-run call and funds the request with the required predicate resources. After this, one can submit the returned transaction request with greater certainty that it will succeed.

However, please remember that you can still modify the transfer request details and use its properties before submitting it to the node.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

// Fund the predicate
const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

const receiver = Wallet.generate({ provider });
const amountToReceiver = 1000;

const transactionRequest = await predicate.createTransfer(
  receiver.address,
  amountToReceiver,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

const sendFromPredicate = await predicate.sendTransaction(transactionRequest);

await sendFromPredicate.waitForResult();
```

### `transfer`

You can send funds to another address using the `transfer` method.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ReturnTruePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const funder = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const predicate = new ReturnTruePredicate({
  provider,
});

const fundPredicate = await funder.transfer(
  predicate.address,
  100_000_000,
  baseAssetId
);
await fundPredicate.waitForResult();

const receiver = Wallet.generate({ provider });
const amountToReceiver = 1000;

const transferPredicateCoins = await predicate.transfer(
  receiver.address,
  amountToReceiver,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

await transferPredicateCoins.waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/predicates/send-and-spend-funds-from-predicates.md.md

# Send And Spend Funds From Predicates

Predicates can be used to validate transactions. This implies that a predicate can safeguard assets, only allowing their transfer if the predicate conditions are met.

This guide will demonstrate how to send and spend funds using a predicate.

## Predicate Example

Consider the following predicate:

```
predicate;

fn main(input_address: b256) -> bool {
    let valid_address = 0xfc05c23a8f7f66222377170ddcbfea9c543dff0dd2d2ba4d0478a4521423a9d4;

    input_address == valid_address
}
```

This predicate accepts an address of type `B256` and compares it with a hard-coded address of the same type. If both addresses are equal, the predicate returns true, otherwise it will return false.

## Interacting with the Predicate Using SDK

Let's use the above predicate to validate our transaction.

Once you've compiled the predicate (`forc build`), you'll obtain two important artifacts: the JSON ABI and the predicate's binary code. These are needed to instantiate a new predicate.

This is where we also pass in the predicate's data. Note that the `main` function in our predicate example requires a parameter called `input_address` of type `B256`. We will pass this parameter to the `Predicate` constructor along with the bytecode and the JSON ABI.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { SimplePredicate } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiver = Wallet.generate({ provider });

const inputAddress =
  '0xfc05c23a8f7f66222377170ddcbfea9c543dff0dd2d2ba4d0478a4521423a9d4';

const predicate = new SimplePredicate({
  provider,
  data: [inputAddress],
});
```

> Note: If you want to pass in the predicate data _after_ instantiating the `Predicate` or if you want to use a different data than the one passed in the constructor, you will have to create a new `Predicate` instance.

With the predicate instantiated, we can transfer funds to its address. This requires us to have a wallet with sufficient funds. If you're unsure about using wallets with the SDK, we recommend checking out our [wallet](../wallets/) guide.

```
// The amount of coins to send to the predicate
const amountToPredicate = 10_000_000;

// Fund the predicate with some funds from our wallet (sender)
const fundPredicateTx = await sender.transfer(
  predicate.address,
  amountToPredicate,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

// Wait for the transaction
await fundPredicateTx.waitForResult();
```

Now that our predicate holds funds, we can use it to validate a transaction and hence execute our transfer. We can achieve that by doing the following:

```
// The amount of coins to send from the predicate, to our receiver wallet.
const amountToReceiver = 200;

// Transfer funds from the predicate, to our receiver wallet
const transferFromPredicateTx = await predicate.transfer(
  receiver.address,
  amountToReceiver,
  baseAssetId
);

// Wait for the transaction
await transferFromPredicateTx.waitForResult();
```

Note the method transfer has two parameters: the recipient's address and the intended transfer amount.

Once the predicate resolves with a return value `true` based on its predefined condition, our predicate successfully spends its funds by means of a transfer to a desired wallet.

---

In a similar approach, you can use the `createTransfer` method, which returns a [`ScriptTransactionRequest`](DOCS_API_URL/classes/_fuel_ts_account.ScriptTransactionRequest.html). Then, we can submit this transaction request by calling the `sendTransaction` method.

The following example, we are pre-staging a transaction and therefore we are able to know the transaction ID without actually submitting the transaction.

```
// Create the transaction for transferring funds from the predicate.
const transactionRequest = await predicate.createTransfer(
  receiver.address,
  amountToReceiver,
  baseAssetId,
  {
    gasLimit: 1000,
  }
);

// We can obtain the transaction ID before submitting the transaction.
const chainId = await provider.getChainId();
const transactionId = transactionRequest.getTransactionId(chainId);

// We can submit the transaction and wait for the result.
const submitTransaction = await predicate.sendTransaction(transactionRequest);
await submitTransaction.waitForResult();
```

## Spending Entire Predicate Held Amount

Trying to forward the entire amount held by the predicate results in an error because no funds are left to cover the transaction fees. Attempting this will result in an error message like:

```
const errorMessage = `Insufficient funds or too many small value coins. Consider combining UTXOs.`;
```

## Predicate Validation Failure

What happens when a predicate fails to validate? Recall our predicate only validates if the `input_address` matches the hard-coded `valid_address`. Hence, if we set a different data from the `valid_address`, the predicate will fail to validate.

When a predicate fails to validate, the SDK throws an error that starts like this:

```
const errorMessage = `PredicateVerificationFailed`;
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/provider/index.md.md

# Provider

The [`Provider`](DOCS_API_URL/classes/_fuel_ts_account.Provider.html) lets you connect to a Fuel node ([_*docs*_](../getting-started/connecting-to-the-network.md)) and interact with it, encapsulating common client operations in the SDK. Those operations include querying the blockchain for network, block, and transaction-related info (and [more](DOCS_API_URL/classes/_fuel_ts_account.Provider.html)), as well as sending [transactions](../transactions/index.md) to the blockchain.

All higher-level abstractions (e.g. [`Wallet`](../wallets/index.md), [`Contract`](../contracts/index.md)) that interact with the blockchain go through the `Provider`, so it's used for various actions like getting a wallet's balance, deploying contracts, querying their state, etc.

```
import { Provider, WalletUnlocked } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// Create the provider
const provider = new Provider(LOCAL_NETWORK_URL);

// Querying the blockchain
const { consensusParameters } = await provider.getChain();

// Create a new wallet
const wallet = WalletUnlocked.generate({ provider });

// Get the balances of the wallet (this will be empty until we have assets)
const { balances } = await wallet.getBalances();
// []
```

You can find more examples of `Provider` usage [here](./querying-the-chain.md).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/provider/pagination.md.md

# Pagination

Pagination is highly efficient when dealing with large sets of data. Because of this some methods from the `Provider` class support [GraphQL cursor pagination](https://graphql.org/learn/pagination/), allowing you to efficiently navigate through data chunks.

## Pagination Arguments

The pagination arguments object is used to specify the range of data you want to retrieve. It includes the following properties:

- `after`: A cursor pointing to a position after which you want to retrieve items.
- `first`: The number of items to retrieve after the specified cursor. This is used in conjunction with the `after` argument.
- `before`: A cursor pointing to a position before which you want to retrieve items.
- `last`: The number of items to retrieve before the specified cursor. This is used in conjunction with the `before` argument.

```
const paginationArgsExample: CursorPaginationArgs = {
  after: 'cursor',
  first: 10,
  before: 'cursor',
  last: 10,
};
```

## Page Info

The `pageInfo` object is included in the GraphQL response for requests that support cursor pagination. It provides crucial metadata about the current page of results, allowing you to understand the pagination state and determine if there are more items to fetch before or after the current set.

- `endCursor`: A cursor representing the last item in the current set of results. It should be used as the `after` argument in subsequent queries to fetch the next set of items.
- `hasNextPage`: A boolean indicating whether there are more items available after the current set.
- `startCursor`: A cursor representing the first item in the current set of results. It should be used as the `before` argument in subsequent queries to fetch the previous set of items.
- `hasPreviousPage`: A boolean indicating whether there are more items available before the current set.

```
const pageInfoExample: PageInfo = {
  endCursor: 'cursor',
  hasNextPage: true,
  startCursor: 'cursor',
  hasPreviousPage: true,
};
```

## Using Pagination

One of the methods that supports pagination is the `getCoins` method. This method receives three parameters:

- `address`: The owner's account address
- `assetId`: The asset ID of the coins (optional)
- `paginationArgs`: The pagination arguments (optional)

### Basic Pagination

Here is how you can use the `getCoins` method with pagination:

```
const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

let paginationArgs: CursorPaginationArgs = {
  first: 10, // It will return only the first 10 coins
};

const { coins, pageInfo } = await provider.getCoins(
  WALLET_ADDRESS,
  baseAssetId,
  paginationArgs
);

if (pageInfo.hasNextPage) {
  paginationArgs = {
    after: pageInfo.endCursor,
    first: 10,
  };
  // The coins array will include the next 10 coins after the last one in the previous array
  await provider.getCoins(WALLET_ADDRESS, baseAssetId, paginationArgs);
}
```

### Navigating to the Previous Page

You can also use the `paginationArgs` to navigate to the previous page of results:

```
if (pageInfo.hasPreviousPage) {
  paginationArgs = {
    before: pageInfo.startCursor,
    last: 10,
  };

  // It will includes the previous 10 coins before the first one in the previous array
  await provider.getCoins(WALLET_ADDRESS, baseAssetId, paginationArgs);
}
```

## Valid Combinations

- Forward Pagination:

  Use `after` with `first` to retrieve items following a cursor.

```
const paginationArgsForward: CursorPaginationArgs = {
  after: 'cursor',
  first: 10,
};
```

- Backward Pagination:

  Use `before` with `last` to retrieve items preceding a cursor.

```
const paginationArgsBackwards: CursorPaginationArgs = {
  before: 'cursor',
  last: 10,
};
```

## Default Behavior

If neither `assetId` nor `paginationArgs` are provided, the `getCoins` method will default to the base asset ID and return the first 100 items:

```
// It will return the first 100 coins for a given wallet
await provider.getCoins(WALLET_ADDRESS);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/provider/provider-options.md.md

# Provider Options

You can provide various [options](DOCS_API_URL/types/_fuel_ts_account.ProviderOptions.html) on `Provider` instantiation to modify its behavior.

### `retryOptions`

Calls to a fuel node via the `Provider` will fail if a connection cannot be established.
Specifying retry options allows you to customize the way you want to handle that failure scenario before ultimately throwing an error.

_NOTE: retrying is only done when a connection cannot be established. If the connection is established and the node throws an error, no retry will happen._

You can provide the following settings:

- `maxRetries` - Amount of attempts to retry after initial attempt before failing the call.
- `backoff` - Strategy used to define the intervals between attempts.
  - `exponential` _(default)_: Doubles the delay with each attempt.
  - `linear` - Increases the delay linearly with each attempt.
  - `fixed`: Uses a constant delay between attempts.
- `baseDelay` _(default 150ms)_ - Base time in milliseconds for the backoff strategy.

```
new Provider(NETWORK_URL, {
  retryOptions: {
    maxRetries: 5,
    baseDelay: 100,
    backoff: 'linear',
  },
});
```

### `requestMiddleware`

Allows you to modify the request object to add additional headers, modify the request's body, and much more.

```
// synchronous request middleware
new Provider(NETWORK_URL, {
  requestMiddleware: (request: RequestInit) => {
    request.credentials = 'omit';

    return request;
  },
});

// asynchronous request middleware
new Provider(NETWORK_URL, {
  requestMiddleware: async (request: RequestInit) => {
    const credentials = await fetchSomeExternalCredentials();
    request.headers ??= {};
    (request.headers as Record<string, string>).auth = credentials;

    return request;
  },
});
```

### `timeout`

Specify the timeout in milliseconds after which every request will be aborted.

```
new Provider(NETWORK_URL, {
  timeout: 3000, // will abort if request takes 30 seconds to complete
});
```

### `fetch`

Provide a custom `fetch` function that'll replace the default fetch call.

_Note: If defined, `requestMiddleware`, `timeout` and `retryOptions` are applied to this custom `fetch` function as well._

```
new Provider(NETWORK_URL, {
  fetch: async (url: string, requestInit: RequestInit | undefined) => {
    // native fetch
    const response = await fetch(url, requestInit);

    const updatedResponse = decorateResponseWithCustomLogic(response);

    return updatedResponse;
  },
});
```

### `resourceCacheTTL`

When using the SDK, it may be necessary to submit multiple transactions from the same account in a short period. In such cases, the SDK creates and funds these transactions, then submits them to the node.

However, if a second transaction is created before the first one is processed, there is a chance of using the same resources (UTXOs or Messages) for both transactions. This happens because the resources used in the first transaction are still unspent until the transaction is fully processed.

If the second transaction attempts to use the same resources that the first transaction has already spent, it will result in one of the following error:

```console
Transaction is not inserted. Hash is already known

Transaction is not inserted. UTXO does not exist: {{utxoID}}

Transaction is not inserted. A higher priced tx {{txID}} is already spending this message: {{messageNonce}}
```

This error indicates that the resources used by the second transaction no longer exist, as the first transaction already spent them.

To prevent this issue, the SDK sets a default cache for resources to 20 seconds. This default caching mechanism ensures that resources used in a submitted transaction are not reused in subsequent transactions within the specified time. You can control the duration of this cache using the `resourceCacheTTL` flag. If you would like to disable caching, you can pass a value of `-1` to the `resourceCacheTTL` parameter.

```
new Provider(NETWORK_URL, {
  // Cache resources (Coin's and Message's) for 5 seconds
  resourceCacheTTL: 5000,
});
```

**Note:**

If you would like to submit multiple transactions without waiting for each transaction to be completed, your account must have multiple UTXOs available. If you only have one UTXO, the first transaction will spend it, and any remaining amount will be converted into a new UTXO with a different ID.

By ensuring your account has multiple UTXOs, you can effectively use the `resourceCacheTTL` flag to manage transactions without conflicts. For more information on UTXOs, refer to the [UTXOs guide](../the-utxo-model/index.md).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/provider/querying-the-chain.md.md

# Querying the Chain

Once you have set up a provider, you're ready to interact with the Fuel blockchain.

- [Connecting to the Network](../getting-started/connecting-to-the-network.md)

Let's look at a few examples below.

## `getBaseAssetId`

The base asset is the underlying asset used to perform any transaction on a chain. This should be fetched from a provider to then be used in transactions.

```
import { Address, Provider, ScriptTransactionRequest } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_ADDRESS } from '../../../../env';

// Fetch the base asset ID using the provider
const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();
// 0x...

// Instantiate our recipients address
const recipientAddress = new Address(WALLET_ADDRESS);

// Create a transaction request
const transactionRequest = new ScriptTransactionRequest();
// Use the base asset for an operation
transactionRequest.addCoinOutput(recipientAddress, 100, baseAssetId);
```

## `getCoins`

Returns UTXOs coins from an account address, optionally filtered by asset ID. This method supports [pagination](./pagination.md).

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const assetIdA =
  '0x0101010101010101010101010101010101010101010101010101010101010101';
const baseAssetId = await provider.getBaseAssetId();

// Fetches up to 100 coins that have an asset ID that is equal to the base asset ID
const { coins: coinsOnlyBaseAsset } = await provider.getCoins(
  wallet.address,
  baseAssetId
);
// [
//   { amount: bn(100), assetId: baseAssetId },
//   ...
// ]

// Fetches up to 100 coins - irrespective of the asset ID
const { coins: coinsAnyAsset } = await provider.getCoins(wallet.address);
// [
//   { amount: bn(100), assetId: baseAssetId }
//   { amount: bn(100), assetId: assetIdA }
//   ...
// ]
```

This method is also implemented on the `Account` class and can be used without providing the `address`:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const baseAssetId = await provider.getBaseAssetId();

const { coins } = await wallet.getCoins(baseAssetId);
// [
//   { amount: bn(100), assetId: baseAssetId },
//   ...
// ]
```

## `getResourcesToSpend`

Returns spendable resources (coins or messages) for a transaction request. It accepts an optional third parameter, `resourcesIdsToIgnore`, to exclude specific UTXO IDs or coin message nonces:

```
import type { CoinQuantityLike, ResourcesIdsToIgnore } from 'fuels';
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const assetIdA =
  '0x0101010101010101010101010101010101010101010101010101010101010101';

const baseAssetId = await provider.getBaseAssetId();

const quantities: CoinQuantityLike[] = [
  { amount: 32, assetId: baseAssetId, max: 42 },
  { amount: 50, assetId: assetIdA },
];

const utxoId =
  '0x00000000000000000000000000000000000000000000000000000000000000010001';
const messageNonce =
  '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0';
const excludedIds: ResourcesIdsToIgnore = {
  utxos: [utxoId],
  messages: [messageNonce],
};

const spendableResources = await provider.getResourcesToSpend(
  wallet.address,
  quantities,
  excludedIds
);

const tx = new ScriptTransactionRequest();
tx.addResources(spendableResources);
```

This method is also available in the `Account` class and can be used without providing the `address`:

```
import type { CoinQuantityLike, ResourcesIdsToIgnore } from 'fuels';
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const assetIdA =
  '0x0101010101010101010101010101010101010101010101010101010101010101';

const baseAssetId = await provider.getBaseAssetId();

const quantities: CoinQuantityLike[] = [
  { amount: 32, assetId: baseAssetId, max: 42 },
  { amount: 50, assetId: assetIdA },
];

const utxoId =
  '0x00000000000000000000000000000000000000000000000000000000000000010001';
const messageNonce =
  '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0';
const excludedIds: ResourcesIdsToIgnore = {
  utxos: [utxoId],
  messages: [messageNonce],
};

const spendableResources = await wallet.getResourcesToSpend(
  quantities,
  excludedIds
);

const tx = new ScriptTransactionRequest();
tx.addResources(spendableResources);
```

## `getBalances`

Returns the sum of all UTXOs coins and unspent message coins amounts for all assets. Unlike `getCoins`, it only returns the total amounts, not the individual coins:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const { balances } = await provider.getBalances(wallet.address);
// [
//   { amount: bn(42), assetId: baseAssetId } // total amount of baseAssetId
//   { amount: bn(100), assetId: assetIdA } // total amount of assetIdA
// ]
```

This method is also available in the `Account` class and can be used without providing the `address` parameter:

```
await wallet.getBalances();
```

## `getBlocks`

The `getBlocks` method returns blocks from the blockchain matching the given `paginationArgs` parameter, supporting [pagination](./pagination.md). The below code snippet shows how to get the last 10 blocks.

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const blockToProduce = 3;

// Force-producing some blocks to make sure that blocks exist
await provider.produceBlocks(blockToProduce);

const { blocks } = await provider.getBlocks({
  last: blockToProduce,
});
```

## `getMessageByNonce`

You can use the `getMessageByNonce` method to retrieve a message by its nonce.

```
import { launchTestNode, TestMessage } from 'fuels/test-utils';

const { provider } = await launchTestNode({
  nodeOptions: {
    snapshotConfig: {
      stateConfig: {
        messages: [
          new TestMessage({
            nonce:
              '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0',
          }).toChainMessage(),
        ],
      },
    },
  },
});

const nonce =
  '0x381de90750098776c71544527fd253412908dec3d07ce9a7367bd1ba975908a0';
const message = await provider.getMessageByNonce(nonce);
```

## `getMessages`

You can use the `getMessages` method to retrieve a list of messages from the blockchain.

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

// Instantiate a provider and wallet
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Retrieves messages from the wallet
const { messages } = await wallet.getMessages();
```

## `getMessageProof`

A message proof is a cryptographic proof that a message was included in a block. You can use the `getMessageProof` method to retrieve a message proof for a given transaction ID and message ID.

You can retrieve a message proof by either using it's block ID:

```
import type { TransactionResultMessageOutReceipt } from 'fuels';
import { sleep } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode({
  nodeOptions: {
    args: ['--poa-instant', 'false', '--poa-interval-period', '1s'],
  },
});

const {
  provider,
  wallets: [sender, recipient],
} = launched;

// Performs a withdrawal transaction from sender to recipient, thus generating a message
const withdrawTx = await sender.withdrawToBaseLayer(
  recipient.address.toB256(),
  100
);
const result = await withdrawTx.waitForResult();

// Waiting for a new block to be committed (1 confirmation block)
// Retrieves the latest block
await sleep(1500);
const latestBlock = await provider.getBlock('latest');

// Retrieves the `nonce` via message out receipt from the initial transaction result
const { nonce } = result.receipts[0] as TransactionResultMessageOutReceipt;

// Retrieves the message proof for the transaction ID and nonce using the next block Id
const messageProofFromBlockId = await provider.getMessageProof(
  result.id,
  nonce,
  latestBlock?.id
);
```

Or by it's block height:

```
import type { TransactionResultMessageOutReceipt } from 'fuels';
import { sleep } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode({
  nodeOptions: {
    args: ['--poa-instant', 'false', '--poa-interval-period', '1s'],
  },
});

const {
  provider,
  wallets: [sender, recipient],
} = launched;

// Performs a withdrawal transaction from sender to recipient, thus generating a message
const withdrawTx = await sender.withdrawToBaseLayer(
  recipient.address.toB256(),
  100
);
const result = await withdrawTx.waitForResult();

// Waiting for a new block to be committed (1 confirmation block)
// Retrieves the latest block
await sleep(1000);
const latestBlock = await provider.getBlock('latest');

// Retrieves the `nonce` via message out receipt from the initial transaction result
const { nonce } = result.receipts[0] as TransactionResultMessageOutReceipt;

// Retrieves the message proof for the transaction ID and nonce using the block height
const messageProofFromBlockHeight = await provider.getMessageProof(
  result.id,
  nonce,
  undefined,
  latestBlock?.height
);
```

## `getTransactions`

You can use the `getTransactions` method to retrieve a list of transactions from the blockchain. This is limited to 30 transactions per page.

```
import { Provider } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const { transactions } = await provider.getTransactions();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/provider/rpc-consistency.md.md

# RPC Consistency

A common issue with querying distributed networks is ensuring consistency between nodes. At any moment, each node could be at a different block height; therefore, querying the state of the blockchain may yield different results from node to node.

To defend against this, the SDK appends the block height to block-sensitive requests so the node will verify that it meets the block height criteria before processing the request.

If the node has not met the block height criteria, the request will either be awaited on the node's side (if the node supports this) or retried from the SDK side. The SDK will attempt to retry the request until it reaches the maximum number of retries and then throw an error.

This functionality is enabled by default but can be disabled as so:

```
import { Provider } from 'fuels';

Provider.ENABLE_RPC_CONSISTENCY = false;
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/scripts/configurable-constants.md.md

# Script With Configurable

In the same way as [contracts](../contracts/configurable-constants.md) and [predicates](../predicates/configurable-constants.md), Scripts also support configurable constants. This feature enables dynamic adjustment of certain values within your scripts.

Configurable constants are fairly straightforward to add and set in your scripts.

Let's consider the following script:

```
// #region encode-and-decode-1
script;

configurable {
    AMOUNT: u32 = 10,
}

fn main(inputted_amount: u32) -> u32 {
    inputted_amount + AMOUNT
}
// #endregion encode-and-decode-1
```

In this script, `AMOUNT` is a configurable constant with a default value of `10`. The main function returns the sum of the `inputted_amount` and the configurable constant `AMOUNT`.

To change the value of the `AMOUNT` constant, we can use the `setConfigurableConstants` method as shown in the following example:

```
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const script = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const configurableConstants = {
  AMOUNT: 81,
};

script.setConfigurableConstants(configurableConstants);

const inputtedValue = 10;

const { waitForResult } = await script.functions.main(inputtedValue).call();
const { value } = await waitForResult();

const expectedTotal = inputtedValue + configurableConstants.AMOUNT;
```

In this example, we're setting a new value `81` for the `AMOUNT` constant. We then call the main function with an inputted value of `10`.

The expectation is that the script will return the sum of the inputted value and the new value of `AMOUNT`.

This way, configurable constants in scripts allow for more flexibility and dynamic behavior during execution.

## Full Example

For a full example, see below:

```
import { Script, BN, Wallet, Provider } from 'fuels';

import { WALLET_PVT_KEY, LOCAL_NETWORK_URL } from '../../../env';
import { ScriptSum } from '../../../typegend/scripts/ScriptSum';

// #region script-with-configurable-contants-2
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const script = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const configurableConstants = {
  AMOUNT: 81,
};

script.setConfigurableConstants(configurableConstants);

const inputtedValue = 10;

const { waitForResult } = await script.functions.main(inputtedValue).call();
const { value } = await waitForResult();

const expectedTotal = inputtedValue + configurableConstants.AMOUNT;

// #endregion script-with-configurable-contants-2

const argument = 10;
const expected = 20;

// #region preparing-scripts
const myMainScript = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const tx = myMainScript.functions.main(argument);

// Set the call parameters
tx.callParams({ gasLimit: 7500 });

// Get the entire transaction request prior to
const txRequest = await tx.getTransactionRequest();

// Get the transaction ID
const chainId = await provider.getChainId();
const txId = txRequest.getTransactionId(chainId);

// Retrieve the value of the call and the actual gas used
const { waitForResult: waitForActualGasUsed } = await tx.call();
const { value: valueOfActualGasUsed, gasUsed: gasUsedOfActualGasUsed } =
  await waitForActualGasUsed();
// #endregion preparing-scripts
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/scripts/custom-script-call.md.md

# Preparing a Script Transaction

Akin to Contracts, we can configure the [call parameters](../contracts/call-parameters.md) and [transaction parameters](../transactions/adding-parameters.md) for Scripts, as well as retrieve the entire transaction request prior to submission.

```
const myMainScript = new Script(ScriptSum.bytecode, ScriptSum.abi, wallet);

const tx = myMainScript.functions.main(argument);

// Set the call parameters
tx.callParams({ gasLimit: 7500 });

// Get the entire transaction request prior to
const txRequest = await tx.getTransactionRequest();

// Get the transaction ID
const chainId = await provider.getChainId();
const txId = txRequest.getTransactionId(chainId);

// Retrieve the value of the call and the actual gas used
const { waitForResult: waitForActualGasUsed } = await tx.call();
const { value: valueOfActualGasUsed, gasUsed: gasUsedOfActualGasUsed } =
  await waitForActualGasUsed();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/scripts/deploying-scripts.md.md

# Deploying Scripts

In order to optimize the cost of your recurring script executions, we recommend first deploying your script. This can be done using the [Fuels CLI](../fuels-cli/index.md) and running the [deploy command](../fuels-cli/commands.md#fuels-deploy).

By deploying the script, its bytecode is stored on chain as a blob. The SDK will then produce bytecode that can load the blob on demand to execute the original script. This far reduces the repeat execution cost of the script.

## How to Deploy a Script

To deploy a script, we can use the [Fuels CLI](../fuels-cli/index.md) and execute the [deploy command](../fuels-cli/commands.md#fuels-deploy).

This will perform the following actions:

1. Compile the script using your `forc` version
1. Deploy the built script binary to the chain as a blob
1. Generate a script that loads the blob that can be used to execute the script
1. Generate types for both the script and the loader that you can use in your application

We can then utilize the above generated types like so:

```
const provider = new Provider(providerUrl);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// First, we will need to instantiate the script via it's loader bytecode. This can be imported from the typegen outputs
// that were created on `fuels deploy`
const script = new TypegenScriptLoader(wallet);

// Now we are free to interact with the script as we would normally, such as overriding the configurables
const configurable = {
  AMOUNT: 20,
};
script.setConfigurableConstants(configurable);

const { waitForResult } = await script.functions.main(10).call();
const { value, gasUsed } = await waitForResult();
console.log('value', value);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/scripts/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `
    https://docs.fuel.network/docs/sway/sway-program-types/scripts/#scripts-and-the-sdks
  `
</script>

# Scripts

A script, in Sway, is runnable bytecode on the chain which executes once to perform some task. A script can return a single value of any type.

Learn more about scripts <a :href="url" target="_blank" rel="noreferrer">here</a>.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/scripts/instantiating-a-script.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `
    https://docs.fuel.network/docs/sway/introduction/
  `
</script>

# Instantiating a script

Similar to contracts and predicates, once you've written a script in Sway and compiled it with `forc build` (read <a :href="url" target="_blank" rel="noreferrer">here</a> for more on how to work with Sway), you'll get the script binary. Using the binary, you can instantiate a `script` as shown in the code snippet below:

```
import type { BigNumberish } from 'fuels';
import { arrayify, Provider, ReceiptType, ScriptRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CallTestScript } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const script = new CallTestScript(wallet);

type MyStruct = {
  arg_one: boolean;
  arg_two: BigNumberish;
};

const scriptRequest = new ScriptRequest(
  CallTestScript.bytecode,
  (myStruct: MyStruct) => {
    const encoded = script.interface.functions.main.encodeArguments([myStruct]);

    return arrayify(encoded);
  },
  (scriptResult) => {
    if (scriptResult.returnReceipt.type === ReceiptType.Revert) {
      throw new Error('Reverted');
    }
    if (scriptResult.returnReceipt.type !== ReceiptType.ReturnData) {
      throw new Error('fail');
    }

    const [decodedResult] = script.interface.functions.main.decodeOutput(
      scriptResult.returnReceipt.data
    );
    return decodedResult;
  }
);
```

In the [next section](./running-scripts.md), we show how to run a script.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/scripts/logs.md.md

# Working with Script Logs

When you log a value within a script, you can generates a log entry that is added to the log receipt, and the variable type is recorded in the script's ABI. The SDK enables you to parse these values into TypeScript types.

## Simple

Consider the following example script:

```
script;

fn main(log_value: str[7]) -> str[7] {
    log(log_value);
    log_value
}
```

To access the logged values in TypeScript, use the `logs` property in the response of a script call.

```
import { Provider, Wallet } from 'fuels';

import { WALLET_PVT_KEY, LOCAL_NETWORK_URL } from '../../../env';
import { ScriptLogSimple } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const script = new ScriptLogSimple(wallet);
const { waitForResult } = await script.functions.main('ScriptA').call();

const { logs } = await waitForResult();
// logs: ['ScriptA']
```

## Grouped logs

Consider the following example script:

```
script;

use log_simple_abi::LogSimple;

fn main(contract_id: b256) {
    log("Script started");

    let log_contract = abi(LogSimple, contract_id);
    log_contract.log_simple(__to_str_array("ContractA"));

    log("Script finished");
}
```

### With Contract

To access the fine-grained logs for each contract, use the `groupedLogs` property from the script call response.

```
import { Provider, Wallet, ZeroBytes32 } from 'fuels';

import { WALLET_PVT_KEY, LOCAL_NETWORK_URL } from '../../../env';
import { LogSimpleFactory, ScriptLogWithContract } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// Create a contract instance
const { waitForResult: waitForDeploy } = await LogSimpleFactory.deploy(wallet);
const { contract } = await waitForDeploy();

// Create a script instance
const script = new ScriptLogWithContract(wallet);

// Call the script
const { waitForResult } = await script.functions
  .main(contract.id.toB256())
  .addContracts([contract])
  .call();

// Wait for the script to finish and get the logs
const { groupedLogs } = await waitForResult();
// groupedLogs = {
//   [ZeroBytes32]: ['Script started', 'Script finished'],
//   [contract.id.toB256()]: ['ContractA', 'ContractB'],
// }
```

Although Scripts don't have IDs/addresses, they can still call contracts and generate logs, so we use a zeroed-out (hexadecimal) address as their key instead.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/scripts/running-scripts.md.md

# Running a script

Suppose your Sway script `main` function is written using the arguments passed to the `main` function like so:

```
script;

use std::logging::log;

fn main(foo: u8) -> u8 {
    log(__to_str_array("u8 foo"));
    log(foo);
    foo
}
```

You can still hand code out a solution wrapper using `callScript` utility to call your script with data. However, if you prefer to use the ABI generated from your script, you can use the `ScriptFactory` helper:

```
import { bn, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { ScriptMainArgs } from '../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const foo = 3;

const scriptInstance = new ScriptMainArgs(wallet);

const { waitForResult } = await scriptInstance.functions.main(foo).call();

const { value, logs } = await waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/advanced-example.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Advanced Example

A more complex example showcasing genesis block state configuration with [`walletsConfig`](./test-node-options.md#walletsconfig) and deployment of multiple contracts is shown below.

```
const assets = TestAssetId.random(2);
const message = new TestMessage({ amount: 1000 });

using counterContractNode = await launchTestNode({
  walletsConfig: {
    count: 4,
    assets,
    coinsPerAsset: 2,
    amountPerCoin: 1_000_000,
    messages: [message],
  },
  contractsConfigs: [
    {
      factory: CounterFactory,
      walletIndex: 3,
      options: { storageSlots: [] },
    },
  ],
});

const {
  contracts: [counterContract],
  wallets: [wallet1, wallet2, wallet3, wallet4],
} = counterContractNode;
```

## Summary

1. All points listed in the [basic example](./basic-example.md#summary) apply here as well.
1. Multiple wallets were generated with highly-specific coins and messages.
1. It's possible to specify the wallet to be used for contract deployment via `walletIndex`.
1. The test contract can be deployed with all the options available for real contract deployment.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/basic-example.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Basic Example

Let's use `launchTestNode` with the counter contract from the [Fuel dApp tutorial](../creating-a-fuel-dapp/index.md).

_Note: you will have to change the import paths of the contract factory and bytecode to match your folder structure._

```
import { CounterFactory } from '../../../typegend/contracts/CounterFactory';

using launchedContractNode = await launchTestNode({
  contractsConfigs: [CounterFactory],
});

const {
  contracts: [contract],
  provider,
  wallets,
} = launchedContractNode;

const { waitForResult } = await contract.functions.get_count().call();
const response = await waitForResult();
```

## Summary

1.  The `launched` variable was instantiated with the [`using`](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations) keyword.
1.  `launchTestNode` spun up a short-lived `fuel-core` node, deployed a contract to it and returned it for testing.
1.  The deployed contract is fully typesafe because of `launchTestNode`'s type-level integration with `typegen` outputs.
1.  Besides the contract, you've got the [provider](../provider/index.md) and [wallets](../wallets/index.md) at your disposal.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/custom-blocks.md.md

# Custom Blocks

You can force-produce blocks using the `produceBlocks` helper to achieve an arbitrary block height. This is especially useful when you want to do some testing regarding transaction maturity.

```
import { DateTime } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode();
const { provider } = launched;
const block = await provider.getBlock('latest');
if (!block) {
  throw new Error('No latest block');
}
const { time: timeLastBlockProduced } = block;

const producedBlockHeight = await provider.produceBlocks(3);

const producedBlock = await provider.getBlock(producedBlockHeight.toNumber());

const oldest = DateTime.fromTai64(timeLastBlockProduced);
const newest = DateTime.fromTai64(producedBlock!.time);
// newest >= oldest
```

# Blocks With Custom Timestamps

You can also produce blocks with a custom block time using the `produceBlocks` helper by specifying the second optional parameter.

```
using launchedWithCustomTimestamp = await launchTestNode();
const { provider: providerWithCustomTimestamp } = launchedWithCustomTimestamp;

const latestBlock = await providerWithCustomTimestamp.getBlock('latest');
if (!latestBlock) {
  throw new Error('No latest block');
}
const latestBlockTimestamp = DateTime.fromTai64(
  latestBlock.time
).toUnixMilliseconds();
const newBlockHeight = await providerWithCustomTimestamp.produceBlocks(
  3,
  latestBlockTimestamp + 1000
);
```

# Full Example

For a full example, see the following file:
```
// #region produce-blocks
import { DateTime } from 'fuels';
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode();
const { provider } = launched;
const block = await provider.getBlock('latest');
if (!block) {
  throw new Error('No latest block');
}
const { time: timeLastBlockProduced } = block;

const producedBlockHeight = await provider.produceBlocks(3);

const producedBlock = await provider.getBlock(producedBlockHeight.toNumber());

const oldest = DateTime.fromTai64(timeLastBlockProduced);
const newest = DateTime.fromTai64(producedBlock!.time);
// newest >= oldest
// #endregion produce-blocks

// #region produceBlocks-custom-timestamp
using launchedWithCustomTimestamp = await launchTestNode();
const { provider: providerWithCustomTimestamp } = launchedWithCustomTimestamp;

const latestBlock = await providerWithCustomTimestamp.getBlock('latest');
if (!latestBlock) {
  throw new Error('No latest block');
}
const latestBlockTimestamp = DateTime.fromTai64(
  latestBlock.time
).toUnixMilliseconds();
const newBlockHeight = await providerWithCustomTimestamp.produceBlocks(
  3,
  latestBlockTimestamp + 1000
);

// #endregion produceBlocks-custom-timestamp
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/fuel-core-options.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Fuel-Core Options

The `launchTestNode` creates a temporary snapshot directory and configurations every time it runs. The path to this directory is passed to `fuel-core` via the `--snapshot` flag.

## Default Snapshot

The default snapshot used is that of the current testnet network iteration.

Click [here](https://github.com/FuelLabs/fuels-ts/tree/master/.fuel-core/configs) to see what it looks like.

## Custom Snapshot

If you need a different snapshot, you can specify a `DEFAULT_CHAIN_SNAPSHOT_DIR` environment variable which points to your snapshot directory. `launchTestNode` will read that config and work with it instead, integrating all the functionality with it the same way it'd do with the default config.

How and where you specify the environment variable depends on your testing tool.

```
process.env.DEFAULT_CHAIN_SNAPSHOT_DIR = mySnapshotDirPath;

const launchedWithCustomChainConfig = await launchTestNode();

const { provider: providerWithCustomChainConfig } =
  launchedWithCustomChainConfig;

const { name } = await providerWithCustomChainConfig.fetchChain();
```

## Fuel-Core Node Options

Besides the snapshot, you can provide arguments to the `fuel-core` node via the `nodeOptions.args` property. For a detailed list of all possible arguments run:

```shell
fuel-core run --help
```

If you want _all_ your tests to run with the same arguments, consider specifying the `DEFAULT_FUEL_CORE_ARGS` environment variable.

```
process.env.DEFAULT_FUEL_CORE_ARGS = `--tx-max-depth 20`;

// `nodeOptions.args` will override the above values if provided.

const nodeWithCustomArgs = await launchTestNode();
const { provider: providerWithCustomArgs } = nodeWithCustomArgs;

process.env.DEFAULT_FUEL_CORE_ARGS = '';
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/index.md.md

<script setup>
  import { data } from '../../versions.data'
  const { forc } = data
  const url = `https://docs.fuel.network/docs/forc/commands/forc_test/`
</script>

# Testing

This guide will teach you how to test Sway applications using the Typescript SDK.

While we use [Vitest](https://vitest.dev/) internally, we don't enforce any specific testing library or framework, so you can pick whichever you feel comfortable with.

### Not using Typescript?

See also:

1. Using [`forc test`](https://docs.fuel.network/docs/forc/commands/forc%5ftest/#forc-test)
1. Using [the Rust SDK](https://docs.fuel.network/docs/fuels-rs/testing/)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/launching-a-test-node.md.md

# Launching a Test Node

To simplify testing in isolation, we provide a utility called `launchTestNode`.

It allows you to spin up a short-lived `fuel-core` node, set up a custom provider, wallets, deploy contracts, and much more in one go.

For usage information for `launchTestNode` including it's inputs, outputs and options, please check the [API reference](DOCS_API_URL/functions/_fuel_ts_contract.test_utils.launchTestNode.html).

## Explicit Resource Management

We support [explicit resource management](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations), introduced in TypeScript 5.2, which automatically calls a `cleanup` function after a variable instantiated with the `using` keyword goes out of block scope:

```
using launched = await launchTestNode();

/*
 * The method `launched.cleanup()` will be automatically
 * called when the variable `launched` goes out of block scope.
 */
```

### Configuring Typescript

To use [explicit resource management](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations), you must:

1.  Set your TypeScript version to `5.2` or above
2.  Set the compilation target to `es2022` or below
3.  Configure your lib setting to either include `esnext` or `esnext.disposable`

```json
{
  "compilerOptions": {
    "target": "es2022",
    "lib": ["es2022", "esnext.disposable"]
  }
}
```

## Standard API

If you don't want, or can't use [explicit resource management](https://www.typescriptlang.org/docs/handbook/variable-declarations.html#using-declarations), you can use `const` as usual.

In this case, remember you must call `.cleanup()` to dispose of the node.

```
const launchedTestNode = await launchTestNode();

/*
  Do your things, run your tests, and then call
  `launchedTestNode.cleanup()` to dispose of everything.
*/

launchedTestNode.cleanup();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/setting-up-test-wallets.md.md

# Setting up test wallets

You'll often want to create one or more test wallets when testing your contracts. Here's how to do it.

## Create a single wallet

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
```

## Setting up multiple test wallets

You can set up multiple test wallets using the `launchTestNode` utility via the `walletsConfigs` option.

To understand the different configurations, check out the [walletsConfig](./test-node-options.md#walletsconfig) in the test node options guide.

```
using launched = await launchTestNode({
  walletsConfig: {
    count: 3,
    assets: [TestAssetId.A, TestAssetId.B],
    coinsPerAsset: 5,
    amountPerCoin: 100_000,
  },
});

const {
  wallets: [wallet1, wallet2, wallet3],
} = launched;
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/testing/test-node-options.md.md

# Test Node Options

This reference describes all the options of the [`launchTestNode`](./launching-a-test-node.md) utility:

- [`walletsConfig`](./test-node-options.md#walletsconfig)
- [`contractsConfigs`](./test-node-options.md#contractsconfigs)
- [`nodeOptions`](./test-node-options.md#nodeoptions)
- [`providerOptions`](./test-node-options.md#provideroptions)

```
const customLaunchTestNode = await launchTestNode(/* options */);
```

Check out the [API reference](DOCS_API_URL/interfaces/_fuel_ts_contract.test_utils.LaunchTestNodeOptions.html) for usage information on the Test Node Options.

## `walletsConfig`

Used to set the node's genesis block state (coins and messages).

- `count`: number of wallets/addresses to generate on the genesis block.
- `assets`: configure how many unique assets each wallet will own with the base asset included. Can be `number` or `TestAssetId[]`.
  - The `TestAssetId` utility simplifies testing when different assets are necessary.
- `coinsPerAsset`: number of coins (UTXOs) per asset id.
- `amountPerCoin`: for each coin, the amount it'll contain.
- `messages`: messages to assign to the wallets.

### `walletsConfig.assets`

The `TestAssetId` utility integrates with [`walletsConfig`](./test-node-options.md#walletsconfig) and gives you an easy way to generate multiple random asset ids via the `TestAssetId.random` static method.

```
const randomAssetIds = TestAssetId.random();

const nodeWithCustomAssetIds = await launchTestNode({
  walletsConfig: {
    assets: randomAssetIds,
  },
});

const {
  wallets: [walletWithCustomAssetIds],
} = nodeWithCustomAssetIds;

const { coins } = await walletWithCustomAssetIds.getCoins(
  randomAssetIds[0].value
);
```

### `walletsConfig.messages`

The `TestMessage` helper class is used to create messages for testing purposes. When passed via `walletsConfig.messages`, the `recipient` field of the message is overriden to be the wallet's address.

```
const testMessage = new TestMessage({ amount: 1000 });

const nodeWithTestMessages = await launchTestNode({
  walletsConfig: {
    messages: [testMessage],
  },
});

const {
  wallets: [walletWithTestMessages],
} = nodeWithTestMessages;

const {
  messages: [messageWithTestMessages],
} = await walletWithTestMessages.getMessages();
```

It can also be used standalone and passed into the initial state of the chain via the `TestMessage.toChainMessage` instance method.

```
const recipient = WalletUnlocked.generate();
const testMessageOnChain = new TestMessage({
  amount: 1000,
  recipient: recipient.address,
});

using launchedWithTestMessagesOnChain = await launchTestNode({
  nodeOptions: {
    snapshotConfig: {
      stateConfig: {
        messages: [testMessageOnChain.toChainMessage()],
      },
    },
  },
});

const { provider: providerWithTestMessagesOnChain } =
  launchedWithTestMessagesOnChain;

recipient.provider = providerWithTestMessagesOnChain;

const {
  messages: [messageOnChain],
} = await recipient.getMessages();
```

## `contractsConfigs`

Used to deploy contracts on the node the `launchTestNode` utility launches. It's an array of objects with the following properties:

- `factory`: contract factory class outputted by `pnpm fuels typegen`.
- `walletIndex`: the index of the wallets generated by [`walletsConfig`](./test-node-options.md#walletsconfig) that you want to deploy the contract with.
- `options`: options for [contract deployment](../contracts/deploying-contracts.md#2-contract-deployment) that get passed to the [`ContractFactory.deploy`](DOCS_API_URL/classes/_fuel_ts_contract.index.ContractFactory.html#deploy) method.

## `nodeOptions`

<!-- TODO: will cross-reference work done in [#1915](https://github.com/FuelLabs/fuels-ts/issues/1915) -->

Options to modify the behavior of the node.

For example, you can specify your own base asset id of the chain like below:

```
const [baseAssetId] = TestAssetId.random();

const nodeWithCustomBaseAssetId = await launchTestNode({
  nodeOptions: {
    snapshotConfig: {
      chainConfig: {
        consensus_parameters: {
          V2: {
            base_asset_id: baseAssetId.value,
          },
        },
      },
    },
  },
});
```

_Note: The API for these options is still not fully complete and better documentation will come in the future._

## `providerOptions`

Provider options passed on `Provider` instantiation. More on them [here](../provider/provider-options.md).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/the-utxo-model/index.md.md

# The UTXO Model

In UTXO (Unspent Transaction Output) based systems, each coin is unique, similar to how physical currency bills have different denominations.

A UTXO represents a coin with a specific amount, similar to having a $10 or $5 bill. It's crucial to understand this unique feature of UTXOs, as it differs significantly from Ethereum's account-based system.

In Ethereum, balances are tracked as cumulative totals, similar to a bank account, rather than as distinct 'coins' or 'bills'.

## Why UTXOs Matter

Each UTXO corresponds to a unique coin and has an associated amount. This model allows for greater transparency and control in cryptocurrency transactions. Understanding UTXOs is key for effectively managing and tracking your digital assets.

## How UTXOs Work

When you create a transaction, you will use UTXOs from your account to fund it. Here's a step-by-step explanation:

`1. Selecting UTXOs`: The SDK selects one or more UTXOs from your account that together are equal to or greater than the transaction amount plus the transaction fee.

`2. Spending UTXOs`: These selected UTXOs are used to fund the transaction and cover the transaction fee. For example, if you need to send $15 and the transaction fee is $1, and you have $10 and $6 UTXOs, both will be used.

`3. New UTXOs`: If the total value of the selected UTXOs exceeds the transaction amount plus the transaction fee, the difference is returned to your account as new UTXOs. For instance, if you spend a $20 UTXO for a $15 transaction with a $1 fee, a new UTXO worth $4 will be created as change and added back to your account.

In summary, the original UTXOs used in the transaction are marked as spent and cannot be used again. The new UTXOs are available for future transactions.

Suppose you have the following UTXOs in your account:

- $10 UTXO
- $20 UTXO

You want to send $15 to someone, and the transaction fee is $1. Here's what happens:

- The $20 UTXO is selected to fund the $15 transaction and cover the $1 fee.
- The transaction is completed and the $20 UTXO is spent.
- A new $15 UTXO is generated to the recipient, and a new $4 UTXO (change) is created and added to your account.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/adding-parameters.md.md

# Adding Parameters

Transaction parameters allow you to configure various aspects of your blockchain transactions. Dependent on these parameters, it may introduce a [transaction policy](./adding-policies.md).

All available parameters are shown below:

```
const txParams: TxParams = {
  // #region transaction-parameters-1
  gasLimit: bn(70935),
  // #endregion transaction-parameters-1
  // #region transaction-parameters-2
  maxFee: bn(69242),
  // #endregion transaction-parameters-2
  // #region transaction-parameters-3
  tip: bn(100),
  // #endregion transaction-parameters-3
  // #region transaction-parameters-4
  maturity: 1,
  // #endregion transaction-parameters-4
  // #region transaction-parameters-5
  witnessLimit: bn(5000),
  // #endregion transaction-parameters-5
  // #region transaction-parameters-6
  expiration: 200,
  // #endregion transaction-parameters-6
};
```

## Gas Limit

The maximum amount of gas you're willing to allow the transaction to consume. If the transaction requires more gas than this limit, it will fail.

```
  gasLimit: bn(70935),
```

## Max Fee

The maximum amount you're willing to pay for the transaction using the base asset. This allows users to set an upper limit on the transaction fee they are willing to pay, preventing unexpected high costs due to sudden network congestion or fee spikes.

```
  maxFee: bn(69242),
```

## Tip

An optional amount of the base asset to incentivise the block producer to include the transaction, ensuring faster processing for those willing to pay more. The value set here will be added to the transaction `maxFee`.

```
  tip: bn(100),
```

## Maturity

The number of blocks that must pass before the transaction can be included in a block. This is useful for time-sensitive transactions, such as those involving time-locked assets.

For example, if the chain produces a new block every second, setting Maturity to `10` means the transaction will be processed after approximately 10 seconds.

```
  maturity: 1,
```

## Witness Limit

The maximum byte length allowed for the transaction witnesses array. For instance, imagine a transaction that will deploy a contract. The contract bytecode will be one of the entries in the transaction witnesses. If you set this limit to `5000` and the contract bytecode length is `6000`, the transaction will be rejected because the witnesses bytes length exceeds the maximum value set.

```
  witnessLimit: bn(5000),
```

## Expiration

The block number after which the transaction can no longer be included in the blockchain. For example, if you set the expiration block for your transaction to 200, and the transaction remains in the queue waiting to be processed when block 200 is created, the transaction will be rejected.

```
  expiration: 200,
```

## Variable Outputs

The number of variable outputs that should be added to the transaction request. You can read more about it on this [guide](../contracts/variable-outputs.md)

> **Note**: Setting transaction parameters is optional. If you don't specify them, the SDK will fetch some sensible defaults from the chain.

## Setting Transaction Parameters

To set the transaction parameters, you have access to the `txParams` method on a transaction request.

```
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  gasLimit: 100,
});
```

The same method is also accessible within a function invocation scope, so it can also be used when calling contract functions.

```
const { waitForResult } = await contract.functions
  .increment_count(15) //
  .txParams(txParams)
  .call();

const {
  value,
  transactionResult: { isStatusSuccess },
} = await waitForResult();

console.log('Transaction request', transactionRequest);
console.log('Transaction status', isStatusSuccess);
console.log('Transaction value', value);
```

> **Note:** When performing an action that results in a transaction (e.g. contract deployment, contract call with `.call()`, asset transfer), the SDK will automatically estimate the fee based on the gas limit and the transaction's byte size. This estimation is used when building the transaction. As a side effect, your wallet must own at least one coin of the base asset, regardless of the amount.

## Full Example

Here is the full example of the transaction parameters:

```
import type { TxParams } from 'fuels';
import { bn, Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { CounterFactory } from '../../../typegend';
import { ScriptSum } from '../../../typegend/scripts';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploy = await CounterFactory.deploy(wallet);

const { contract } = await deploy.waitForResult();

// #region transaction-parameters-7
const txParams: TxParams = {
  // #region transaction-parameters-1
  gasLimit: bn(70935),
  // #endregion transaction-parameters-1
  // #region transaction-parameters-2
  maxFee: bn(69242),
  // #endregion transaction-parameters-2
  // #region transaction-parameters-3
  tip: bn(100),
  // #endregion transaction-parameters-3
  // #region transaction-parameters-4
  maturity: 1,
  // #endregion transaction-parameters-4
  // #region transaction-parameters-5
  witnessLimit: bn(5000),
  // #endregion transaction-parameters-5
  // #region transaction-parameters-6
  expiration: 200,
  // #endregion transaction-parameters-6
};
// #endregion transaction-parameters-7

// #region transaction-parameters-8
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  gasLimit: 100,
});
// #endregion transaction-parameters-8

// #region transaction-parameters-9
const { waitForResult } = await contract.functions
  .increment_count(15) //
  .txParams(txParams)
  .call();

const {
  value,
  transactionResult: { isStatusSuccess },
} = await waitForResult();

console.log('Transaction request', transactionRequest);
console.log('Transaction status', isStatusSuccess);
console.log('Transaction value', value);

// #endregion transaction-parameters-9
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/adding-policies.md.md

# Adding Policies

Transaction policies are rules that can govern how a transaction is processed, introduced by the [transaction parameters](./adding-parameters.md) that you pass to a transaction request. The available policies are as follows:

### Tip

Optional amount on the base asset to incentivise block producer to include transaction, ensuring faster processing for those willing to pay more. The value set here will be added to the transaction `maxFee`.

### Witness Limit

The maximum byte length allowed for the transaction witnesses array.

### Maturity

The number of blocks that must pass before the transaction can be included in a block.

### Max Fee

The maximum amount you're willing to pay for the transaction using the base asset.

### Expiration

Block number after which the transaction can no longer be included in the blockchain.

## Setting Transaction Policies

The following snippet shows which transaction parameters correspond to which policies:

```
import { bn, ScriptTransactionRequest } from 'fuels';

const transactionRequest = new ScriptTransactionRequest({
  tip: bn(10), // Sets the tip policy
  witnessLimit: bn(1), // Sets the witness limit policy
  maturity: 1, // Sets the maturity policy
  maxFee: bn(1), // Sets the max fee policy
  expiration: 200, // Sets the block after which the transaction cannot be included.
});
```

## Retrieving Transaction Policies from a Transaction

Policies used for a transaction can be retrieved from a transaction using a `TransactionResponse`. The below snippet will show how to retrieve the policies from a transaction:

```
import type { Policy } from 'fuels';
import { Provider, Wallet, ScriptTransactionRequest, bn } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { ScriptSum } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

/**
 * Instantiate the transaction request with transaction parameters
 * that will set the respective policies.
 */
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  gasLimit: bn(2000),
  tip: bn(10),
  witnessLimit: 900,
  maxFee: bn(2000),
  expiration: 200,
});

// Set the script main function arguments
const scriptArguments = [1];
transactionRequest.setData(ScriptSum.abi, scriptArguments);

// Fund the transaction
const resources = await wallet.getResourcesToSpend([
  { amount: 1000, assetId: await provider.getBaseAssetId() },
]);

transactionRequest.addResources(resources);

// Submit the transaction and retrieve the transaction response
const tx = await wallet.sendTransaction(transactionRequest);
const response = await tx.waitForResult();
const policies: Policy[] | undefined = response.transaction.policies;

console.log('policies', policies);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/assemble-tx-migration-guide.md.md

# AssembleTx Migrating Guide

The old methods of estimating and funding transaction were deprecated in favor of a more robust `provider.assembleTx`. This guide will help you migrate your code to use the new method.

## Migrating From `getTransactionCost` and `fund`

### Old Approach (Deprecated)

```
const transferAmount = 100;

const request = new ScriptTransactionRequest();

// Add a coin output to transfer 100 base asset to account
request.addCoinOutput(accountB.address, transferAmount, baseAssetId);

const txCost = await accountA.getTransactionCost(request);

request.maxFee = txCost.maxFee;
request.gasLimit = txCost.gasUsed;

await accountA.fund(request, txCost);

const tx = await accountA.sendTransaction(request);
const { isStatusSuccess } = await tx.waitForResult();
```

### New Approach

```
const transferAmount = 100;

const request = new ScriptTransactionRequest();
request.addCoinOutput(accountB.address, transferAmount, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: accountA,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: baseAssetId,
      account: accountA,
      changeOutputAccount: accountA,
    },
  ],
});

const tx = await accountA.sendTransaction(assembledRequest);
const { isStatusSuccess } = await tx.waitForResult();
```

### More Complex Transactions

Consider the following Sway script

```
script;

use std::asset::transfer;

fn main(
    contract_address: b256,
    asset_a: AssetId,
    amount_asset_a: u64,
    asset_b: AssetId,
    amount_asset_b: u64,
) -> bool {
    let wrapped_contract = ContractId::from(contract_address);
    let contract_id = Identity::ContractId(wrapped_contract);
    transfer(contract_id, asset_a, amount_asset_a);
    transfer(contract_id, asset_b, amount_asset_b);
    true
}
```

This script transfers two asset amounts to the same contract address. To ensure the transaction succeeds, it must be properly funded with the required amounts. This means we need to explicitly define how the transaction should be funded.

### Old Approach (Deprecated)

```
const transferAmountA = 400;
const transferAmountB = 600;

const script = new ScriptTransferToContract(account);

const request = await script.functions
  .main(
    contractId,
    { bits: TestAssetId.A.value },
    transferAmountA,
    { bits: TestAssetId.B.value },
    transferAmountB
  )
  .addContracts([contract])
  .getTransactionRequest();

const txCost = await account.getTransactionCost(request, {
  quantities: [
    {
      amount: bn(transferAmountA),
      assetId: TestAssetId.A.value,
    },
    {
      amount: bn(transferAmountB),
      assetId: TestAssetId.B.value,
    },
  ],
});

request.maxFee = txCost.maxFee;
request.gasLimit = txCost.gasUsed;

await account.fund(request, txCost);

const tx = await account.sendTransaction(request);
const { isStatusSuccess } = await tx.waitForResult();
```

### New Approach

```
const transferAmountA = 400;
const transferAmountB = 600;

const script = new ScriptTransferToContract(account);

const scope = script.functions
  .main(
    contractId,
    { bits: TestAssetId.A.value },
    transferAmountA,
    { bits: TestAssetId.B.value },
    transferAmountB
  )
  .assembleTxParams({
    feePayerAccount: account,
    accountCoinQuantities: [
      {
        amount: transferAmountA,
        assetId: TestAssetId.A.value,
        account,
        changeOutputAccount: account,
      },
      {
        amount: transferAmountB,
        assetId: TestAssetId.B.value,
        account,
        changeOutputAccount: account,
      },
    ],
  });

const { waitForResult } = await scope.call();

const {
  transactionResult: { isStatusSuccess },
} = await waitForResult();
```

By specifying which parameters `assembleTx` should use, we gain control over how the script call is estimated and funded.

## Migrating from `estimateAndFund`

### Old Code

```
const request = new ScriptTransactionRequest();

// Add a coin output to transfer 100 base asset to accountB
request.addCoinOutput(accountB.address, 100, baseAssetId);

// Estimate and fund the request
await request.estimateAndFund(accountA);

// Send the transaction
const tx = await accountA.sendTransaction(request);
await tx.waitForResult();
```

### New Code

```
const request = new ScriptTransactionRequest();

// Add a coin output to transfer 100 base asset to accountB
request.addCoinOutput(accountB.address, 100, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: accountA,
  accountCoinQuantities: [
    {
      amount: 100,
      assetId: baseAssetId,
      account: accountA,
      changeOutputAccount: accountA,
    },
  ],
});

const tx = await accountA.sendTransaction(assembledRequest);
await tx.waitForResult();
```

### Key Differences

1. **More Explicit Control**: `assembleTx` provides clearer control over which account pays fees and which accounts provide resources.

2. **Better Resource Management**: The new method allows you to specify exactly which accounts should provide which quantities of assets.

3. **Controlling Change Output**: When informing each account coin quantity you have control over determining who is going to receive a the change for that specific asset ID.

## Notes

- The methods `getTransactionCost` and `estimateAndFund` are deprecated and are going to be removed on futures updates
- The new method provides more predictable transaction assembly

## Additional Options

The new `assembleTx` method provides several additional options:

```
export type AssembleTxParams<T extends TransactionRequest = TransactionRequest> = {
  // The transaction request to assemble
  request: T;
  // Coin quantities required for the transaction, optional if transaction only needs funds for the fee
  accountCoinQuantities?: AccountCoinQuantity[];
  // Account that will pay for the transaction fees
  feePayerAccount: Account;
  // Block horizon for gas price estimation (default: 10)
  blockHorizon?: number;
  // Whether to estimate predicates (default: true)
  estimatePredicates?: boolean;
  // Resources to be ignored when funding the transaction (optional)
  resourcesIdsToIgnore?: ResourcesIdsToIgnore;
  // Amount of gas to reserve (optional)
  reserveGas?: BigNumberish;
};

export type AssembleTxResponse<T extends TransactionRequest = TransactionRequest> = {
  assembledRequest: T;
  gasPrice: BN;
  receipts: TransactionResultReceipt[];
  rawReceipts: TransactionReceiptJson[];
};
```

You can read more about the `assembleTx` [here](./index.md).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/assemble-tx.md.md

# AssembleTx

The `assembleTx` method is a crucial part of the Fuel TypeScript SDK that helps prepare and assemble transactions with the correct inputs, outputs, and policies. It is used by all higher-level APIs in the SDK, including account transfers, contract and blob deployments, and contract calls. This guide provides a comprehensive overview of how to use `assembleTx` effectively.

## Overview

The `assembleTx` method takes a transaction request and assembles it with the necessary inputs, outputs, and policies based on the provided parameters. It handles:

- Coin quantity for different assets
- Fee payer account
- Gas and fee estimation
- Predicate estimation
- Resource exclusion (specific resources to ignore)

## Parameters

The [AssembleTxParams](DOCS_API_URL/types/_fuel_ts_account.AssembleTxParams.html) interface includes the following parameters:

```
export type AssembleTxParams<T extends TransactionRequest = TransactionRequest> = {
  // The transaction request to assemble
  request: T;
  // Coin quantities required for the transaction, optional if transaction only needs funds for the fee
  accountCoinQuantities?: AccountCoinQuantity[];
  // Account that will pay for the transaction fees
  feePayerAccount: Account;
  // Block horizon for gas price estimation (default: 10)
  blockHorizon?: number;
  // Whether to estimate predicates (default: true)
  estimatePredicates?: boolean;
  // Resources to be ignored when funding the transaction (optional)
  resourcesIdsToIgnore?: ResourcesIdsToIgnore;
  // Amount of gas to reserve (optional)
  reserveGas?: BigNumberish;
};

export type AssembleTxResponse<T extends TransactionRequest = TransactionRequest> = {
  assembledRequest: T;
  gasPrice: BN;
  receipts: TransactionResultReceipt[];
  rawReceipts: TransactionReceiptJson[];
};
```

### Parameter Details

- `request`: The transaction request to be assembled.
- `blockHorizon`: The number of blocks to look ahead for gas price estimation. Defaults to `10` blocks.
- `feePayerAccount`: The account that will pay for the transaction fees
- `accountCoinQuantities`: An array of coin quantities needed for the transaction. This is optional if the transaction only requires funds to cover the fee. The parameters are:
  - `amount`: The amount of coins needed (fee value does need to be included)
  - `assetId`: The asset ID of the coins
  - `account`: The account providing the coins (optional, defaults to `feePayerAccount`)
  - `changeOutputAccount`: The account to receive change (optional, defaults to the `account` or `feePayerAccount` properties, respectively)
- `resourcesIdsToIgnore`: Resources to be ignored when funding the transaction (UTXOs or messages)
- `estimatePredicates`: Whether to estimate gas for predicates
- `reserveGas`: Additional Amount of gas to be set for the transaction

### Default Behaviors for Account Properties

The `accountCoinQuantities` entries have two optional properties with specific default behaviors:

1. `account` property:

   - If not provided, defaults to the root `feePayerAccount`
   - Used to specify which account provides the resources for the transaction

2. `changeOutputAccount` property:
   - If not provided, defaults to the `account` property
   - Used to specify which account receives the change from all spent resources from a specific `assetId`

Example of default behaviors:

```
import { Provider, Wallet, type AccountCoinQuantity } from 'fuels';
import { TestAssetId } from 'fuels/test-utils';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
  WALLET_PVT_KEY_3,
} from '../../../../env';

// #region transaction-request-3
const provider = new Provider(LOCAL_NETWORK_URL);
const accountA = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const accountB = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);
const accountC = Wallet.fromPrivateKey(WALLET_PVT_KEY_3, provider);
const baseAssetId = await provider.getBaseAssetId();
const accountCoinQuantities: AccountCoinQuantity[] = [
  {
    amount: 100,
    assetId: baseAssetId,
    // account defaults to feePayerAccount
    // changeOutputAccount defaults to feePayerAccount
  },
  {
    amount: 200,
    assetId: TestAssetId.A.value,
    account: accountA,
    // changeOutputAccount defaults to accountA
  },
  {
    amount: 300,
    assetId: TestAssetId.B.value,
    account: accountB,
    changeOutputAccount: accountC,
    // Both account and changeOutputAccount are explicitly set
  },
];
```

## Return Value

The method returns an object of the type [AssembleTxResponse](DOCS_API_URL/types/_fuel_ts_account.AssembleTxResponse.html):

- `assembledRequest`: The fully assembled transaction request with all necessary inputs, outputs, and policies
- `gasPrice`: The estimated gas price for the transaction
- `receipts`: Parsed receipts returned from the transaction dry run.
- `rawReceipts`: Unparsed receipts returned from the transaction dry run.

## Usage Example

```
const request = new ScriptTransactionRequest();

request.addCoinOutput(accountB.address, transferAmount, baseAssetId);

const accountCoinQuantities: AccountCoinQuantity[] = [
  {
    amount: transferAmount,
    assetId: baseAssetId, // Asset ID
    account: accountA,
    changeOutputAccount: accountA, // Optional
  },
];

// Assemble the transaction
const { assembledRequest, gasPrice, receipts } = await provider.assembleTx({
  request,
  accountCoinQuantities,
  feePayerAccount: accountA,
  blockHorizon: 10,
  estimatePredicates: true,
});

// The assembledRequest is now ready to be signed and sent
const submit = await accountA.sendTransaction(assembledRequest);
await submit.waitForResult();
```

## Attention to `account` and `changeOutputAccount` Fields

As mentioned earlier, the `account` and `changeOutputAccount` fields are optional in the `accountCoinQuantities` entries. However, **special attention must be paid to** `changeOutputAccount` due to how change from spent resources works on Fuel.

In Fuel, only one `OutputChange` is allowed per `assetId` in a transaction. But what exactly is an `OutputChange`? In simple terms, it designates the recipient of the leftover funds ("change") after all UTXO resources for a specific `assetId` have been spent.

### Understanding Change in Fuel's UTXO Model

Because Fuel uses a **UTXO-based model** (unlike Ethereum’s account-based model), transactions will spend all included UTXOs, even if only a small portion is actually required. For example, suppose you have a single UTXO worth 10 ETH. If you create a transaction to send just 1 Gwei, the entire 10 ETH UTXO will be consumed. The transaction will then:

- Create a UTXO with 1 Gwei to the recipient.
- Create another UTXO for the remaining amount (i.e., 10 ETH - 1 Gwei - fee), sent to the address defined in the `OutputChange`.

In this context, the `OutputChange` ensures that **you receive the change** from your transaction.

### Fuel's Constraint: One Change Output per `assetId`

A key rule in Fuel is that only one `OutputChange` per `assetId` is allowed per transaction. This becomes particularly important when a transaction includes resources from **multiple accounts** that hold the same `assetId` (e.g., ETH). In such a case, **only one account can receive the change**, whichever one is defined on the `OutputChange`.

If not managed correctly, this can lead to unintended behavior, such as one account spending its funds while another receives the leftover balance.

### How This Relates to `assembleTx`

The `changeOutputAccount` field in `assembleTx` explicitly specifies **which account should receive the change** for a particular `assetId`. This is critical when you're using resources from multiple accounts in the same transaction.

Here's an example:

```
let { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: accountA,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: baseAssetId,
      account: accountB,
      /**
       * accountB will receive the change. Although it is explicitly set here,
       * if it were not set, it would default to the account property,
       * which in this case is also accountB.
       */
      changeOutputAccount: accountB,
    },
  ],
});
```

In the example above:

- Resources from `accountB` are being explicitly requested in `accountCoinQuantities`.
- `accountA` is listed as the `feePayerAccount`, meaning it will also contribute resources to cover fees.
- `changeOutputAccount` is explicitly set to `accountB`.

As a result, `accountB` will receive the change, even if UTXOs from `accountA` are spent in the transaction.

This means that if `accountA` contributes a 10 ETH UTXO, the transaction will spend the full 10 ETH. The leftover amount (change) will be sent to `accountB`, not back to `accountA`, because `changeOutputAccount`is set to `accountB`.

## Best Practices

1. Always provide the correct `feePayerAccount` that has sufficient funds for the transaction fees
2. Pay special attention to change outputs when dealing with multiple accounts and the same asset ID:
   - In Fuel, only one change output is allowed per asset ID
   - If a transaction includes resources from the same asset ID for multiple accounts, only one account will receive the change from all spent resources
   - Make sure to coordinate with all parties involved to determine which account should receive the change output

## Notes

- The method automatically handles base asset requirements for fees
- It performs a dry run to validate the transaction before returning
- The assembled transaction will include all necessary inputs and outputs based on the provided coin quantities
- Gas and fee estimation is performed using the specified block horizon


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/getting-the-response.md.md

# Transaction Response

Once a transaction has been submitted, you may want to extract information regarding the result of the transaction. The SDK offers a `TransactionResponse` class with helper methods to expose the following information:

- The transaction ID
- The status (submitted, success, squeezed out, or failure)
- Receipts (return data, logs, mints/burns, transfers and panic/reverts)
- Operations (contract calls, transfers, withdrawals)
- Gas fees and usages
- Date and time of the transaction
- The block the transaction was included in

We can easily extract this information from a contract call:

```
// Call a contract function
const call = await contract.functions.increment_count(15).call();

// Wait for the result
const { transactionResponse } = await call.waitForResult();

// Retrieve the full transaction summary
const transactionSummary = await transactionResponse.getTransactionSummary({
  // Pass a Contract ID and ABI map to generate the contract operations
  [contract.id.toB256()]: Counter.abi,
});
```

We can also use the result of a transaction request to extract a transaction summary:

```
/**
 * Instantiate the transaction request using a ScriptTransactionRequest and
 * set the script main function arguments
 */
const request = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

request.setData(ScriptSum.abi, [1]);

// Estimate and funding the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: 1000,
      assetId: await provider.getBaseAssetId(),
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

// Submit the transaction
const response = await wallet.sendTransaction(assembledRequest);

// Generate the transaction summary
const transactionSummary = await response.getTransactionSummary();
```

Or we can build a transaction summary from a stored transaction ID:

```
// Take a transaction ID from a previous transaction
const transactionId = previouslySubmittedTransactionId;
// 0x...

// Retrieve the transaction response from the transaction ID
const transactionResponse = await TransactionResponse.create(
  transactionId,
  provider
);

// Generate the transaction summary
const summary = await transactionResponse.getTransactionSummary();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/index.md.md

# Transactions

A transaction is a way of interacting with a Fuel blockchain and can include actions like transferring assets, deploying contracts and minting tokens. All of which are possible through the SDK by using simple utility methods or building out more custom transactions.

Transferring assets is the most common transaction type and can be be executed by calling the `transfer` function from an account to a recipient address:

```
const tx = await sender.transfer(receiver.address, 100, assetId);
await tx.waitForResult();

const newBalance = await receiver.getBalance(assetId);
// 100
```

Deploying and interacting with contracts are other common transactions. More information on this can be found in the [contracts guide](../contracts/index.md), either through the [contract deployment guide](../contracts/deploying-contracts.md) or the [contract interaction guide](../contracts/methods.md).

This guide will discuss how to create and modify transactions to fit bespoke use cases, as well as submit them to the network using transactional policies and parameters. As well as retrieving information about submitted transactions.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/modifying-the-request.md.md

# Transaction Request

A transaction request provides the foundations for submitting a transaction and interacting with the blockchain.

Within Fuel, we have the following transaction types:

- Script
- Create
- Mint

The SDK provides class helpers for handling script and create transactions: `ScriptTransactionRequest` and `CreateTransactionRequest`, respectively.

> **Note**: Mint transactions can only be created by the block producer and do not have any use outside of block creation. Therefore, the SDK only provides the ability to decode them.

## Creating a Transaction Request

To create a transaction request, you must first instantiate either a `ScriptTransactionRequest` or `CreateTransactionRequest`.

A `ScriptTransactionRequest` is used for script transactions, which allows you to execute bytecode on chain to perform a task or chain of tasks. Within the SDK they can be created like so:

```
import {
  CreateTransactionRequest,
  ScriptTransactionRequest,
  ZeroBytes32,
} from 'fuels';

import { ScriptSum } from '../../../../typegend';

// Instantiate the transaction request using a ScriptTransactionRequest
const scriptTransactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const scriptData = [1];

// Set the script main function arguments (can also be passed in the class constructor)
scriptTransactionRequest.setData(ScriptSum.abi, scriptData);
```

A `CreateTransactionRequest` is used for create transactions, which are transactions that create a new contract on the blockchain.

```
// Instantiate the transaction request using a CreateTransactionRequest
const createTransactionRequest = new CreateTransactionRequest({
  witnesses: [contractByteCode],
});
```

> **Note**: We recommend you use the `ContractFactory` for contract deployment as this will shape the create transaction request for you. Information on this can be found in the [contract deployment guide](../contracts/deploying-contracts.md#2-contract-deployment).

## Modifying a Transaction Request

Once you have instantiated a transaction request, you can modify it by setting the transaction parameters and policies. This can either be done manually by directly altering the transaction request object, or through helper methods that are available on the above classes.

### Adding `OutputCoin`

Including `OutputCoin`s in the transaction request specifies the UTXOs that will be created once the transaction is processed. These UTXOs represent the amounts being transferred to specified account addresses during the transaction:

```
const provider = new Provider(LOCAL_NETWORK_URL);

const recipient1 = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient2 = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const baseAssetId = await provider.getBaseAssetId();
const assetA = TestAssetId.A.value;

const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

transactionRequest.addCoinOutput(recipient1.address, 1000, baseAssetId);
transactionRequest.addCoinOutput(recipient2.address, 500, assetA);
```

### Estimating and Funding the Transaction Request

Before submitting a transaction, ensure it is fully funded to meet its requirements and cover the associated fees. The `assembleTx` method handles this by returning a fully funded and estimated transaction, ready for submission.

```
const transferAmount = 1000;

const request = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const baseAssetId = await provider.getBaseAssetId();

request.addCoinOutput(wallet.address, transferAmount, baseAssetId);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: wallet,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: baseAssetId,
      account: wallet,
      changeOutputAccount: wallet,
    },
  ],
});

await wallet.sendTransaction(assembledRequest);
```

### Manually Fetching Resources

In certain scenarios, you may need to manually fetch resources. This can be achieved using the `getResourcesToSpend` method, which accepts an array of `CoinQuantities` and returns the necessary resources to meet the specified amounts:

```
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const baseAssetId = await provider.getBaseAssetId();
const assetA = TestAssetId.A.value;

// Define the quantities to fetch
const quantities: CoinQuantity[] = [
  {
    amount: bn(10000),
    assetId: baseAssetId,
  },
  {
    amount: bn(100),
    assetId: assetA,
  },
];

// Fetching resources
const resources = await wallet.getResourcesToSpend(quantities);

// Adding resources (coins or messages)
transactionRequest.addResources(resources);
```

#### Manually Fetching Coins or Messages

If needed, you can manually include specific coins or messages in the transaction. However, this approach is generally discouraged and should only be used in scenarios where explicitly adding particular coins or messages to the transaction request is required:

```
// Fetching coins
const { coins } = await wallet.getCoins(baseAssetId);
const { messages } = await wallet.getMessages();

// Adding a specific coin or message
transactionRequest.addCoinInput(coins[0]);
transactionRequest.addMessageInput(messages[0]);
```

### Adding a Contract Input and Output to a Transaction Request

Imagine that you have a Sway script that manually calls a contract:

```
use counter::CounterAbi;
fn main(contract_id: ContractId) -> u64 {
    let counter_contract = abi(CounterAbi, contract_id.into());
    counter_contract.get_count()
}
```

In those cases, you will need to add both an `InputContract` and `OutputContract` to the transaction request:

```
const deploy = await CounterFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
  scriptData: contract.id.toB256(),
});

// Add the contract input and output using the contract ID
transactionRequest.addContractInputAndOutput(contract.id);
```

### Adding a Predicate to a Transaction Request

Predicates are used to define the conditions under which a transaction can be executed. Therefore you may want to add a predicate to a transaction request to unlock funds that are utilized by a script. This can be added like so:

```
// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

const predicateArguments = [ZeroBytes32];

/**
 * Instantiate the predicate and pass valid input data to validate
 * the predicate and unlock the funds
 */
const predicate = new Predicate({
  bytecode: SimplePredicate.bytecode,
  abi: SimplePredicate.abi,
  data: predicateArguments,
  provider,
});

// Fund the predicate
const tx = await wallet.transfer(predicate.address, bn(100_000));
await tx.waitForResult();

const predicateCoins = await predicate.getResourcesToSpend([
  { amount: 2000, assetId: await provider.getBaseAssetId() },
]);

// Add the predicate input and resources
transactionRequest.addResources(predicateCoins);
```

> **Note**: For more information on predicates, including information on configuring them, funding them and using them to unlock funds, please refer to the [predicate guide](../predicates/index.md).

### Adding a Witness and Signing a Transaction Request

The SDK provides a way of either modifying the witnesses for a transaction request directly, or by passing accounts. This will then sign the transaction request with the account's private key. Below will detail how to add a witness to a transaction request:

```
const provider = new Provider(LOCAL_NETWORK_URL);
const accountA = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const accountB = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const transactionRequest = new ScriptTransactionRequest({
  script: ScriptSum.bytecode,
});

// Add a witness directly
// Add a witness signature directly
const signature = await accountA.signTransaction(transactionRequest);
transactionRequest.addWitness(signature);

// Or add multiple via `addAccountWitnesses`
await transactionRequest.addAccountWitnesses([accountB]);
```

A more complex example would when signatures are validated inside the script itself, like this guide [here](../cookbook/sway-script-with-signature-validation.md), .

> **Note**: Once `addAccountWitnesses` has been called, any additional modifications to the transaction request will invalidate the signature as the transaction ID changes. Therefore, it is recommended to add witnesses last.

### Getting the Transaction ID for a Transaction Request

The transaction ID is a SHA-256 hash of the entire transaction request. This can be useful for tracking the transaction on chain. To get the transaction ID, you can use the following method:

```
// Get the chain ID
const chainId = await provider.getChainId();

// Get the transaction ID using the Chain ID
const transactionId = transactionRequest.getTransactionId(chainId);
// TX ID: 0x420f6...
```

> **Note**: Any changes made to a transaction request will alter the transaction ID. Therefore, you should only get the transaction ID after all modifications have been made.

### Burning assets

Assets can be burnt as part of a transaction that has inputs without associated output change. The SDK validates against this behavior, so we need to explicitly enable this by sending the transaction with the `enableAssetBurn` option set to `true`.

```
const baseAssetId = await provider.getBaseAssetId();
const request = new ScriptTransactionRequest();

const {
  coins: [coin],
} = await sender.getCoins(ASSET_A);

// Add the coin as an input, without a change output
request.addResource(coin);

/**
 * Remove the OutputChange for the specific assetId as it is always added by default
 * when using 'addResource'
 */
request.outputs = request.outputs.filter(
  (output) =>
    output.type !== OutputType.Change || String(output.assetId) !== ASSET_A
);

// Fund the transaction
const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: sender,
  accountCoinQuantities: [
    {
      amount: '0',
      assetId: baseAssetId,
      account: sender,
      changeOutputAccount: sender,
    },
  ],
});

// Send the transaction with asset burn enabled
const tx = await sender.sendTransaction(assembledRequest, {
  enableAssetBurn: true,
});
```

> **Note**: Burning assets is permanent and all assets burnt will be lost. Therefore, be mindful of the usage of this functionality.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/optimizing-frontend-apps.md.md

# Optimizing Frontend Apps

Your application must perform a series of operations to estimate, submit and receive the result of a transaction. However, the flow in which it performs these actions can be organized or performed optimistically, increasing it's perceived speed.

## Use Case

In a frontend application, imagine we have a button that executes a contract call:

```tsx
<Button onClick={handleSubmit}>Submit</Button>
```

The handler would be implemented as follows:

```
async function handleSubmit() {
  // 1. Calling the `call` function for a contract method will create
  // a transaction request, estimate it, fund it and then submit it
  const transaction = await contract.functions.increment_count(1).call();
  info(`Transaction ID Submitted: ${transaction.transactionId}`);

  // 2. Calling `waitForResult` will wait for the transaction to
  // settle, then assemble and return it
  const result = await transaction.waitForResult();
  info(`Transaction ID Successful: ${result.transactionId}`);
}
```

Once the user clicks the button, multiple sequential calls are made to the network, which can take a while because the transaction must be:

1. Estimated
1. Funded
1. Submitted

## Optimization Strategy

With a few optimizations, the flow can be organized as follows:

```
/**
 * Here we'll prepare our transaction upfront on page load, so that
 * by the time the user interacts with your app (i.e. clicking a btn),
 * the transaction is ready to be submitted
 */
async function onPageLoad() {
  // 1. Invoke the contract function whilst estimating and funding the
  // call, which gives us the transaction request
  request = await contract.functions.increment_count(1).fundWithRequiredCoins();
}

/**
 * By the time user user clicks the submit button, we only need to
 * submit the transaction to the network
 */
async function handleSubmit() {
  // 1. Submit the transaction to the network
  info(`Transaction ID Submitted: ${request.getTransactionId(chainId)}`);
  const response = await wallet.sendTransaction(request);

  // 2. Wait for the transaction to settle and get the result
  const result = await response.waitForResult();
  info(`Transaction ID Successful: ${result.id}`);
}
```

## Conclusion

Finally, when users click the button, they only need to submit the transaction, which vastly improves the perceived speed of the transaction because many of the necessary requests were done upfront, under the hood.

Just remember:

- _After preparation, any changes made to the transaction request will require it to be re-estimated and re-funded before it can be signed and submitted._

# See Also

- Check a full example at [Optimized React Example](../cookbook/optimized-react-example.md)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/transactions/pre-confirmations.md.md

# Pre-Confirmations

## What is a Pre-Confirmation?

A **pre-confirmation** is an intermediate transaction status that occurs after a transaction has been **submitted** and **accepted** by the blockchain, but **before** it is fully **processed and included** in a new block.

At this stage, the transaction is pre-executed and assigned one of two possible statuses:

- `PreconfirmationSuccessStatus`: The transaction is expected to be successfully included in a future block.

- `PreconfirmationFailureStatus`: The transaction will **not** be included in any future block.

## Why are Pre-Confirmations important?

Pre-confirmations allow applications to **react earlier** by providing immediate feedback about a transaction's expected outcome without waiting for full block finalization.

Additionally, pre-confirmations expose **processed outputs** (such as `OutputChange` and `OutputVariable`) that can be **immediately reused** in new transactions.

## Available Outputs for Pre-Confirmations

When a transaction reaches the **pre-confirmation** stage, certain `resolvedOutputs` become available:

- `OutputChange`: Represents the change UTXO generated from unspent inputs, grouped by `assetId` (one per asset).

- `OutputVariable`: Similar to `OutputCoin`, but only created if the transaction succeeds.

These outputs can be:

- Extracted directly from the pre-confirmation response.
- **Used immediately** to fund new transactions, without waiting for block confirmation.

This significantly improves the ability to build transaction sequences or reactive transaction flows.

This is the `ResolvedOutput` interface structure:

```
export type ResolvedOutput = {
  utxoId: string;
  output: OutputChange | OutputVariable;
};
```

## Example Workflow

Suppose you send a transaction that will send funds to another wallet.

As soon as you receive a `PreconfirmationSuccessStatus`, you can:

- Use the `OutputChange` in a new transaction.
- Submit the next transaction **without waiting** for block finalization.

This reduces wait times and accelerates transaction chaining.

## Code Examples

### Using Pre-Confirmations when Submitting a Transfer

The following example sends a transfer, waits for the pre-confirmation success, and then submits another transfer using the resolved outputs from the first:

```
const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient1 = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);
const recipient2 = Wallet.fromPrivateKey(WALLET_PVT_KEY_3, provider);
const baseAssetId = await provider.getBaseAssetId();

// Send a transfer and retrieve the pre-confirmation callback
const { waitForPreConfirmation } = await wallet.transfer(
  recipient1.address,
  1000
);

// Wait for the transaction to reach a pre-confirmation status
const { resolvedOutputs, isStatusPreConfirmationSuccess } =
  await waitForPreConfirmation();

// Check if the pre-confirmation status indicates success
if (isStatusPreConfirmationSuccess) {
  // Find the change output associated with the base asset ID
  const resolvedChangeOutput = resolvedOutputs?.find(
    (resolved) =>
      resolved.output.type === OutputType.Change &&
      resolved.output.assetId === baseAssetId
  );

  // If we find the change output, we can use it to create a new transaction
  if (resolvedChangeOutput) {
    const { output, utxoId } = resolvedChangeOutput;

    // Create a new transaction request
    const newTransaction = new ScriptTransactionRequest({
      maxFee: 1000,
      gasLimit: 1000,
    });

    // Add the change output as an input resource for the new transaction
    newTransaction.addResource({
      id: utxoId,
      assetId: output.assetId,
      amount: output.amount,
      owner: new Address(output.to),
      blockCreated: bn(0),
      txCreatedIdx: bn(0),
    });

    // Define the transfer recipient of the new transaction
    newTransaction.addCoinOutput(recipient2.address, 1000, baseAssetId);

    // Send the new transaction
    await wallet.sendTransaction(newTransaction);
  }
}
```

### Using Pre-Confirmations with a Contract Call

This example performs a contract call, waits for pre-confirmation success, and then uses the resolved output to execute another contract call:

```
// Send a contract call and retrieve the pre-confirmation callback
const { waitForPreConfirmation } = await contract.functions
  .increment_count(1)
  .call();

const {
  transactionResult: { resolvedOutputs, isStatusPreConfirmationSuccess },
} = await waitForPreConfirmation();

// Check if the pre-confirmation status indicates success
if (isStatusPreConfirmationSuccess) {
  // Find the change output associated with the base asset ID
  const resolvedChangeOutput = resolvedOutputs?.find(
    (resolved) =>
      resolved.output.type === OutputType.Change &&
      resolved.output.assetId === baseAssetId
  );

  // If we find the change output, we can use it to create a new transaction
  if (resolvedChangeOutput) {
    const { output, utxoId } = resolvedChangeOutput;

    // Creates a new scope invocation for another contract call
    const scope = contract.functions.increment_count(1).txParams({
      maxFee: 100_000,
      gasLimit: 100_000,
    });

    // Get the transaction request from the scope invocation
    const request = await scope.getTransactionRequest();

    // Add the change output as an input resource for the new transaction
    request.addResource({
      id: utxoId,
      assetId: output.assetId,
      amount: output.amount,
      owner: new Address(output.to),
      blockCreated: bn(0),
      txCreatedIdx: bn(0),
    });

    /**
     * Call the scope invocation and skip the assembleTx step since the transaction
     * request is already funded
     */
    await scope.call({ skipAssembleTx: true });
  }
}
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/address.md.md

# Address

In Sway, the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) type serves as a type-safe wrapper around the primitive `B256` type. The SDK takes a different approach and has its own abstraction for the [Address](DOCS_API_URL/classes/_fuel_ts_address.Address.html) type.

## Address Class

The [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class also provides a set of utility functions for easy manipulation and conversion between address formats along with one property; `b256Address`, which is of the [`B256`](./b256.md) type.

```
  readonly b256Address: B256Address;
```

## Creating an Address

There are several ways to create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) instance:

### From a b256 address

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from a 256-bit address, use the following code snippet:

```
import { Address } from 'fuels';
// #region b256-1
const b256 =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';
// #endregion b256-1

const address = new Address(b256);

console.log('b256', address.toB256());
// 0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6
```

### From a Public Key

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from a public key, use the following code snippet:

```
import { Address, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.generate({ provider });

const address = new Address(wallet.publicKey);
```

### From an EVM Address

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from an EVM address, use the following code snippet:

```
import { Address } from 'fuels';

const evmAddress = '0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c';

const address = new Address(evmAddress);
```

### From an existing Address

To create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from an existing [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) instance, use the following code snippet:

```
import { Address } from 'fuels';

const address = Address.fromRandom();

const addressClone = new Address(address);
```

## Utility functions

### `equals`

As you may already notice, the `equals` function can compare addresses instances:

```
import { Address } from 'fuels';

const address = Address.fromRandom();

const address1 = new Address(address.toString());
const address2 = new Address(address.toB256());

console.log('equals', address1.equals(address2));
// true
```

### `toChecksum`

To convert an address to a checksum address, use the `toChecksum` function:

```
import { Address } from 'fuels';

const b256 =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';

const address = new Address(b256);

console.log('checksum', address.toChecksum());
// true
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/arrays.md.md

# Arrays

In Sway, an `Array` is a fixed-size collection of elements of the same type, similar to a `Tuple`. `Arrays` can hold arbitrary types, including non-primitive types, with their size determined at compile time.

## Using Arrays in the SDK

You can pass a TypeScript `Array` into your contract method seamlessly just like you would pass an `Array` to a TypeScript function.

The SDK handles the conversion from TypeScript to Sway in the background, allowing the expected data to be passed through the type regardless of the `Array` type.

An `Array` in Sway is simply a typed `Array`, as demonstrated in the following example:

```
// in Sway: [u8; 5]
const numberArray: number[] = [1, 2, 3, 4, 5];

// in Sway: [bool; 3]
const boolArray: boolean[] = [true, false, true];
```

In Sway, `Arrays` are fixed in size, so the storage size is determined at the time of program compilation, not during runtime.

Let's say you have a contract that takes an `Array` of type `u64` with a size length of 2 as a parameter and returns it:

```
    fn echo_u64_array(u64_array: [u64; 2]) -> [u64; 2] {
        u64_array
    }
```

To execute the contract call using the SDK, you would do something like this:

```
const u64Array: [BigNumberish, BigNumberish] = [10000000, 20000000];

const { value } = await contract.functions.echo_u64_array(u64Array).get();

console.log('value', value);
// [<BN: 0x989680>, <BN: 1312D00>]
```

You can easily access and validate the `Array` returned by the contract method, as demonstrated in the previous example.

As previously mentioned, Sway `Arrays` have a predefined type and size, so you need to be careful when passing `Arrays` as parameters to contract calls.

Passing an Array with an incorrect size, whether it has more or fewer elements than the specified length, will result in an error:

```
try {
  // @ts-expect-error forced error
  await contract.functions.echo_u64_array([10000000]).get();
} catch (e) {
  console.log('error', e);
  // Types/values length mismatch.
}
```

Similarly, passing an `Array` with an incorrect type will also result in an error:

```
try {
  await contract.functions.echo_u64_array([10000000, 'a']).get();
} catch (e) {
  console.log('error', e);
  // Invalid u64.
}
```

## Vectors

If your `Array` size is unknown until runtime, consider using the [Vectors](./vectors.md) type, which is more suitable for dynamic-sized collections.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/asset-id.md.md

# Asset ID

An Asset ID can be represented using the `AssetId` type. It's definition matches the Sway standard library type being a `Struct` wrapper around an inner `B256` value.

```
import type { AssetId } from 'fuels';
import { getRandomB256 } from 'fuels';

const b256 = getRandomB256();

const assetId: AssetId = {
  bits: b256,
};
```

## Using an Asset ID

You can easily use the `AssetId` type within your Sway programs. Consider the following contract that can compares and return an `AssetId`:

```
contract;

abi EvmTest {
    fn echo_asset_id() -> AssetId;
    fn echo_asset_id_comparison(asset_id: AssetId) -> bool;
    fn echo_asset_id_input(asset_id: AssetId) -> AssetId;
}

const ASSET_ID: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);

impl EvmTest for Contract {
    fn echo_asset_id() -> AssetId {
        ASSET_ID
    }

    fn echo_asset_id_comparison(asset_id: AssetId) -> bool {
        asset_id == ASSET_ID
    }

    fn echo_asset_id_input(asset_id: AssetId) -> AssetId {
        asset_id
    }
}
```

The `AssetId` struct can be passed to the contract function as follows:

```
const assetId: AssetId = {
  bits: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c',
};

const { value } = await contract.functions
  .echo_asset_id_comparison(assetId)
  .get();
```

And to validate the returned value:

```
const { value } = await contract.functions.echo_asset_id().get();

console.log('value', value);
// const value: AssetId = {
//   bits: '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c',
// };
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/b256.md.md

# `B256`

The type `B256` in Fuel represents hashes and holds a 256-bit (32-bytes) value. The TypeScript SDK represents `B256` as a hexlified string value for portability and provides utilities to convert to `Uint8Array` when the [raw bytes](./bytes32.md) are required.

## Generating random `B256` values

To generate a random `B256` value, you can use the `getRandomB256()` function:

```
import { getRandomB256 } from 'fuels';

// b256 is a hexlified string representing a 256-bit value
const b256: string = getRandomB256();

console.log('b256', b256);
// 0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6
```

### Converting between `B256` and `Uint8Array`

To convert between a `B256` hexlified string and a `Uint8Array`, you can use the `arrayify` and `hexlify` functions:

```
import { arrayify, getRandomB256, hexlify } from 'fuels';

const randomB256: string = getRandomB256();

// Convert to Uint8Array
const uint8Arr: Uint8Array = arrayify(randomB256);

// Convert back to hexlified string
const hexedB256: string = hexlify(uint8Arr);
```

## Support from `Address` Class

A `B256` value is also supported as part of the [`Address`](https://fuels-ts-docs-api.vercel.app/classes/_fuel_ts_address.Address.html) class, providing seamless integration with other components of your application. To create an [`Address`](https://fuels-ts-docs-api.vercel.app/classes/_fuel_ts_address.Address.html) instance from a b256 value, use the `new Address()` method:

```
import { getRandomB256, Address } from 'fuels';

const randomB256: string = getRandomB256();

const address = new Address(randomB256);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/b512.md.md

# B512

In Sway, the `B512` type is commonly used to handle public keys and signatures. This guide will explain how the `B512` type is defined in Sway, how to visualize a `B512` value using the SDK, and how to interact with a contract function that accepts a `B512` parameter.

The `B512` type in Sway is a wrapper around two `B256` types, allowing for the representation of 64-byte values. It is defined as a struct:

```
pub struct B512 {
    /// The two `B256`s that make up the `B512`.
    bits: [b256; 2],
}
```

## `B512` in the SDK

In the SDK, you can visualize a `B512` value by examining a wallet's public key:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.generate({ provider });

console.log('public key', wallet.publicKey);

// 0x97e3a666e4cd34b6b3cf778ef5ec617de4439b68f7a629245442a1fece7713094a1cb0aa7ad0ac253ca1ea47d4618f9090b2a881e829e091fb2c426763e94cca
```

## Example: Echoing a `B512` Value in a Contract Function

Let's consider a contract function that accepts a `B512` parameter and returns the same value:

```
    fn echo_b512(input: B512) -> B512 {
        input
    }
```

To call this function and validate the returned value, follow these steps:

```
const b512 = wallet.publicKey;

const { value } = await contract.functions.echo_b512(b512).get();
```

In this example, we generate a wallet, use its public key as the `B512` input, call the `echo_b512` contract function, and expect the returned value to match the original input.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/bytes.md.md

# Bytes

A dynamic array of byte values can be represented using the `Bytes` type, which represents raw bytes.

## Using Bytes

The `Bytes` type can be integrated with your contract calls. Consider the following contract that can compare and return a `Bytes`:

```
contract;

use std::bytes::Bytes;

abi BytesTest {
    fn echo_bytes(value: Bytes) -> Bytes;
    fn bytes_comparison(value: Bytes) -> bool;
}

impl BytesTest for Contract {
    fn echo_bytes(value: Bytes) -> Bytes {
        value
    }

    fn bytes_comparison(value: Bytes) -> bool {
        let mut bytes = Bytes::new();

        bytes.push(40u8);
        bytes.push(41u8);
        bytes.push(42u8);

        value == bytes
    }
}
```

A `Bytes` array can be created using a native JavaScript array of numbers or Big Numbers, and sent to a Sway contract:

```
const bytes: Bytes = [40, 41, 42];

const { value } = await contract.functions.echo_bytes(bytes).get();

console.log('value', value);
// Uint8Array(3)[40, 41, 42]
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/bytes32.md.md

# Bytes32

In Sway and the FuelVM, `bytes32` is used to represent hashes. It holds a 256-bit (32-bytes) value.

## Generating Random bytes32 Values

To generate a random `bytes32` value, you can use the `randomBytes` function from the fuels module:

```
import { randomBytes, type Bytes } from 'fuels';

const bytes32: Bytes = randomBytes(32);
```

## Converting Between Byte Arrays and Strings

You can use the `hexlify` function to convert a byte array to a hex string, and the `arrayify` function to convert a hex string back to a byte array:

```
import type { Bytes } from 'fuels';
import { arrayify, hexlify, randomBytes } from 'fuels';

const randomBytes32: Bytes = randomBytes(32);

const bytes32String: string = hexlify(randomBytes32);

const bytes32: Bytes = arrayify(bytes32String);
```

## Working with b256 in Fuel

In Fuel, there is a special type called b256, which is similar to `bytes32`. Like `bytes32`, `B256` is also used to represent hashes and holds a 256-bit value. You can learn more about working with `B256` values in the [B256 documentation](./b256.md).


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/enums.md.md

# Enums

Sway Enums are a little distinct from TypeScript Enums. In this document, we will explore how you can represent Sway Enums in the SDK and how to use them with Sway contract functions.

## Basic Sway Enum Example

Consider the following basic Sway Enum called `StateError`:

```
// #region enums-4
pub enum StateError {
    Void: (),
    Pending: (),
    Completed: (),
}
```

The type `()` indicates that there is no additional data associated with each Enum variant. Sway allows you to create Enums of Enums or associate types with Enum variants.

### Using Sway Enums As Function Parameters

Let's define a Sway contract function that takes a `StateError` Enum variant as an argument and returns it:

```
    fn echo_state_error_enum(state_error: StateError) -> StateError {
        state_error
    }
```

To execute the contract function and validate the response, we can use the following code:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { EchoEnumFactory } from '../../../../typegend';
import { StateErrorInput } from '../../../../typegend/contracts/EchoEnum';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const deploy = await EchoEnumFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

const enumParam = StateErrorInput.Completed;

const { value } = await contract.functions
  .echo_state_error_enum(enumParam)
  .get();

console.log('value', value);
// StateErrorInput.Completed
```

In this example, we simply pass the Enum variant as a value to execute the contract function call.

## Enum of Enums Example

In this example, the `Error` Enum is an Enum of two other Enums: `StateError` and `UserError`.

```
pub enum StateError {
    Void: (),
    Pending: (),
    Completed: (),
}
// #endregion enums-1

pub enum UserError {
    Unauthorized: (),
    InsufficientPermissions: (),
}

pub enum Error {
    StateError: StateError,
    UserError: UserError,
}
```

### Using Enums of Enums with Contract Functions

Now, let's create a Sway contract function that accepts any variant of the `Error` Enum as a parameter and returns it immediately. This variant could be from either the `StateError` or `UserError` Enums.

```
    fn echo_error_enum(error: Error) -> Error {
        error
    }
```

Since the `Error` Enum is an Enum of Enums, we need to pass the function parameter differently. The parameter will be a TypeScript object:

```
const enumParam = { UserError: UserErrorInput.InsufficientPermissions };

const { value } = await contract.functions.echo_error_enum(enumParam).get();

console.log('value', value);
// { UserError: UserErrorInput.InsufficientPermissions }
```

In this case, since the variant `InsufficientPermissions` belongs to the `UserError` Enum, we create a TypeScript object using the Enum name as the object key and the variant as the object value.

We would follow the same approach if we intended to use a variant from the `StateError` Enum:

```
const enumParam = { StateError: StateErrorInput.Completed };

const { value } = await contract.functions.echo_error_enum(enumParam).get();

console.log('value', value);
// { StateError: StateErrorInput.Completed }
```

## Errors

While working with enums, you may run into the following issues:

### Using an invalid enum type

Thrown when the type being passed to the enum does not match that expected by it.

```
// Valid types: string
const emumParam = 1;

try {
  // @ts-expect-error number is not a valid type
  await contract.functions.echo_state_error_enum(emumParam).get();
} catch (error) {
  console.log('error', error);
}
```

### Using an invalid enum value

Thrown when the parameter passed is not an expected enum value.

```
// Valid values: 'Void', 'Pending', 'Completed'
const invalidEnumValue = 'NotStateEnumValue';

try {
  // @ts-expect-error NotStateEnumValue is not a valid value
  await contract.functions.echo_state_error_enum(invalidEnumValue).get();
} catch (error) {
  console.log('error', error);
}
```

### Using an invalid enum case key

Thrown when the passed enum case is not an expected enum case value.

```
// Valid case keys: 'StateError', 'UserError'
const enumParam = { UnknownKey: 'Completed' };

try {
  // @ts-expect-error UnknownKey is not a valid key
  await contract.functions.echo_error_enum(enumParam).get();
} catch (error) {
  console.log('error', error);
}
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/evm-address.md.md

# `EvmAddress`

An Ethereum Virtual Machine (EVM) Address can be represented using the `EvmAddress` type. It's definition matches the Sway standard library type being a `Struct` wrapper around an inner `B256` value.

```
import type { B256AddressEvm, EvmAddress } from 'fuels';

const b256: B256AddressEvm =
  '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6';

const evmAddress: EvmAddress = {
  bits: b256,
};
```

## Creating an EVM Address

An EVM Address only has 20 bytes therefore the first 12 bytes of the `B256` value are set to 0. Within the SDK, an `Address` can be instantiated and converted to a wrapped and Sway compatible EVM Address using the `toEvmAddress()` function:

```
import { Address } from 'fuels';

// #region snippet-2
const b256Address =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';
// #endregion snippet-2

const address = new Address(b256Address);

const evmAddress = address.toEvmAddress();

console.log('evmAddress', evmAddress);
// '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6'
```

## Using an EVM Address

The `EvmAddress` type can be integrated with your contract calls. Consider the following contract that can compare and return an EVM Address:

```
contract;

use std::vm::evm::evm_address::EvmAddress;

configurable {
    B256_ADDR: b256 = 0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6,
}

abi EvmTest {
    fn echo_address() -> EvmAddress;
    fn echo_address_comparison(evm_addr: EvmAddress) -> bool;
}

impl EvmTest for Contract {
    fn echo_address() -> EvmAddress {
        return EvmAddress::from(B256_ADDR);
    }

    fn echo_address_comparison(evm_addr: EvmAddress) -> bool {
        let evm_addr2 = EvmAddress::from(B256_ADDR);

        evm_addr == evm_addr2
    }
}
```

The `EvmAddress` type can be used with the SDK and passed to the contract function as follows:

```
// #region snippet-2
const evmAddress: EvmAddress = {
  bits: '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6',
};
// #endregion snippet-2

const { value } = await contract.functions
  .echo_address_comparison(evmAddress)
  .get();
```

And to validate the returned value:

```
const { value } = await contract.functions.echo_address().get();

console.log('value', value);
// { bits: '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6' }
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/index.md.md

# Types

As you dive deeper into the SDK, it's essential to understand the variety of internal types available in both FuelVM and Sway, as well as their corresponding SDK equivalents. This section aims to provide you with the necessary knowledge to efficiently work with these types.

## Overview

In this section, you will learn about:

1. `FuelVM and Sway Internal Types`: Discover the various types used within FuelVM and Sway, and their significance in different contexts.

2. `SDK Equivalents`: Explore the corresponding types available in the SDK, and understand their similarities and differences compared to FuelVM and Sway internal types.

3. `Type Usage`: Gain insights into how to effectively use these types in your projects or applications, with examples and best practices.

4. `Type Conversion`: Learn the techniques and methods for converting between FuelVM, Sway, and SDK types, guaranteeing smooth interoperability and consistent data integrity.

## Additional Resources

As you progress through the documentation, you may find it helpful to refer back to the following resources:

- [Sway Documentation](https://docs.fuel.network/docs/sway/): Explore the Sway documentation homepage for an overview of Sway Types, as well as other sections.

- [The Fuel Book](https://fuelbook.fuel.network/master/index.html): A comprehensive guide to the whole Fuel ecosystem.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/native-parameters.md.md

# Native Parameter Types

Below you can find examples of how to convert between common native Sway program input and output types:

- [`Address`](#address)
- [`ContractId`](#contractid)
- [`Identity`](#identity)
- [`AssetId`](#assetid)

## `Address`

### `AddressInput`

To pass an `Address` as an input parameter to a Sway program, you can define the input as shown below:

```
const address = Address.fromRandom();
const addressInput = { bits: address.toB256() };
```

### `AddressOutput`

For a Sway program that returns an `Address` type, you can convert the returned value to an `Address` type in `fuels` as shown below:

```
const addressOutput = response1.value;
const addressFromOutput: Address = new Address(addressOutput.bits);
```

## `ContractId`

### `ContractIdInput`

To pass a `ContractId` as an input parameter to a Sway program, you can define the input as shown below:

```
const contractId =
  '0x7296ff960b5eb86b5f79aa587d7ebe1bae147c7cac046a16d062fbd7f3a753ec';
const contractIdInput = { bits: contractId };
```

### `ContractIdOutput`

For a Sway program that returns a `ContractId` type, you can convert the returned value to a `string` as shown below:

```
const contractIdOutput = response.value;
const contractIdFromOutput: string = contractIdOutput.bits;
```

## `Identity`

### `IdentityInput`

To pass an `Identity` as an input parameter to a Sway program, you can define the input as shown below:

For an address:

```
const address = Address.fromRandom();
const addressInput = { bits: address.toB256() };
const addressIdentityInput = { Address: addressInput };
```

For a contract:

```
const contractId =
  '0x7296ff960b5eb86b5f79aa587d7ebe1bae147c7cac046a16d062fbd7f3a753ec';
const contractIdInput = { bits: contractId.toString() };
const contractIdentityInput = { ContractId: contractIdInput };
```

### `IdentityOutput`

For a Sway program that returns an `Identity` type, you can convert the returned value to an `Address` or `string` as shown below:

For an address:

```
const response = await contract.functions.identity(addressIdentityInput).get();

const identityFromOutput: IdentityOutput = response.value;
const addressStringFromOutput: AddressOutput =
  identityFromOutput.Address as AddressOutput;
const addressFromOutput = new Address(addressStringFromOutput.bits);
```

For a contract:

```
const response = await contract.functions.identity(contractIdentityInput).get();

const identityFromOutput2: IdentityOutput = response.value;
const contractIdOutput = identityFromOutput2.ContractId as ContractIdOutput;
const contractIdFromOutput = contractIdOutput.bits;
```

## `AssetId`

### `AssetIdInput`

To pass an `AssetId` as an input parameter to a Sway program, you can define the input as shown below:

```
const assetId =
  '0x0cfabde7bbe58d253cf3103d8f55d26987b3dc4691205b9299ac6826c613a2e2';
const assetIdInput = { bits: assetId };
```

### `AssetIdOutput`

For a Sway program that returns an `AssetId` type, you can convert the returned value to a `string` as shown below:

```
const assetIdOutput = response5.value;
const assetIdFromOutput: string = assetIdOutput.bits;
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/numbers.md.md

# Numbers

In Sway, there are multiple primitive number types:

1. `u8` (8-bit unsigned integer)
1. `u16` (16-bit unsigned integer)
1. `u32` (32-bit unsigned integer)
1. `u64` (64-bit unsigned integer)
1. `u256` (256-bit unsigned integer)

This guide explains how to create and interact with Sway numbers while using the SDK.

## Creating Numbers

### For `u64` and `u256`

When you pass in a `u64` or a `u256` to a Sway program from JavaScript, you must first convert it to a `BigNum` object. This is because these types can have extremely large maximum values (`2^64` and `2^256` respectively), and JavaScript's `Number` type can only hold up to 53 bits of precision (`2^53`).

```
import { bn } from 'fuels';

const number: number | string = 20;

const bigNumber = bn(number);

console.log('equals', bigNumber.eqn(number));
// true
```

You can also create a `BigNum` from a string. This is useful when you want to pass in a number that is too large to be represented as a JavaScript number. Here's how you can do that:

```
import { bn } from 'fuels';

const strNumber = '9007199254740992';

const bigNumber = bn(strNumber);

console.log('equals', bigNumber.toString() === strNumber);
// true
```

### For `u8`, `u16`, and `u32`

You don't need to do anything special to create these numbers. You can pass in a JavaScript number directly. See the examples below for more details.

## Examples: Interacting with Numbers in Contract Methods

### For `u64` and `u256`

```
const bigNumber = bn('10000000000000000000');

const { value } = await contract.functions.echo_u64(bigNumber).get();

console.log('value', value.toString());
// '10000000000000000000'
```

> Note: If a contract call returns a number that is too large to be represented as a JavaScript number, you can convert it to a string using the `.toString()` method instead of `.toNumber()`.

### For `u8`, `u16`, and `u32`

```
const number = 200;

const { value } = await contract.functions.echo_u8(number).get();

console.log('value', Number(value));
// 200
```

### Using a `BigNum` from `ethers` with `fuels`

```
import { toBigInt } from 'ethers';
import { bn } from 'fuels';

const number = 20;

const ethersBigNum = toBigInt(number);

const fuelsBigNum = bn(ethersBigNum.toString());

console.log('value', fuelsBigNum.toNumber());
// 20
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/options.md.md

# Options

Sway provides the `Option` (optional) container for handling variables that can have a value or be marked as `no-value`. This concept is useful when dealing with situations where a variable may or may not have a defined value.

In this guide, we'll explain how to work with Option types in Sway and demonstrate their usage through a practical example.

## Overview of `Option` Type

The `Option` type in Sway is a special wrapper type of Enum. In TypeScript, you can represent the `Option` type by using the `undefined` keyword, as shown in the following example

```
// Sway Option<u8>
// #region snippet-2
const input: number | undefined = 10;
```

In this example, the variable `input1` can be either a `number` or `undefined`.

## Example: `Option<u8>` Parameters

Let's say we have a contract function that accepts two `Option<u8>` parameters. Both of these parameters can have a value or be undefined. The function checks whether each input has a value; if not, it assigns a value of `0`. Finally, the function returns the sum of the two inputs.

Here's the contract function written in Sway:

```
    fn sum_optional_u8(input1: Option<u8>, input2: Option<u8>) -> u8 {
        let value1 = match input1 {
            Option::Some(v) => v,
            Option::None => 0,
        };

        let value2 = match input2 {
            Option::Some(v) => v,
            Option::None => 0,
        };

        value1 + value2
    }
```

You can interact with the contract function using the SDK as follows:

```
const input: number | undefined = 10;
// #endregion snippet-1
const input2: number | undefined = 5;

const { value } = await contract.functions.sum_optional_u8(input, input2).get();

console.log('value', value);
// 15
```

In this case, the result of the contract function call is the sum of both input parameters. If we pass only one parameter, the contract function will default the other parameter's value to `0`.

```
const input: number | undefined = 10;

const { value } = await contract.functions.sum_optional_u8(input).get();

console.log('value', value);
// 10
```

Using `Option` types in Sway allows you to elegantly handle situations where a variable may or may not have a defined value.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/raw-slice.md.md

# `RawSlice`

A dynamic array of values can be represented using the `RawSlice` type. A raw slice can be a value reference or a raw pointer.

## Using a `RawSlice`

The `RawSlice` type can be integrated with your contract calls. Consider the following contract that can compare and return a `RawSlice`:

```
contract;

abi RawSliceTest {
    fn echo_raw_slice(value: raw_slice) -> raw_slice;
    fn raw_slice_comparison(value: raw_slice) -> bool;
}

impl RawSliceTest for Contract {
    fn echo_raw_slice(value: raw_slice) -> raw_slice {
        value
    }

    fn raw_slice_comparison(value: raw_slice) -> bool {
        let vec: Vec<u8> = Vec::from(value);

        vec.len() == 3 && vec.get(0).unwrap() == 40 && vec.get(1).unwrap() == 41 && vec.get(2).unwrap() == 42
    }
}
```

A `RawSlice` can be created using a native JavaScript array of numbers or Big Numbers, and sent to a Sway contract:

```
const rawSlice: RawSlice = [8, 42, 77];

const { value } = await contract.functions.echo_raw_slice(rawSlice).get();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/std-string.md.md

# `StdString`

A dynamic string of variable length can be represented using the `StdString` type, also known as a Standard Lib String or `std-lib-string`. It behaves much like a dynamic string in most languages, and is essentially an array of characters.

## Using a `StdString`

The `StdString` type can be integrated with your contract calls. Consider the following contract that can compare and return a String:

```
contract;

use std::string::String;

abi StdStringTest {
    fn echo_string(value: String) -> String;
    fn string_comparison(value: String) -> bool;
}

impl StdStringTest for Contract {
    fn echo_string(value: String) -> String {
        value
    }

    fn string_comparison(value: String) -> bool {
        let expected = String::from_ascii_str("Hello World");

        value.as_bytes() == expected.as_bytes()
    }
}
```

A string can be created using a native JavaScript string, and sent to a Sway contract:

```
const stdString: StdString = 'Hello Fuel';

const { value } = await contract.functions.echo_string(stdString).get();

console.log('value', value);
// 'Hello Fuel'
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/string.md.md

# String

In Sway, strings are statically-sized, which means you must define the size of the string beforehand. Statically-sized strings are represented using the `str[x]` syntax, where `x` indicates the string's size.
This guide explains how to create and interact with statically-sized strings while using the SDK.

## Creating Statically-Sized Strings

```
// Sway str[2]
const stringSize2 = 'st';

// Sway str[8]
const stringSize8 = 'fuel-sdk';
```

## Interacting with Statically-Sized Strings in Contract Methods

When a contract method accepts and returns a `str[8]`, the corresponding SDK wrapper method will also take and return a string of the same length. You can pass a string to the contract method like this:

```
const { value } = await contract.functions.echo_str_8('fuel-sdk').get();

console.log('value', value);
// 'fuel-sdk'
```

When working with statically-sized strings, ensure that the input and output strings have the correct length to avoid erroneous behavior.

If you pass a string that is either too long or too short for a contract method, the call will fail like this:

```
const longString = 'fuel-sdk-WILL-THROW-ERROR';

try {
  await contract.functions.echo_str_8(longString).call();
} catch (error) {
  console.log('error', error);
  // Value length mismatch during encode
}

const shortString = 'THROWS';

try {
  await contract.functions.echo_str_8(shortString).call();
} catch (error) {
  console.log('error', error);
  // Value length mismatch during encode
}
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/structs.md.md

# Structs

In Sway, a `struct` serves a similar purpose as an `Object` in TypeScript. It defines a custom data structure with specified property names and types. The property names and types in the Sway struct must match the corresponding TypeScript definition.

## Example

Here is an example of a `struct` in Sway:

```
pub struct EmployeeData {
    name: str[8],
    age: u8,
    salary: u64,
    idHash: b256,
    ratings: [u8; 3],
    isActive: bool,
}
```

And here is the equivalent structure represented in TypeScript:

```
type EmployeeDataStruct = {
  name: string;
  age: number;
  salary: number;
  idHash: string;
  ratings: number[];
  isActive: boolean;
};

const data: EmployeeDataStruct = {
  name: 'John Doe',
  age: 30,
  salary: 100_000,
  idHash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef',
  ratings: [4, 5, 5],
  isActive: true,
};
```

## Handling Different Data Types

Please note that TypeScript does not have native support for `u8` and `u64` types. Instead, use the `number` type to represent them.

Additionally, TypeScript does not support specifying string length, so just use `string` for the `name`.

In a similar way, since the type `B256` on the SDK is just an hexlified string, we use `string` as well.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/tuples.md.md

# Tuples

In Sway, Tuples are fixed-length collections of heterogeneous elements. Tuples can store multiple data types, including basic types, structs, and enums. This guide will demonstrate how to represent and work with Tuples in TypeScript and interact with a contract function that accepts a tuple as a parameter.

In TypeScript, you can represent Sway tuples using arrays with specified types for each element:

```
// Sway let tuple2: (u8, bool, u64) = (100, false, 10000);
// #region tuples-3
const tuple: [number, boolean, number] = [100, false, 10000];
```

In this example, the Typescript `tuple` variable contains three elements of different types: a number, a boolean, and another number.

## Example: Passing Tuple as a Parameter

Let's consider a contract function that accepts a tuple as a parameter and returns the same Tuple:

```
    fn echo_tuple(tuple: (u8, bool, u64)) -> (u8, bool, u64) {
        tuple
    }
```

To execute and validate the contract function using the SDK, follow these steps:

```
const tuple: [number, boolean, number] = [100, false, 10000];
// #endregion tuples-1

const { value } = await contract.functions.echo_tuple(tuple).simulate();

console.log('value', value);
// [100, false, <BN 0x2710>]
```

In this example, we create a Tuple with three elements, call the `echo_tuple` contract function, and expect the returned tuple to match the original one. Note that we convert the third element of the returned tuple to a number using `new BN(value[2]).toNumber()`.

Tuples in Sway provide a convenient way to store and manipulate collections of heterogeneous elements. Understanding how to represent and work with tuples in TypeScript and Sway contracts will enable you to create more versatile and expressive code.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/types/vectors.md.md

# Vectors

In Sway, a Vector is a dynamic-sized collection of elements of the same type. Vectors can hold arbitrary types, including non-primitive types.

## Working with Vectors in the SDK

A basic Vector in Sway is similar to a TypeScript Array:

```
// Sway Vec<u8>
const basicU8Vector = [1, 2, 3];
```

Consider the following example of a `EmployeeData` struct in Sway:

```
pub struct EmployeeData {
    name: str[8],
    age: u8,
    salary: u64,
    idHash: b256,
    ratings: [u8; 3],
    isActive: bool,
}
```

Now, let's look at the following contract method. It receives a Vector of the `Transaction` struct type as a parameter and returns the last `Transaction` entry from the Vector:

```
    fn echo_last_employee_data(employee_data_vector: Vec<EmployeeData>) -> EmployeeData {
        employee_data_vector.get(employee_data_vector.len() - 1).unwrap()
    }
```

The code snippet below demonstrates how to call this Sway contract method, which accepts a `Vec<Transaction>`:

```
const employees: EmployeeDataInput[] = [
  {
    name: 'John Doe',
    age: 30,
    salary: bn(8000),
    idHash: getRandomB256(),
    ratings: [1, 2, 3],
    isActive: true,
  },
  {
    name: 'Everyman',
    age: 31,
    salary: bn(9000),
    idHash: getRandomB256(),
    ratings: [5, 6, 7],
    isActive: true,
  },
];
const { value } = await contract.functions
  .echo_last_employee_data(employees)
  .simulate();
```

## Converting Bytecode to Vectors

Some functions require you to pass in bytecode to the function. The type of the bytecode parameter is usually `Vec<u8>`, here's an example of how to pass bytecode to a function:

```
    fn compute_bytecode_root(bytecode_input: Vec<u8>) -> b256 {
        //simply return a fixed b256 value created from a hexadecimal string from testing purposes
        return 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20;
    }
```

To pass bytecode to this function, you can make use of the `arrayify` function to convert the bytecode file contents into a `UInt8Array`, the TS compatible type for Sway's `Vec<u8>` type and pass it the function like so:

```
const bytecodeAsVecU8 = Array.from(arrayify(BytecodeInputFactory.bytecode));

const { waitForResult } = await bytecodeContract.functions
  .compute_bytecode_root(bytecodeAsVecU8)
  .call();

const { value: bytecodeRoot } = await waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/utilities/address-conversion.md.md

# Address

Addresses and varying address formats are commonplace when interacting with decentralized applications. Furthermore, different networks may enforce different address formats.

The Fuel Network uses the [`B256`](../types/b256.md) address format for its interactions, an example of which can be seen below:

```
const b256 =
  '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c';
```

However, a hexlified [B256](../types/b256.md) (hex) is another common address format; an example can be seen below:

```
const b256Address =
  '0xbebd3baab326f895289ecbd4210cf886ce41952316441ae4cac35f00f0e882a6';
```
apps/

At times, these can even be wrapped in a [Struct](../types/structs.md). Such as an [Asset ID](../types/asset-id.md) or a [EVM Address](../types/evm-address.md):

```
const evmAddress: EvmAddress = {
  bits: '0x000000000000000000000000210cf886ce41952316441ae4cac35f00f0e882a6',
};
```

The TS-SDK makes converting between these addresses simple using the [Address](../types/address.md) helper, which provides various utilities for conversion.

The following [conversion guide](./address-conversion.md#address-conversion) will show how to utilize this class to convert between address formats, as well as Sway Standard Types.

## Address Conversion

This guide demonstrates how to convert between address formats and Sway Standard Types using helper functions. Native types are wrappers for bytes, and you can perform conversions between them by leveraging these functions and classes.

## Converting a Contract ID

The Contract `id` property is an instance of the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class. Therefore, it can be converted using the [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class functions such as `toAddress` and `toB256`:

```
import type { B256Address } from 'fuels';
import { Address, Provider, Contract } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';
import { Counter } from '../../../../typegend/contracts';

const provider = new Provider(LOCAL_NETWORK_URL);

const contractAbi = Counter.abi;
const contractAddress = new Address(
  '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
);

const contract = new Contract(contractAddress, contractAbi, provider);

const b256: B256Address = contract.id.toAddress();
// 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
```

## Converting a Wallet Address

Similarly, the Wallet `address` property is also of type [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) and can therefore use the same [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) class functions for conversion:

```
import type { B256Address, WalletLocked } from 'fuels';
import { Address, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const address = new Address(
  '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
);

const wallet: WalletLocked = Wallet.fromAddress(address, provider);

const b256: B256Address = wallet.address.toAddress();
// 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
```

## Converting an Asset ID

[Asset IDs](../types/asset-id.md) are a wrapped [`B256`](../types/b256.md) value. The following example shows how to create an [`Address`](DOCS_API_URL/classes/_fuel_ts_address.Address.html) from a `B256` type:

```
import type { AssetId, B256Address } from 'fuels';
import { Address } from 'fuels';

const b256: B256Address =
  '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f';
const address: Address = new Address(b256);
const assetId: AssetId = address.toAssetId();
// {
//    bits: '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f
// }
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/utilities/asset-api.md.md

# Asset API

The Asset API is a RESTful API that allows you to query the assets on the Fuel blockchain. We allow for querying the Asset API on both the Mainnet and Testnet.

|         | Endpoint                                      |
| ------- | --------------------------------------------- |
| Mainnet | https://mainnet-explorer.fuel.network         |
| Testnet | https://explorer-indexer-testnet.fuel.network |

For more information about the API, please refer to the [Wiki](https://github.com/FuelLabs/fuel-explorer/wiki/Assets-API#) page.

## Asset by ID

We can request information about an asset by its asset ID, using the `getAssetById` function. This will leverage the endpoint `/assets/<assetId>` to fetch the asset information.

```
import type { AssetInfo } from 'fuels';
import { getAssetById } from 'fuels';

const asset: AssetInfo | null = await getAssetById({
  assetId: '0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07',
});

console.log('AssetInfo', asset);
// AssetInfo { ... }
```

By default, we will request the asset information for `mainnet`. If you want to request the asset information from other networks, you can pass the `network` parameter (this is the same for the [`getAssetsByOwner`](#assets-by-owner) function).

```
await getAssetById({
  assetId: '0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07',
  network: 'testnet',
});
```

## Assets by Owner

We can request information about an asset by its owner, using the `getAssetsByOwner` function. This will leverage the endpoint `/accounts/<owner>/assets` to fetch the asset information.

```
import type { AssetsByOwner } from 'fuels';
import { getAssetsByOwner } from 'fuels';

const assets: AssetsByOwner = await getAssetsByOwner({
  owner: '0x0000000000000000000000000000000000000000000000000000000000000000',
});

console.log('AssetsByOwner', assets);
// AssetsByOwner { data: [], pageInfo: { count: 0 } }
```

You can change the pagination parameters to fetch more assets (up to 100 assets per request).

```
await getAssetsByOwner({
  owner: '0x0000000000000000000000000000000000000000000000000000000000000000',
  pagination: { last: 100 },
});
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/utilities/date-conversion.md.md

# Date conversion

To allow for easier manipulation of date and time, the SDK exports the `DateTime` class which is a wrapper around the [built-in](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) `Date` class. Below we will go over the methods of instantiation, utility functions and time formats.

Internally the transactions and other time/date assets are encoded using the [`TAI64`](#tai-format) format. We return a `DateTime` class, to allow of easier conversion and formatting between the two formats.

## Instantiating a `DateTime`

We have a host of static method for **instantiation** of our `DateTime` class.

```
import { DateTime } from 'fuels';

const tai64: DateTime = DateTime.fromTai64('4611686020108779339');
const unixSeconds: DateTime = DateTime.fromUnixSeconds(1681391398);
const unixMilliseconds: DateTime = DateTime.fromUnixMilliseconds(1681391398000);
```

### TAI64

`fromTai64` is a _static_ method, that allows the creation of `DateTime` class from a `TAI64` string.

`toTai64` is an _instance_ method, that allows the conversion of a `DateTime` class to a `TAI64` string.

```
import { DateTime } from 'fuels';

const date: DateTime = DateTime.fromTai64('4611686020108779339');

const tai64: string = date.toTai64();
// "4611686020108779339"
```

### UNIX

`fromUnixMilliseconds` is a _static_ method, that allows the creation of `DateTime` class from a UNIX Milliseconds number.

`toUnixMilliseconds` is an _instance_ method, that allows the conversion of a `DateTime` class to a `UNIX` number in milliseconds.

```
import { DateTime } from 'fuels';

const date: DateTime = DateTime.fromUnixMilliseconds(1681391398000);

const unixMilliseconds: number = date.toUnixMilliseconds();
// 1681391398000
```

`fromUnixSeconds` is a _static_ method, that allows the creation of `DateTime` class from a UNIX Seconds number.

`toUnixSeconds` is an _instance_ method, that allows the conversion of a `DateTime` class to a `UNIX` number in seconds.

```
import { DateTime } from 'fuels';

const date: DateTime = DateTime.fromUnixSeconds(1681391398);

const unixSeconds: number = date.toUnixSeconds();
// 1681391398
```

### Date

The `DateTime` class extends the functionality of the `Date` object, so all method are available for your usages.

```
import { DateTime } from 'fuels';

const dateTime: DateTime = DateTime.fromUnixMilliseconds(1681391398000);

// Extends the Date object
const date: Date = dateTime;

// Date object methods
date.getTime(); // 1681391398000
date.toISOString(); // 2023-04-13T13:09:58.000Z
date.toDateString(); // Thu Apr 13 2023
```

## Formats

Here we will go over the different date/time formats that we use in the SDK. Internally the blockchain uses the `TAI64` format, but we also support the `UNIX` format for ease of use.

### UNIX Format

UNIX time is the number of seconds that have elapsed since **00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970**, minus leap seconds. Every day is treated as if it contains exactly 86400 seconds, so leap seconds are ignored.

### TAI Format

TAI stands for _Temps Atomique International_ and is the current international real-time standard [Source](https://cr.yp.to/libtai/tai64.html).

We use `TAI64` is a 64-bit integer representing the number of nanoseconds since the epoch.

- the TAI second beginning exactly _(2^62 - s) seconds_ before the beginning of 1970 TAI, if s is between 0 inclusive and 2^62 exclusive; or

- the TAI second beginning exactly _(2^62 + s) seconds_ after the beginning of 1970 TAI, if s is between -2^62 inclusive and 0 exclusive.

[Source](https://cr.yp.to/libtai/tai64.html)


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/utilities/index.md.md

# Utilities

Utilities are a set of helpers that can be used for various purposes.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/utilities/unit-conversion.md.md

# Unit conversion

Internally, we use [Arbitrary-precision](https://mathworld.wolfram.com/ArbitraryPrecision.html) arithmetic (also known as Big Number arithmetic) to allow for the handling of large numbers and different assets.

On the Fuel network, we work with 9 decimals to represent amounts under a unit. This differs from chain to chain, so it is important to know the number of decimals used on the chain you are working with.

> Note: The package [`@fuels/assets`](https://www.npmjs.com/package/@fuels/assets) provides a list of assets and their decimals.

Below we will go over some common use cases for unit conversion.

Using our `BN` class we can instantiate these numbers.

```
const myBigNumberOne = '100000000';

const resultOne = new BN('100000000').toString();
```

Or using our `bn` utility function.

```
const resultTwo = bn('100000000').toString();
```

## Contract calls

Generally, we will need to convert `u64` and `u256` numbers to a `BN` object when passing them to a Sway program from JavaScript. More information on this can be found [here](../types/numbers.md).

```
// Let's deploy a contract that has a function that takes a u64 as input
const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = await Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployedContract = await new EchoValuesFactory(wallet).deploy();
const { contract } = await deployedContract.waitForResult();

const MAX_U64 = bn('18446744073709551615');

const { waitForResult } = await contract.functions.echo_u64(MAX_U64).call();
const { value } = await waitForResult();
```

> Note: If a contract call returns a number that is too large to be represented as a JavaScript number, you can convert it to a string using the `toString` method instead of `toNumber`.

## Parsing

Parsing string-represented numbers (from user input) has never been easier, than using the `parseUnits` function.

```
const resultThree = bn.parseUnits('0.000000001').toString();
```

We can parse large numbers.

```
const myBigNumberFour = '100100000000000';
const resultFour = bn.parseUnits('100100').toString();
```

Or numbers formatted for human readability.

```
const myBigNumberFive = '100100000200001';

const resultFive = bn.parseUnits('100,100.000200001').toString();
```

We can also parse numbers in other units of measure.

```
const myBigNumberSix = '1000000000';

const resultSix = bn.parseUnits('1', DECIMAL_GWEI).toString();
```

## Formatting

We can format common units of measure using the `format` function.

In the following example, we format a BigNumber representation of one Gwei, into units for the Fuel network (with 3 decimal place precision).

```
const myBigNumberSeven = '1.000';
const oneGwei = bn('1000000000');

const resultSeven = oneGwei.format();
```

We can also format numbers in other units of measure by specifying the `units` variable.

```
const myBigNumberEight = '2.000';

const twoGwei = bn('2000000000');

const resultEight = twoGwei.format({ units: DECIMAL_GWEI });
```

A `precision` variable will allow for the formatting of numbers with a specific number of decimal places.

```
const oneDecimalGwei = '1.0';

const formattedGwei = oneGwei.format({ precision: 1 });
```

### Format units

The `formatUnits` function is a lesser alternative to the `format` function, as it will maintain the same precision as the input value.

```
const myFormattedGwei = '1.000000000';

const formattedUnitsGwei = oneGwei.formatUnits();
```

We can also format numbers in other units of measure by specifying the `units` variable.

```
const myFormattedKwei = '1.000000000000000';

const oneKwei = bn('1000000000000000');

const formattedUnitsKwei = oneKwei.formatUnits(DECIMAL_KWEI);
```

## See also

- [Sway Numbers](../types/numbers.md)

## Full Example

For the full example of unit conversion see the snippet below:

```
import { BN, DECIMAL_GWEI, DECIMAL_KWEI, bn, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';
import { EchoValuesFactory } from '../../../typegend/contracts/EchoValuesFactory';

// #region instantiation-1
const myBigNumberOne = '100000000';

const resultOne = new BN('100000000').toString();

// #endregion instantiation-1

const myBigNumberTwo = '100000000';

// #region instantiation-2

const resultTwo = bn('100000000').toString();
// #endregion instantiation-2

// #region contract-calls-1

// Let's deploy a contract that has a function that takes a u64 as input
const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = await Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployedContract = await new EchoValuesFactory(wallet).deploy();
const { contract } = await deployedContract.waitForResult();

const MAX_U64 = bn('18446744073709551615');

const { waitForResult } = await contract.functions.echo_u64(MAX_U64).call();
const { value } = await waitForResult();

// #endregion contract-calls-1

const myBigNumberThree = '1';

// #region parse-units-1
const resultThree = bn.parseUnits('0.000000001').toString();
// #endregion parse-units-1

// #endregion parse-units-1

// #region parse-units-2
const myBigNumberFour = '100100000000000';
const resultFour = bn.parseUnits('100100').toString();
// #endregion parse-units-2

// #endregion parse-units-3

// #region parse-units-3
const myBigNumberFive = '100100000200001';

const resultFive = bn.parseUnits('100,100.000200001').toString();
// #endregion parse-units-3

// #endregion parse-units-4

// #region parse-units-4
const myBigNumberSix = '1000000000';

const resultSix = bn.parseUnits('1', DECIMAL_GWEI).toString();
// #endregion parse-units-4

// #region format-1
const myBigNumberSeven = '1.000';
const oneGwei = bn('1000000000');

const resultSeven = oneGwei.format();
// #endregion format-1

// #region format-2
const myBigNumberEight = '2.000';

const twoGwei = bn('2000000000');

const resultEight = twoGwei.format({ units: DECIMAL_GWEI });
// #endregion format-2

// #region format-3
const oneDecimalGwei = '1.0';

const formattedGwei = oneGwei.format({ precision: 1 });
// #endregion format-3

// #region format-units-1
const myFormattedGwei = '1.000000000';

const formattedUnitsGwei = oneGwei.formatUnits();
// #endregion format-units-1

// #region format-units-2
const myFormattedKwei = '1.000000000000000';

const oneKwei = bn('1000000000000000');

const formattedUnitsKwei = oneKwei.formatUnits(DECIMAL_KWEI);
// #endregion format-units-2
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/utilities/using-assets.md.md

# Assets

We export an array of [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html) objects, that can be useful when creating your dApp. The `Asset` object has useful metadata about the different assets that are available on blockchain networks (Fuel and Ethereum).

Included assets such as:

- Ethereum (ETH)
- Tether (USDT)
- USD Coin (USDC)
- Wrapped ETH (WETH)

The helper functions `getAssetFuel` and `getAssetEth` can be used to get an asset's details relative to each network. These return a combination of the asset, and network information (the return types are [`AssetFuel`](DOCS_API_URL/types/_fuel_ts_account.AssetFuel.html) and [`AssetEth`](DOCS_API_URL/types/_fuel_ts_account.AssetEth.html) respectively).

```
import type { Asset, AssetFuel } from 'fuels';
import { assets, CHAIN_IDS, getAssetFuel, Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient = Wallet.generate({ provider });

// Find the asset with symbol 'ETH'
const assetEth: Asset = assets.find((asset) => asset.symbol === 'ETH')!;

// Get all the metadata for ETH on Fuel Test Network
const chainId: number = CHAIN_IDS.fuel.testnet;
const assetEthOnFuel: AssetFuel = getAssetFuel(assetEth, chainId)!;

// Send a transaction (using the asset on Fuel Test Network)
const transaction = await sender.transfer(
  recipient.address,
  100,
  assetEthOnFuel.assetId
);
await transaction.waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/checking-balances.md.md

# Checking balances

To check the balance of a specific asset, you can use [`getBalance`](DOCS_API_URL/classes/_fuel_ts_account.Account.html#getBalance) method. This function aggregates the amounts of all unspent coins of the given asset in your wallet.

```
import type { BN } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const myWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// The returned amount is a BigNumber
const balance: BN = await myWallet.getBalance(await provider.getBaseAssetId());
```

To retrieve the balances of all assets in your wallet, use the [`getBalances`](DOCS_API_URL/classes/_fuel_ts_account.Account.html#getBalances) method, it returns an array of [`CoinQuantity`](DOCS_API_URL/types/_fuel_ts_account.CoinQuantity.html). This is useful for getting a comprehensive view of your holdings.

```
import { Provider, Wallet } from 'fuels';

import { WALLET_PVT_KEY_2, LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const myOtherWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const { balances } = await myOtherWallet.getBalances();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/connectors.md.md

# Connectors

Fuel Wallet Connectors offer a standardized interface to integrate multiple wallets with your DApps, simplifying wallet integration and ensuring smooth user interactions.

## Fuel Connectors

`Fuel Connectors` are a set of standardized interfaces that provide a way to interact with various wallets and services. They offer a consistent way to interact with different wallets and services, allowing developers to focus on building their applications rather than worrying about wallet integration.

To build your own wallet integration, you can create a custom connector that extends the abstract [`FuelConnector`](DOCS_API_URL/classes/_fuel_ts_account.FuelConnector.html) class. This interface provides a set of methods and events that allow you to interact with the wallet and handle various operations such as connecting, disconnecting, signing messages, and sending transactions.

```
class MyWalletConnector extends FuelConnector
```

### Properties

The `FuelConnector` abstract class provides several properties that should be implemented to provide information about the connector.

#### `name`

The `name` property is simply a `string` on the connector that serves as an identifier and will be displayed to the end-user when selecting a connector.

```
  public override name: string = 'My Wallet Connector';
```

### `external`

The `external` property is simply a `boolean` that indicates when a connector is external or not.
Connectors are considered external, or non-native, when they do not support the Fuel Network (e.g. `Solana`, `WalletConnect`).

#### `metadata`

The `metadata` property on the connector provides additional information about the connector. This information will be displayed to the end-user when selecting a connector. The following is the structure of the `metadata` object:

```
export type ConnectorMetadata = {
  image?:
    | string
    | {
        light: string;
        dark: string;
      };
  install: {
    action: string;
    link: string;
    description: string;
  };
};
```

##### `install`

The `metadata.install` property (_required_) is used to provide information about how to install the connector.

The `install` object requires three properties:

- `action` (_required_) - a `string` that will contain an action string that will be displayed to the user (e.g. "Install").

- `link` (_required_) - a `string` that will contain a URL that will be opened when the user clicks the action.

- `description` (_required_) - a `string` that will contain a description of the installation process.

```
  install: {
    action: 'Install',
    description: 'Install the My Wallet Connector',
    link: 'https://example.com/install',
  },
```

##### `image`

The `metadata.image` property (_optional_) provides an image that will be displayed to the end-user when selecting a connector. The image will be a URL to the image to be displayed (this can be an inline data URI, encoded in base64).

```
  image: 'https://example.com/image.png',
```

You can even define a `light` and `dark` theme for the image by providing an object with the `light` and `dark` keys (these will take a similar URI as above).

```
  image: {
    light: 'https://example.com/light.png',
    dark: 'https://example.com/dark.png',
  },
```

### Events

The `FuelConnector` class provides a number of events that enable developers to listen for changes in the connector state. As part of implementing a custom connector, you can emit these events to notify the consumer dApp of changes.

#### `accounts`

The `accounts` event is emitted every time a connector's accounts change. The event data is an array of `string` addresses available on the network.

```
    const accounts: Array<string> = ['0x1234567890abcdef'];

    this.emit(this.events.accounts, accounts);
```

#### `connectors`

The `connectors` event is emitted when the connectors are initialized. The event data is an array of [`FuelConnector`](DOCS_API_URL/classes/_fuel_ts_account.FuelConnector.html) objects available on the network.

```
    const connectors: Array<FuelConnector> = [new MyWalletConnector()];

    this.emit(this.events.connectors, connectors);
```

#### `currentConnector`

The `currentConnector` event is emitted every time the current connector changes. The event data is a [`FuelConnector`](DOCS_API_URL/classes/_fuel_ts_account.FuelConnector.html) object that is currently connected.

```
    const currentConnector: FuelConnector = new MyWalletConnector();

    this.emit(this.events.currentConnector, currentConnector);
```

#### `currentAccount`

The `currentAccount` event is emitted every time the current account changes. The event data is a string containing the current account address.

```
    const currentAccount: string = '0x1234567890abcdef';

    this.emit(this.events.currentAccount, currentAccount);
```

#### `connection`

The `connection` event is emitted every time the connection status changes. The event data is a `boolean` value that is `true` if the connection is established and `false` otherwise.

```
    const connection: boolean = true;

    this.emit(this.events.connection, connection);
```

#### `networks`

The `networks` event is emitted every time the network changes. The event data will be a [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html) object containing the current network information.

```
    const network: Network = {
      chainId: 1,
      url: 'https://example.com/rpc',
    };

    this.emit(this.events.networks, network);
```

#### `currentNetwork`

The `currentNetwork` event is emitted every time the current network changes. The event data will be a [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html) object containing the current network information.

```
    const currentNetwork: Network = {
      chainId: 1,
      url: 'https://example.com/rpc',
    };

    this.emit(this.events.currentNetwork, currentNetwork);
```

#### `assets`

The `assets` event is emitted every time the assets change. The event data will be an array of [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html) objects available on the network.

```
    const assets: Array<Asset> = [
      {
        name: 'Ethereum',
        symbol: 'ETH',
        icon: 'https://assets.fuel.network/providers/eth.svg',
        networks: [
          {
            type: 'ethereum',
            chainId: 11155111,
            decimals: 18,
          },
        ],
      },
    ];

    this.emit(this.events.assets, assets);
```

#### `abis`

The `abis` event is emitted every time an ABI is added to a connector. The event data will be an array of [`FuelABI`](DOCS_API_URL/types/_fuel_ts_account.FuelABI.html) object.

```
    const assets: Array<Asset> = [
      {
        name: 'Ethereum',
        symbol: 'ETH',
        icon: 'https://assets.fuel.network/providers/eth.svg',
        networks: [
          {
            type: 'ethereum',
            chainId: 11155111,
            decimals: 18,
          },
        ],
      },
    ];

    this.emit(this.events.assets, assets);
```

### Methods

The `FuelConnector` abstract class provides a number of methods that _can_ be implemented to perform various functions. Not all the methods are required to be implemented; if you choose not to implement a given method, then just don't include it in your connector.

#### `ping`

The `ping` method is used to check if the connector is available and connected.

It will return a promise that resolves to `true` if the connector is available and connected; otherwise, it will resolve to `false`.

```
  ping(): Promise<boolean>;
```

#### `version`

The `version` method is used to get the current supported version of the connector. It returns a promise that resolves to an object containing the `app` and `network` versions.

The returned version strings can be in a range of formats:

- Caret Ranges (e.g. `^1.2.3`)
- Tilde Ranges (e.g. `~1.2.3`)
- Exact Versions (e.g. `1.2.3`)

```
  version(): Promise<Version>;
```

#### `isConnected`

The `isConnected` method informs if the connector is currently connected.

It will return a promise that resolves to `true` if the connector is established and currently connected; otherwise, it will return `false`.

```
  isConnected(): Promise<boolean>;
```

#### `connect`

The `connect` method initiates the current connectors authorization flow if a connection has not already been made.

It will return a promise that resolves to `true` if the connection has been established successfully, or `false` if the user has rejected it.

```
  connect(): Promise<boolean>;
```

#### `disconnect`

The `disconnect` method revokes the authorization of the current connector (provided by the `connect` methods).

It will return a promise that resolves to `true` if the disconnection is successful; otherwise, it will resolve to `false`.

```
  connect(): Promise<boolean>;
```

#### `accounts`

The `accounts` method should return a list of all the accounts for the current connection.

It returns a promise that resolves to an array of addresses, pointing to the accounts currently available on the network.

```
  accounts(): Promise<Array<string>>;
```

#### `currentAccount`

The `currentAccount` method will return the default account address if it's authorized with the connection.

It will return a promise to resolve the issue to an address, or if the account is not authorized for the connection, it will return `null`.

```
  currentAccount(): Promise<string | null>;
```

#### `signMessage`

The `signMessage` method initiates the sign message flow for the current connection.

It requires two arguments:

- `address` (`string`)
- `message` (`string`)

Providing the message signing flow is successful, it will return the message signature (as a `string`).

```
  signMessage(address: string, message: HashableMessage): Promise<string>;
```

#### `sendTransaction`

The `signTransaction` method initiates the send transaction flow for the current connection.

It requires two arguments:

- `address` (`string`)
- `transaction` ([`TransactionRequestLike`](DOCS_API_URL/types/_fuel_ts_account.TransactionRequestLike.html))

It will return the transaction signature (as a `string`) if it is successfully signed.

```
  sendTransaction(
    address: string,
    transaction: TransactionRequestLike,
    params?: FuelConnectorSendTxParams
  ): Promise<string | TransactionResponse>;
```

#### `assets`

The `assets` method returns a list of all the assets available for the current connection.

It will return a promise that will resolve to an array of assets (see [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html)) that are available on the network.

```
  assets(): Promise<Array<Asset>>;
```

#### `addAsset`

The `addAsset` method adds asset metadata to the connector.

It requires a single argument:

- `asset` ([`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html))

It returns a promise that resolves to `true` if the asset is successfully added; otherwise, it resolves to `false`.

```
  addAssets(assets: Array<Asset>): Promise<boolean>;
```

#### `addAssets`

The `addAssets` method adds multiple asset metadata to the connector.

It requires a single argument:

- `assets` (an Array of [`Asset`](DOCS_API_URL/types/_fuel_ts_account.Asset.html)).

Returns a promise that resolves to `true` if the assets are successfully added; otherwise, resolves to `false`.

```
  addAssets(assets: Array<Asset>): Promise<boolean>;
```

#### `addNetwork`

The `addNetwork` method starts the add network flow for the current connection.

It requires a single argument:

- `networkUrl` (`string`)

Returns a promise that resolves to `true` if the network is successfully added; otherwise, `false`.

It should throw an error if the network is not available or the network already exists.

```
  addNetwork(networkUrl: string): Promise<boolean>;
```

#### `networks`

The `networks` method returns a list of all the networks available for the current connection.

Returns a promise that resolves to an array of available networks (see [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html)).

```
  networks(): Promise<Array<Network>>;
```

#### `currentNetwork`

The `currentNetwork` method will return the current network that is connected.

It will return a promise that will resolve to the current network (see [`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html)).

```
  currentNetwork(): Promise<Network>;
```

#### `selectNetwork`

The `selectNetwork` method requests the user to select a network for the current connection.

It requires a single argument:

- `network` ([`Network`](DOCS_API_URL/types/_fuel_ts_account.Network.html))

You call this method with either the `providerUrl` or `chainId` to select the network.

It will return a promise that resolves to `true` if the network is successfully selected; otherwise, it will return `false`.

It should throw an error if the network is not available or the network does _not_ exist.

```
  selectNetwork(network: SelectNetworkArguments): Promise<boolean>;
```

#### `addABI`

The `addABI` method adds ABI information about a contract to the connector. This operation does not require an authorized connection.

It requires two arguments:

- `contractId` (`string`)
- `abi` ([`FuelABI`](DOCS_API_URL/types/_fuel_ts_account.FuelABI.html)).

It will return a promise that will resolve to `true` if the ABI is successfully added; otherwise `false`.

```
  addABI(contractId: string, abi: FuelABI): Promise<boolean>;
```

#### `getABI`

The `getABI` method is used to get the ABI information that is sorted about a contract.

It requires a single argument:

- `contractId` (`string`)

Returns a promise that resolves to the ABI information (as a [`FuelABI`](DOCS_API_URL/types/_fuel_ts_account.FuelABI.html)) or `null` if the data is unavailable.

```
  getABI(contractId: string): Promise<FuelABI | null>;
```

#### `hasABI`

The `hasABI` method checks if the ABI information is available for a contract.

It requires a single argument:

- `contractId` (`string`)

Returns a promise that resolves to `true` if the ABI information is available; otherwise `false`.

```
  hasABI(contractId: string): Promise<boolean>;
```

## Connectors Manager

The TS SDK exports the `Fuel` class, which serves as the connectors manager. This class provides the interface for interacting with the TS SDK and the broader Fuel ecosystem.

It can be instantiated as follows:

```
const sdk = new Fuel();

/*
	Awaits for initialization to mitigate potential race conditions
	derived from the async nature of instantiating a connector.
*/
await sdk.init();
```

> [!NOTE] Note
> We recommend initializing the Fuel class with the `init` method to avoid any potential race conditions that may arise from the async nature of instantiating a connector.

### Options

Several options can be passed to the `Fuel` connector manager:

- [`connectors`](#connectors)
- [`storage`](#storage)
- [`targetObject`](#targetobject)

#### `connectors`

The `connectors` option provides a list of connectors with which the `Fuel` connector manager can interact. The manager interacts with the connectors, which in turn handle communication with the respective wallet. You can find a list of all the connectors in our [`FuelLabs/fuel-connectors`](https://github.com/FuelLabs/fuel-connectors).

Below, we initialize the manager using the `defaultConnectors` method which provides an array of all the default connectors available in the `fuel-connectors` package. It's being mocked here for the purposes of this example, but you can provide your own custom connectors. Supplying the `devMode` flag as `true` will enable the development wallet for the connectors (to install visit our [wallet documentation](https://docs.fuel.network/docs/wallet/install/)).

```
import { Fuel, FuelConnector } from 'fuels';

class WalletConnector extends FuelConnector {
  public override name: string = 'My Wallet Connector';
}

const defaultConnectors = (_opts: {
  devMode: boolean;
}): Array<FuelConnector> => [new WalletConnector()];

const sdkDevMode = await new Fuel({
  connectors: defaultConnectors({
    devMode: true,
  }),
}).init();
```

#### `storage`

The `storage` is used internally to store the current connector state. It can be overridden by passing an instance that extends the `StorageAbstract` class.

```
import { Fuel, MemoryStorage } from 'fuels';

const sdkWithMemoryStorage = await new Fuel({
  storage: new MemoryStorage(),
}).init();
```

The default behavior will use `LocalStorage` if the `window` is available:

```
import { Fuel, LocalStorage } from 'fuels';

const window = {
  localStorage: {
    setItem: vi.fn(),
    getItem: vi.fn(),
    removeItem: vi.fn(),
    clear: vi.fn(),
  } as unknown as Storage,
};

const sdkWithLocalStorage = await new Fuel({
  storage: new LocalStorage(window.localStorage),
}).init();
```

#### `targetObject`

The `targetObject` provides a target with which the `Fuel` manager can interact. Used for registering events and can be overridden as follows:

```
import { Fuel } from 'fuels';
import type { TargetObject } from 'fuels';

const emptyWindow = {} as unknown as TargetObject;

const targetObject: TargetObject = emptyWindow || document;

const sdkWithTargetObject = await new Fuel({
  targetObject,
}).init();
```

### Methods

The `Fuel` manager provides several methods to interact with the Manager:

#### All methods from connectors

The `Fuel` manager provides all the [methods](#methods) available from the connected connectors. Thus, you can interact with the current connector as if you were interacting with the `Fuel` manager directly.

If no current connector is available or connected, it will throw an error.

#### `connectors`

The `connectors` method gets the current list of _installed_ and _connected_ connectors.

```
  connectors: () => Promise<Array<FuelConnector>>;
```

#### `getConnector`

The `getConnector` method resolves a connector by its name. This is useful for finding a specific connector with which to interact. If the connector is not found, it will return `null`.

```
  getConnector: (connector: FuelConnector | string) => FuelConnector | null;
```

#### `hasConnector`

The `hasConnector` method will return `true` under the following conditions:

- There is a current connector that is connected.
- A connector is connected within two seconds of calling the method.

```
  hasConnector(): Promise<boolean>;
```

#### `selectConnector`

The `selectConnector` method accepts a connector name and will return `true` when it is _available_ and _connected_. Otherwise, if not found or unavailable, it will return `false`.

```
  selectConnector(connectorName: string, options: FuelConnectorSelectOptions): Promise<boolean>;
```

#### `currentConnector`

The `currentConnector` method will return the current connector that is connected or if one is available and connected, otherwise it'll return `null` or `undefined`.

```
  currentConnector(): FuelConnector | null | undefined;
```

#### `getWallet`

The `getWallet` method accepts an address (string or instance) as the first parameter and a provider or network as the second parameter. It will return an `Account` instance for the given address (providing it is valid).

The provider or network will default to the current network if not provided. When a provider cannot be resolved, it will throw an [`INVALID_PROVIDER`](../errors/index.md) error.

```
  getWallet(address: string | Address, providerOrNetwork?: Provider | Network): Promise<Account>;
```

#### `clean`

The `clean` method removes all the data currently stored in the [`storage`](#storage) instance.

```
  clean(): Promise<void>;
```

#### `unsubscribe`

The `unsubscribe` method removes all currently registered event listeners.

```
  unsubscribe(): void;
```

#### `destroy`

The `destroy` method unsubscribes from all the event listeners and clears the storage.

```
  destroy(): Promise<void>;
```

## Learning Resources

For a deeper understanding of `Fuel Connectors` and how to start using them in your projects, consider the following resources:

- [**Fuel Connectors Wiki**](https://github.com/FuelLabs/fuel-connectors/wiki) - read about what a `Fuel Connector` is and how it works.
- [**Fuel Connectors Guide**](https://docs.fuel.network/docs/wallet/dev/connectors/) - find out how to set up and use connectors.
- [**GitHub Repository**](https://github.com/FuelLabs/fuel-connectors) - explore different connector implementations.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/encrypting-and-decrypting.md.md

# Encrypting and Decrypting

JSON wallets are a standardized way of storing wallets securely. They follow a specific schema and are encrypted using a password. This makes it easier to manage multiple wallets and securely store them on disk. This guide will take you through the process of encrypting and decrypting JSON wallets using the Typescript SDK.

## Encrypting a Wallet

We will be calling `encrypt` from the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instance which will take a password as the argument. It will encrypt the private key using a cipher and returns the JSON keystore wallet. You can then securely store this JSON wallet.

Here is an example of how you can accomplish this:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet = Wallet.generate({ provider });

// Encrypt the wallet
const password = 'my-password';
const jsonWallet = await wallet.encrypt(password);

// Save the encrypted wallet to a file
// e.g. const jsonWallet = fs.writeFileSync('secure-path/my-wallet.json', jsonWallet);
```

Please note that `encrypt` must be called within an instance of [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html). This instance can only be achieved through passing a private key or mnemonic phrase to a locked wallet.

## Decrypting a Wallet

To decrypt the JSON wallet and retrieve your private key, you can call `fromEncryptedJson` on a [Wallet](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html) instance. It takes the encrypted JSON wallet and the password as its arguments, and returns the decrypted wallet.

Here is an example:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const newJsonWallet = await Wallet.generate({
  provider,
}).encrypt('my-password');

// Load the encrypted wallet from a file
// const jsonWallet = fs.readFileSync('secure-path/my-wallet.json', 'utf-8');

// Decrypt the wallet
const newPassword = 'my-password';
const decryptedWallet = await Wallet.fromEncryptedJson(
  newJsonWallet,
  newPassword,
  provider
);

// Use the decrypted wallet
const myBalance = await decryptedWallet.getBalance();
```

In this example, `decryptedWallet` is an instance of [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) class, now available for use.

## Important

Remember to securely store your encrypted JSON wallet and password. If you lose them, there will be no way to recover your wallet. For security reasons, avoid sharing your private key, encrypted JSON wallet or password with anyone.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/index.md.md

# Wallets

Wallets can be used for many important things, for instance:

1. Checking your balance;
2. Transferring coins to a destination address or contract;
3. Signing messages and transactions;
4. Paying for network fees when sending transactions or deploying smart contracts.

## Wallets Instances

The SDK has multiple classes related to a Wallet instance:

- [Wallet](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html): Works simply like a wrapper providing methods to create and instantiating `WalletUnlocked` and `WalletLocked` instances.

- [WalletLocked](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html): Provides the functionalities for a locked wallet.

- [WalletUnlocked](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html): Provides the functionalities for an unlocked wallet.

- [Account](DOCS_API_URL/classes/_fuel_ts_account.Account.html): Provides an abstraction with basic functionalities for wallets or accounts to interact with the network. It is essential to notice that both `WalletLocked` and `WalletUnlocked` extend from the `Account` class.

Let's explore these different approaches in the following sub-chapters.

> **Note:** Keep in mind that you should never share your private/secret key. And in the case of wallets that were derived from a mnemonic phrase, never share your mnemonic phrase. If you're planning on storing the wallet on disk, do not store the plain private/secret key and do not store the plain mnemonic phrase. Instead, use `WalletManager` to encrypt its content first before saving it to disk.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/instantiating-wallets.md.md

# Instantiating Wallets

Wallets can be instantiated in multiple ways within the SDK.

## Generating new wallets

To generate a new, unlocked wallet, use the [`generate`](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html#generate) method. This method creates a new [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instance, which is immediately ready for use.

```
import { Wallet } from 'fuels';
import type { WalletUnlocked } from 'fuels';

const wallet: WalletUnlocked = Wallet.generate();
```

## Instantiating Unlocked Wallets

Creating [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instances of your existing wallets is easy and can be done in several ways:

From a private key:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const privateKey =
  '0x36ca81ba70f3e04b7cc8780bff42d907ebca508097d4ae3df5147c93fd217f7c';

const wallet: WalletUnlocked = Wallet.fromPrivateKey(privateKey);
```

From a mnemonic phrase:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const mnemonic =
  'section gospel lady april mouse huge prosper boy urge fox tackle orient';

const wallet: WalletUnlocked = Wallet.fromMnemonic(mnemonic);
```

From a seed:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const seed =
  '0xa5d42fd0cf8825fc846b2f257887a515573ee5b779e99f060dc945b3d5504bca';

const wallet: WalletUnlocked = Wallet.fromSeed(seed);
```

From a Hierarchical Deterministic (HD) derived key:

```
import type { WalletUnlocked } from 'fuels';
import { HDWallet, Wallet } from 'fuels';

const seed =
  '0xa5d42fd0cf8825fc846b2f257887a515573ee5b779e99f060dc945b3d5504bca';

const extendedKey = HDWallet.fromSeed(seed).toExtendedKey();

const wallet: WalletUnlocked = Wallet.fromExtendedKey(extendedKey);
```

From a JSON wallet:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const jsonWallet = `{"id":"83d1792f-3230-496a-92af-3b44a1524fd6","version":3,"address":"ada436e1b80f855f94d678771c384504e46335f571aa244f11b5a70fe3e61644","crypto":{"cipher":"aes-128-ctr","mac":"6911499ec31a6a6d240220971730374396efd666bd34123d4e3ce85e4cf248c6","cipherparams":{"iv":"40576cbd4f7c84e88b0532320e23b425"},"ciphertext":"3e5e77f23444aa86b397dbc62e14d8b7d3fd7c7fe209e066bb7df17eca398129","kdf":"scrypt","kdfparams":{"dklen":32,"n":8192,"p":1,"r":8,"salt":"b046520d85090ee2abd6285174f37bc01e28846b6bb5edc03ae5f7c13aec03d2"}}}`;

const password = 'password';

const wallet: WalletUnlocked = await Wallet.fromEncryptedJson(
  jsonWallet,
  password
);
```

It's possible to instantiate a `WalletUnlocked` from a `WalletLocked`:

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

const address =
  '0x4cb2b5d2bdbcc8dbdbf91cd00be3e2deedb0ea0f34c969c0ed741a1925111a87';
const privateKey =
  '0x9deba03f08676716e3a4247797672d8008a5198d183048be65415ef89447b890';

const lockedWallet: WalletLocked = Wallet.fromAddress(address);

const wallet: WalletUnlocked = lockedWallet.unlock(privateKey);
```

## Instantiating Locked Wallets

You can also instantiate [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) instances using just the wallet address:

```
import type { B256Address, WalletLocked } from 'fuels';
import { Wallet } from 'fuels';

const address: B256Address = `0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f`;

const wallet: WalletLocked = Wallet.fromAddress(address);
```

## Connecting to a Provider

While wallets can be used independently of a [`Provider`](DOCS_API_URL/classes/_fuel_ts_account.Provider.html), operations requiring blockchain interaction will need one.

Connecting an existing wallet to a Provider:

```
import type { WalletLocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_ADDRESS } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet: WalletLocked = Wallet.fromAddress(WALLET_ADDRESS);
wallet.connect(provider);
```

Instantiating a wallet with a Provider:

```
import type { WalletLocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_ADDRESS } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const wallet: WalletLocked = Wallet.fromAddress(WALLET_ADDRESS, provider);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/locking-and-unlocking.md.md

# Locking and Unlocking

The kinds of operations we can perform with a [`Wallet`](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html) instance depend on
whether or not we have access to the wallet's private key.

In order to differentiate between [`Wallet`](DOCS_API_URL/classes/_fuel_ts_account.Wallet.html) instances that know their private key
and those that do not, we use the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) and [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) types
respectively.

## Wallet States

The [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) type represents a wallet whose private key is known and
stored internally in memory. A wallet must be of type [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) in order
to perform operations that involve [signing messages or transactions](./signing.md).

The [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) type represents a wallet whose private key is _not_ known or stored
in memory. Instead, [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) only knows its public address. A [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) cannot be
used to sign transactions, however it may still perform a whole suite of useful
operations including listing transactions, assets, querying balances, and so on.

Note that the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) type implements most methods available on the [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html)
type. In other words, [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) can be thought of as a thin wrapper around [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) that
provides greater access via its private key.

## Basic Example

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
```

## Optional Provider

You can choose not to pass through a provider argument on `Wallet` construction:

```
import type { WalletUnlocked } from 'fuels';
import { Wallet } from 'fuels';

// You can create a wallet, without a provider
let unlockedWalletWithoutProvider: WalletUnlocked = Wallet.generate();
unlockedWalletWithoutProvider = Wallet.fromPrivateKey(
  unlockedWalletWithoutProvider.privateKey
);

// All non-provider dependent methods are available
unlockedWalletWithoutProvider.lock();

// All provider dependent methods will throw
try {
  await unlockedWalletWithoutProvider.getCoins();
} catch (e) {
  console.log('error', e);
}
```

## Transitioning States

A [`WalletLocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletLocked.html) instance can be unlocked by providing the private key:

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const wallet: WalletUnlocked = Wallet.generate({ provider });
const PRIVATE_KEY = wallet.privateKey;

// Lock an existing wallet
const lockedWallet: WalletLocked = Wallet.fromAddress(wallet.address, provider);

// Unlock an existing wallet
const someUnlockedWallet: WalletUnlocked = lockedWallet.unlock(PRIVATE_KEY);
```

A [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) instance can be locked using the `lock` method:

```
import type { WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

const unlockedWallet: WalletUnlocked = Wallet.generate({ provider });
const newlyLockedWallet = unlockedWallet.lock();
```

Most wallet constructors that create or generate a new wallet are provided on
the [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) type. Consider locking the wallet with the `lock` method after the new private
key has been handled in order to reduce the scope in which the wallet's private
key is stored in memory.

## Design Guidelines

When designing APIs that accept a wallet as an input, we should think carefully
about the kind of access that we require. API developers should aim to minimise
their usage of [`WalletUnlocked`](DOCS_API_URL/classes/_fuel_ts_account.WalletUnlocked.html) in order to ensure private keys are stored in
memory no longer than necessary to reduce the surface area for attacks and
vulnerabilities in downstream libraries and applications.

## Full Example

For a full example of how to lock and unlock a wallet, see the snippet below:

```
// #region wallets
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
// #endregion wallets

const wallet: WalletUnlocked = Wallet.generate({ provider });
const PRIVATE_KEY = wallet.privateKey;

// Lock an existing wallet
const lockedWallet: WalletLocked = Wallet.fromAddress(
  myWallet.address,
  provider
);

// Unlock an existing wallet
const someUnlockedWallet: WalletUnlocked = lockedWallet.unlock(PRIVATE_KEY);

const unlockedWallet: WalletUnlocked = Wallet.generate({ provider });
const newlyLockedWallet = unlockedWallet.lock();

// You can create a wallet, without a provider
let unlockedWalletWithoutProvider: WalletUnlocked = Wallet.generate();
unlockedWalletWithoutProvider = Wallet.fromPrivateKey(
  unlockedWalletWithoutProvider.privateKey
);

// All non-provider dependent methods are available
unlockedWalletWithoutProvider.lock();

// All provider dependent methods will throw
await expect(() => unlockedWalletWithoutProvider.getCoins()).rejects.toThrow(
  /Provider not set/
);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/mnemonic-wallet.md.md

# Creating a wallet from mnemonic phrases

A mnemonic phrase is a cryptographically-generated sequence of words that's used to derive a private key. For instance: `"oblige salon price punch saddle immune slogan rare snap desert retire surprise";` would generate the address `0xdf9d0e6c6c5f5da6e82e5e1a77974af6642bdb450a10c43f0c6910a212600185`.

In addition to that, we also support [Hierarchical Deterministic Wallets](https://www.ledger.com/academy/crypto/what-are-hierarchical-deterministic-hd-wallets) and [derivation paths](https://learnmeabitcoin.com/technical/derivation-paths), allowing multiple wallets to be derived from a single root mnemonic. You may recognize a derivation path like:

```text
"m/44'/1179993420'/0'/0/0"
```

In simple terms, this structure enables the creation of multiple wallet addresses from the same mnemonic phrase.

The SDK gives you two wallets from mnemonic instantiation methods: one that takes a derivation path and one that uses the default derivation path, in case you don't want or don't need to configure that.

Here's how you can create wallets with both mnemonic phrases and derivation paths:

1 - Using the default derivation path `m/44'/1179993420'/0'/0/0`

```
const mnemonic =
  'oblige salon price punch saddle immune slogan rare snap desert retire surprise';

const wallet = Wallet.fromMnemonic(mnemonic);
```

2 - Using a Custom Derivation Path

```
const mnemonic =
  'oblige salon price punch saddle immune slogan rare snap desert retire surprise';

const path = "m/44'/60'/1'/0/0";

const wallet = Wallet.fromMnemonic(mnemonic, path);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/private-keys.md.md

# Creating a wallet from a private key

A new wallet with a randomly generated private key can be created by supplying `Wallet.generate`.

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL } from '../../../env';

// We can use the `generate` to create a new unlocked wallet.
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet: WalletUnlocked = Wallet.generate({ provider });

// or use an Address to create a wallet
const someWallet: WalletLocked = Wallet.fromAddress(myWallet.address, provider);
```

Alternatively, you can create a wallet from a Private Key:

```
import type { WalletLocked, WalletUnlocked } from 'fuels';
import { Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_ADDRESS,
  WALLET_PVT_KEY,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);

// Generate a locked wallet
const lockedWallet: WalletLocked = Wallet.fromAddress(WALLET_ADDRESS, provider);

// Unlock an existing unlocked wallet
let unlockedWallet: WalletUnlocked = lockedWallet.unlock(WALLET_PVT_KEY);
// Or directly from a private key
unlockedWallet = Wallet.fromPrivateKey(WALLET_PVT_KEY);
```

You can obtain an address to a private key using the `Signer` package

```
import { Signer } from 'fuels';

import { WALLET_PVT_KEY } from '../../../../env';

const signer = new Signer(WALLET_PVT_KEY);
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/signing.md.md

# Signing

## Signing Messages

Signing messages with a wallet is a fundamental security practice in a blockchain environment. It can be used to verify ownership and ensure the integrity of data.

Here's how to use the `wallet.signMessage` method to sign messages (as string):

```
import { hashMessage, Signer, WalletUnlocked } from 'fuels';

const wallet = WalletUnlocked.generate();

const message: string = 'my-message';
const signedMessage = await wallet.signMessage(message);
// Example output: 0x277e1461cbb2e6a3250fa8c490221595efb3f4d66d43a4618d1013ca61ca56ba

const hashedMessage = hashMessage(message);
// Example output: 0x40436501b686546b7c660bb18791ac2ae35e77fbe2ac977fc061922b9ec83766

const recoveredAddress = Signer.recoverAddress(hashedMessage, signedMessage);
// Example output: Address {
//   b256Address: '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'
// }
```

The `signMessage` method internally:

- Hashes the message (via `hashMessage`)
- Signs the hashed message using the wallet's private key
- Returns the signature as a hex string

The `hashMessage` helper will:

- Performs a SHA-256 hash on the UTF-8 encoded message.

The `recoverAddress` method from the `Signer` class will take the hashed message and the signature to recover the signer's address. This confirms that the signature was created by the holder of the private key associated with that address, ensuring the authenticity and integrity of the signed message.

## Signing Personal Message

We can also sign arbitrary data, not just strings. This is possible by passing an object containing the `personalSign` property to the `hashMessage` and `signMessage` methods:

```
const message: string | Uint8Array = Uint8Array.from([0x01, 0x02, 0x03]);
const signedMessage = await wallet.signMessage({ personalSign: message });
// Example output: 0x0ca4ca2a01003d076b4044e38a7ca2443640d5fb493c37e28c582e4f2b47ada7

const hashedMessage = hashMessage({ personalSign: message });
// Example output: 0x862e2d2c46b1b52fd65538c71f7ef209ee32f4647f939283b3dd2434cc5320c5
```

The primary difference between this [personal message signing](#signing-personal-message) and [message signing](#signing-messages) is the underlying hashing format.

To format the message, we use a similar approach to a [EIP-191](https://eips.ethereum.org/EIPS/eip-191):

```console
\x19Fuel Signed Message:\n<message length><message>
```

> **Note**: We still hash using `SHA-256`, unlike Ethereum's [EIP-191](https://eips.ethereum.org/EIPS/eip-191) which uses `Keccak-256`.

## Signing Transactions

Signing a transaction involves using your wallet to sign the transaction ID (also known as [transaction hash](https://docs.fuel.network/docs/specs/identifiers/transaction-id/)) to authorize the use of your resources. Here's how it works:

1. `Generate a Signature`: Using the wallet to create a signature based on the transaction ID.

2. `Using the Signature on the transaction`: Place the signature in the transaction's `witnesses` array. Each Coin / Message input should have a matching `witnessIndex`. This index indicates your signature's location within the `witnesses` array.

3. `Security Mechanism`: The transaction ID is derived from the transaction bytes (excluding the `witnesses`). If the transaction changes, the ID changes, making any previous signatures invalid. This ensures no unauthorized changes can be made after signing.

The following code snippet exemplifies how a Transaction can be signed:

```
import {
  Address,
  Provider,
  ScriptTransactionRequest,
  Signer,
  Wallet,
} from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiverAddress = Address.fromRandom();

const request = new ScriptTransactionRequest();

const transferAmount = 1000;

request.addCoinOutput(
  receiverAddress,
  transferAmount,
  await provider.getBaseAssetId()
);

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: sender,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: await provider.getBaseAssetId(),
      account: sender,
      changeOutputAccount: sender,
    },
  ],
});

const signedTransaction = await sender.signTransaction(assembledRequest);
const transactionId = request.getTransactionId(await provider.getChainId());

const recoveredAddress = Signer.recoverAddress(
  transactionId,
  signedTransaction
);

request.updateWitnessByOwner(recoveredAddress, signedTransaction);

const tx = await provider.sendTransaction(request);
await tx.waitForResult();
```

Similar to the sign message example, the previous code used `Signer.recoverAddress` to get the wallet's address from the transaction ID and the signed data.

When using your wallet to submit a transaction with `wallet.sendTransaction()`, the SDK already handles these steps related to signing the transaction and adding the signature to the `witnesses` array. Because of that, you can skip this in most cases:

```
import { Address, Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const receiverAddress = Address.fromRandom();

const transferAmount = 1000;

const request = new ScriptTransactionRequest();

request.addCoinOutput(receiverAddress, 1000, await provider.getBaseAssetId());

const { assembledRequest } = await provider.assembleTx({
  request,
  feePayerAccount: sender,
  accountCoinQuantities: [
    {
      amount: transferAmount,
      assetId: await provider.getBaseAssetId(),
      account: sender,
      changeOutputAccount: sender,
    },
  ],
});

const tx = await sender.sendTransaction(assembledRequest);
await tx.waitForResult();
```


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/wallet-manager.md.md

# Wallet Manager

The `WalletManager` is a robust tool designed for managing vaults of wallets. It offers robust management of vaults, including support for custom storage and powerful encryption of all held vaults.

## Key Features

### Managing Vaults with `WalletManager`

This includes adding new wallets to specific vaults, retrieving all wallets from a vault, exporting specific vaults, and exporting private keys. The `WalletManager` class currently supports two types of vaults: `PrivateKeyVault` and `MnemonicVault`.

### Custom Storage Solutions

The `WalletManager` supports defining a custom storage solution, allowing you to specify how and where the encrypted vaults are saved. With support for custom storage, you can make the `WalletManager` to fit your specific needs and security requirements.

### Locking and Unlocking `WalletManager`

The `WalletManager` implements an automatic encryption mechanism, securely saving the wallet's held vaults. This not only preserves the state of your vaults but also ensures robust protection of the stored information. When needed, you can easily unlock and decrypt the vaults using the previously defined password.

## Getting Started with `WalletManager`

This guide provides step-by-step instructions on how to use `WalletManager`.

### Instantiating `WalletManager`

The `WalletManager` constructor accepts an optional object to define its storage. The storage describes how and where the `WalletManager` will store its vaults of wallets. If storage is not provided, the `WalletManager` uses a default one that does not persist data.

For now, let's keep it simple and not worry about the storage. Later we will discuss it in more detail.

To instantiate a `WalletManager` you can simply:

```
// Initialize a WalletManager
const walletManager = new WalletManager();
```

### Setting `WalletManager` Password

By default, a `WalletManager` instance is locked when created. Before using it, you need to unlock it by setting a password. You can do this by calling the `unlock` method.

```
const password = 'my-password';

await walletManager.unlock(password);
```

Once your `WalletManager` is unlocked, it can manage your wallets.

### Managing Vaults with `WalletManager`

A vault in `WalletManager` serves as a secure container for wallets. The `WalletManager` manages wallets by interacting with these vaults, supporting operations such as `getAccounts`, which returns public information about all wallets stored in the vault, and `exportAccount`, which exports a private key for a given wallet address.

To add a vault, we utilize the `addVault` method. Here's how we can create a private key vault and add a private key from a wallet we own:

```
// Initialize a Provider
const provider = new Provider(LOCAL_NETWORK_URL);
const myWallet = Wallet.generate({
  provider,
});

const privateKey = myWallet.privateKey;

await walletManager.addVault({
  type: 'privateKey',
  secret: privateKey,
  title: 'My first private key vault',
});
```

The `addVault` method requires an object with three properties: `type`, `secret`, and `title`. The `WalletManager` currently supports two types of vaults: `privateKeyVault` and `mnemonicVault`. For the `secret`, we use our wallet's private key, and for the `title`, we can provide a custom name.

By running this code, `WalletManager` creates a new vault instance of the type `privateKey` and adds one account (our wallet) to this newly created vault.

A key feature of the `WalletManager` is its ability to manage multiple vaults, even of the same type. This implies that if you run the `addVault` method again, with the same parameters, `WalletManager` will create another vault of the type `privateKey`, holding the same wallet. Here's an example:

```
await walletManager.addVault({
  type: 'privateKey',
  secret: privateKey,
  title: 'My second private key vault',
});
```

After executing this, you will find that your `WalletManager` is managing two `privateKey` vaults, both storing the same wallet.

Remember, both `title` and `secret` are optional when adding vaults, but providing a `title` makes it easier to manage your vaults and wallets. If you add a vault without providing a `secret`, this will result in one new account (wallet) being generated by the vault it self.

### Using The `WalletManager`

With your `WalletManager` set up, you can now access your vaults and wallets. Here's how to retrieve the details of your vaults:

```
const vaults = walletManager.getVaults();
```

This will output something like this:

```
// [
//     {
//         title: 'My first private key vault',
//         type: 'privateKey',
//         vaultId: 0
//     },
//     {
//         title: 'My second private key vault',
//         type: 'privateKey',
//         vaultId: 1
//     }
// ]
```

As you can see, the `WalletManager` assigns unique `vaultIds` for each vault. The first vault you added has a `vaultId` of `0`, and the second one has a `vaultId` of `1`.

Let's retrieve your wallet instance with the `getWallet` method:

```
const retrievedWallet = walletManager.getWallet(myWallet.address);
```

This guide walked through the steps to instantiate a `WalletManager`, set up its first vault, and retrieve vault information. The following sections will explore more functionalities of `WalletManager`, and go deeper into the usage of its vaults and the details of its storage system.

## Locking and Unlocking `WalletManager`

This guide will walk you through the process of managing the lock state of your wallets using the `WalletManager`.

### Initializing and Unlocking the `WalletManager`

As mentioned earlier, a `WalletManager` instance begins in a locked state. Before usage, you need to unlock it by providing a password via the unlock method.

```
const password = '0b540281-f87b-49ca-be37-2264c7f260f7';

const walletManager = new WalletManager();

await walletManager.unlock(password);
```

### Locking the `WalletManager`

When you lock the `WalletManager` using the `lock` method, all its vaults and associated accounts (wallets) are cleared. This clearance is possible due to the encryption and saving of all data by the storage system. `WalletManager` frequently uses the storage system to preserve its state. Consequently, sensitive operations including exporting vaults, private keys, accessing wallets, and saving/loading the `WalletManager` state are not possible when it is locked.

```
await walletManager.lock();
```

Remember, it's crucial to lock your `WalletManager` when it's not in use to ensure the safety of your funds.

### Reaccessing Your Wallets by Unlocking the `WalletManager`

The `unlock` method requires the previously set password to unlock the `WalletManager` and all its vaults. The password decrypts the stored vaults, allowing `WalletManager` to load its saved data.

```
await walletManager.unlock(password);
```

Providing an incorrect password will result in an error. However, when unlocked successfully, `WalletManager` is ready for use again.

### Verifying the Lock State

You can confirm the current lock state of the `WalletManager` by using the `isLocked` method:

```
const isLocked = walletManager.isLocked;
```

### Updating the Password

To change the current password, invoke the `updatePassphrase` method, and provide both the old and new passwords:

```
const newPassword = 'my-new-password';

await walletManager.updatePassphrase(password, newPassword);
```

### Reminder: Always Lock Your `WalletManager`

Always ensure you lock the `WalletManager` after completing operations. This step is critical for securing your wallets.

```
await walletManager.unlock(newPassword);

// perform your tasks...

walletManager.lock(); // Always lock your WalletManager when you're done
```

By using `WalletManager` to manage lock and unlock states, you introduce an additional layer of security. Never forget to lock your `WalletManager` when it's not in use.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/guide/wallets/wallet-transferring.md.md

# Wallet Transferring

This guide provides instructions for transferring assets between wallets and contracts using the SDK. It includes methods to validate balances and initiate and configure transfer requests.

## Transferring Assets Between Accounts

The `transfer` method initiates a transaction request that transfers an asset from one wallet to another. This method requires three parameters:

1. The receiver's wallet address
2. The amount of the asset to be transferred
3. The ID of the asset to be transferred (optional - defaults to the base asset ID)

Upon execution, this function returns a promise that resolves to a transaction response. To wait for the transaction to be processed, call `response.waitForResult()`.

### Example

Here is an example of how to use the `transfer` function:

```
import { Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const destination = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const amountToTransfer = 500;

const response = await sender.transfer(
  destination.address,
  amountToTransfer,
  baseAssetId
);

await response.waitForResult();

// Retrieve balances
const balance = await destination.getBalance(baseAssetId);
```

In the previous example, we used the `transfer` method which creates a `ScriptTransactionRequest`, populates its data with the provided transfer information and submits the transaction.

However, there may be times when you need the Transaction ID before actually submitting it to the node. To achieve this, you can simply call the `createTransfer` method instead.

This method also creates a `ScriptTransactionRequest` and populates it with the provided data but returns the request object prior to submission.

```
import { Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const destination = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const amountToTransfer = 200;
const baseAssetId = await provider.getBaseAssetId();

const transactionRequest = await sender.createTransfer(
  destination.address,
  amountToTransfer,
  baseAssetId
);

const chainId = await provider.getChainId();

const transactionId = transactionRequest.getTransactionId(chainId);

const response = await sender.sendTransaction(transactionRequest);

// The transaction id is the same one returned by the code above.
const { id } = await response.wait();
```

> **Note**: Any changes made to a transaction request will alter the transaction ID. Therefore, you should only get the transaction ID after all modifications have been made.

```
import { bn, Provider, Wallet } from 'fuels';

import {
  LOCAL_NETWORK_URL,
  WALLET_PVT_KEY,
  WALLET_PVT_KEY_2,
} from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const destination = Wallet.fromPrivateKey(WALLET_PVT_KEY_2, provider);

const amountToTransfer = 200;
const baseAssetId = await provider.getBaseAssetId();

const transactionRequest = await sender.createTransfer(
  destination.address,
  amountToTransfer,
  baseAssetId
);

const chainId = await provider.getChainId();

const transactionId = transactionRequest.getTransactionId(chainId);

/**
 * Modifying any property of the transaction request, except for the number
 * of witnesses within the ".witnesses" array, will generate a new transaction
 * hash, resulting in a different transaction ID.
 */
transactionRequest.gasLimit = bn(1000);

const response = await sender.sendTransaction(transactionRequest);

// The transaction id here is NOT the same one returned above.
const { id } = await response.wait();
```

## Transferring Assets To Multiple Wallets

To transfer assets to multiple wallets, use the `Account.batchTransfer` method:

```
import type { TransferParams } from 'fuels';
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = new Provider(LOCAL_NETWORK_URL);
const baseAssetId = await provider.getBaseAssetId();

const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const recipient1 = Wallet.generate({ provider });
const recipient2 = Wallet.generate({ provider });

const someOtherAssetId =
  '0x0101010101010101010101010101010101010101010101010101010101010101';
const transfersToMake: TransferParams[] = [
  {
    amount: 100,
    assetId: baseAssetId,
    destination: recipient1.address,
  },
  {
    amount: 200,
    assetId: baseAssetId,
    destination: recipient2.address,
  },
  {
    amount: 300,
    assetId: someOtherAssetId,
    destination: recipient2.address,
  },
];

const tx = await sender.batchTransfer(transfersToMake);
await tx.waitForResult();
```

## Transferring Assets To Contracts

When transferring assets to a deployed contract, we use the `transferToContract` method, which shares a similar parameter structure with the `transfer` method.

However, instead of supplying the target wallet's address, as done in `destination.address` for the transfer method, we need to provide an instance of [Address](../types/address.md) created from the deployed contract id.

If you have the [Contract](../contracts/) instance of the deployed contract, you can simply use its `id` property. However, if the contract was deployed with `forc deploy` or not by you, you will likely only have its ID in a hex string format. In such cases, you can create an [Address](../types/address.md) instance from the contract ID using `new Address('0x123...')`.

Here's an example demonstrating how to use `transferToContract`:

```
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const deploy = await CounterFactory.deploy(sender);
const { contract } = await deploy.waitForResult();

const amountToTransfer = 400;
const assetId = await provider.getBaseAssetId();
const contractId = contract.id;

const tx = await sender.transferToContract(
  contractId,
  amountToTransfer,
  assetId
);

await tx.waitForResult();
```

_Note: Use `transferToContract` exclusively for transfers to a contract. For transfers to an account address, use `transfer` instead._

## Transferring Assets To Multiple Contracts

Similar to the `Account.batchTransfer` method, you can transfer multiple assets to multiple contracts using the `Account.batchTransferToContracts` method. Here's how it works:

```
import type { ContractTransferParams } from 'fuels';
import { Provider, Wallet } from 'fuels';
import { TestAssetId } from 'fuels/test-utils';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory, EchoValuesFactory } from '../../../../typegend';

const provider = new Provider(LOCAL_NETWORK_URL);
const sender = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const baseAssetId = await provider.getBaseAssetId();
const assetA = TestAssetId.A.value;

const deploy1 = await CounterFactory.deploy(sender);
const { contract: contract1 } = await deploy1.waitForResult();

const deploy2 = await EchoValuesFactory.deploy(sender);
const { contract: contract2 } = await deploy2.waitForResult();

const contractTransferParams: ContractTransferParams[] = [
  {
    contractId: contract1.id,
    amount: 999,
    assetId: baseAssetId,
  },
  {
    contractId: contract1.id,
    amount: 550,
    assetId: assetA,
  },
  {
    contractId: contract2.id,
    amount: 200,
    assetId: assetA,
  },
];

const transfer = await sender.batchTransferToContracts(contractTransferParams);
await transfer.waitForResult();
```

Always remember to call the `waitForResult()` function on the transaction response. That ensures the transaction has been mined successfully before proceeding.

_Note: Use `batchTransferToContracts` solely for transferring assets to contracts. Do not use account addresses with this method. For multiple account transfers, use `batchTransfer` instead._

## Checking Balances

Before you transfer assets, please make sure your wallet has enough funds. Attempting a transfer without enough funds will result in the error: `The transaction does not have enough funds to cover its execution.`

You can see how to check your balance at the [`checking-balances`](./checking-balances.md) page.


---

### File: docs/fuels-ts/nightly/fuels-ts/apps/docs/src/index.md.md

<script setup>
  import { data } from './versions.data'
  const { forc, fuels, fuelCore } = data
  const url = `https://docs.fuel.network/docs/forc/`
  const logoSrc = './fuel-logo.png'
</script>

# The Fuel TypeScript SDK

The Fuel TypeScript SDK provides methods and utilities in TypeScript, for developing on or interacting with the Fuel network and its [ecosystem](https://docs.fuel.network/docs/intro/what-is-fuel/).

Using the SDK you can:

- Deploy, interact with, and test [Sway](https://docs.fuel.network/docs/sway/) contracts.
- Bootstrap a dApp and local development environment using the [create fuels CLI](https://docs.fuel.network/docs/fuels-ts/creating-a-fuel-dapp/).
- Generate and import wallets from private key, mnemonic, or JSON and safely store them on the client.
- Craft custom transactions and mutate them by adding resources, policies and signers and submit them.
- Generate types for [Sway programs](https://docs.fuel.network/docs/sway/sway-program-types/) using [typegen](https://docs.fuel.network/docs/fuels-ts/fuels-cli/abi-typegen/) to give end-to-end type safety.

## Version

This documentation was generated using Fuels `v{{fuels}}`, Fuel Core `v{{fuelCore}}`, Sway `v{{forc}}`, and Forc `v{{forc}}`.

## API Documentation

The Complete API documentation for the SDK is available [here](DOCS_API_URL/).


---

### File: docs/integration-docs/docs/src/index.md

# Integrations

This section provides help for developers using integrations with Fuel's tech stack.

## Wallets

### Fuelet

Fuelet is the leading account abstraction and non-custodial wallet on Fuel.

[More info](https://docs.fuelet.app/)

### Fuel

The official Fuel wallet. With the Fuel Wallet, you can explore DApps on Fuel and manage your crypto assets, all in one place.

[More info](https://docs.fuel.network/docs/wallet/install/)

## Indexers

### Envio

Envio is a modern, multi-chain EVM blockchain indexing framework speed-optimized for querying real-time and historical data.

[More info](https://docs.envio.dev/docs/HyperIndex/tutorial-indexing-fuel)

### SQD

SQD enables permissionless, cost-efficient access to petabytes of high-value Web3 data.

[More info](https://docs.sqd.dev/fuel-indexing/)

### Pangea

Pangea provides access to fine-grained real-time and historical data.

[More info](https://docs.pangea.foundation/chain-data/fuel/fuel.html)

## Oracles

### Pyth

Build apps with high-fidelity oracle feeds designed for mission-critical systems.

[More info](https://docs.pyth.network/price-feeds/use-real-time-data/fuel)

### ORAO

ORAO Network provides provably fair random data on Fuel.

[More info](https://orao.network/fuel-vrf)

### Redstone

Redstone provides modular oracles tailored to your decentralized applications.

[More info](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/fuel-connector/README.md)

## RPCs

### QuickNode

QuickNode provides infrastructure that allows developers and services to interact with the Fuel network quickly and efficiently, without the need to manage their own nodes.

[More info](https://www.quicknode.com/chains/fuel)


---

### File: docs/intro/glossary.md

# Fuel Glossary

## Address

An address is a cryptographic hash representing an identity of a wallet or a predicate root.

## AssetId

An asset ID is a unique identifier for an on-chain asset. It is derived from the root of the bytecode of the contract minting the asset.

## Base Asset

The base asset is the underlying asset needed to perform any transactions on a blockchain. It is used to pay gas for transactions. On Ethereum, the base asset is ETH.

## Block

A block is a record of many transactions, that are grouped together and cryptographically hashed. The linked blocks form a chain, also called a blockchain.

## Block Explorer

A block explorer is an interface for block and transaction data produced by a blockchain. You can use a block explorer to explore and verify addresses, contracts, and transaction histories.

## Block Height

The block height refers to the total number of valid blocks produced in the history of a blockchain, starting with the genesis block.

## Block ID

A block ID is a unique identifier for a particular block.

## Bridge

A bridge is a mechanism that allows the transfer of data or assets from one blockchain to another.

## Bytecode

Bytecode is machine-readable code, usually generated from a compiler.

## Chain

Another name for a blockchain.

## ChainId

A unique ID for a blockchain.

## Client

The Fuel client refers to the software that runs the Fuel Virtual Machine. It can be used to validate and produce blocks, and send transactions.

## Coinbase

Coinbase refers to the validators paying themselves for processing a block from the transaction fees. Having a coinbase transaction on each block makes this process transparent to all users.

## Consensus

The consensus layer defines the state and validates that all nodes on the blockchain have the same state.

## Consensus Parameters

Consensus parameters are the rules used by clients to determine the validity of and finalize a block.

## Contract Call

Calling a contract means invoking a function from a smart contract that has been deployed to the blockchain.

## Contract ID

The contract ID is a unique identifier for a contract derived from the root of the contract bytecode.

## Data Availability

The data availability layer ensures that block data has been published to the network.

## EIP

EIP stands for Ethereum Improvement Proposal. It refers to a proposal to upgrade the core software powering the Ethereum blockchain.

## EOA

EOA stands for Externally Owned Account. It refers to a wallet address that is not controlled by a contract.

## EVM

EVM stands for Ethereum Virtual Machine, which is the virtual machine used for the Ethereum network.

## Execution

Execution refers to the processing of transactions by nodes in a network.

## Faucet

A faucet is a service that provides free tokens for a testnet.

## Forc

Forc is short for Fuel Orchestrator. Similar to Cargo for Rust, Forc is the build system and package manager for Sway. It is used to build, test, and deploy Sway contracts.

## Fraud Proof

Fraud proofs are a blockchain verification mechanism whereby a claim on a new block is accepted unless a proof the claim is invalid is provided within some configurable time window. Both the Fuel protocol and the FuelVM are designed to be fraud-provable in restrictive environments such as the Ethereum Virtual Machine.

## Fuel

The Fuel blockchain.

## Fuels

Fuels is the name of the Fuel Rust and Typescript SDKs used to interact with a contract, similar to ethers.js or web3.js

## Fuelup

Fuelup is the official toolchain and package manager for the Fuel toolchain.

## FuelVM

The FuelVM is the virtual machine powering the Fuel blockchain.

## Fuel Core

`fuel-core` is the name of the Fuel client implementation.

## Gas

Gas is a variable fee charged by a node to process a transaction that is executed on-chain.

## Indexer

An indexer is a program that watches and organizes blockchain data so it can be easily queried.

## Input

An input refers to a transaction input, which is a UTXO consumed by a transaction.

## Layer 1 (L1)

Also called a level 1, this refers to a base layer blockchain that is not built on top of any other blockchain.

## Layer 2 (L2)

Also called a level 2, this is a blockchain that is built on top of another blockchain. Layer 2 networks can offer unique benefits like allowing for cheaper transactions or sovereign rollups that can fork without forking the base layer.

## Light Client

A light client is a client that doesn't validate blocks and transactions but still offers some functionality to send transactions.

## Locked Wallet

A locked wallet is a wallet that can only interact with read-only smart contract methods.

## Mainnet

Mainnet refers to the main network of a blockchain, as opposed to a testnet.

## Merkle Tree

A Merkle tree is a data structure which uses a cryptographic hash function recursively to condense a set of data into a single value, called the root. It allows efficient proofs that a given element is part of the set.

## Message

A type of input that only includes specific metadata, and is often used for bridging.

## Mint

Minting refers to the creation of new coins.

## Modular

Referring to a blockchain architecture that allows for execution, settlement, consensus, and data availability to run on separate layers.

## Monolithic

Referring to a blockchain architecture that handles execution, settlement, consensus, and data availability all at the same time on a single layer.

## Native Asset

With Fuel any contract can make its own native asset. On Ethereum, the only native asset is ETH. This allows for much cheaper token transactions because it doesn't require any contract state changes. It also allows you to directly forward any asset in a transaction call, avoiding the need for the `approve` and `transferFrom` mechanisms.

## Network

Another name for a blockchain.

## Node

A client that validates and produces blocks for the network.

## Optimistic Rollup

An optimistic rollup is a sidechain that uses fraud proofs to verify transactions instead of relying on a majority of validators to be honest.

## Output

An output refers to a transaction output, or which UTXOs are output by a transaction.

## Parallel Transactions

Parallel transactions refers to the ability of the FuelVM to process multiple transactions in parallel.

## Predicate

A predicate is a pure function that can return true or false, and is sent inside a transaction as bytecode and checked at transaction validity time. If it evaluates to `false` the transaction will not be processed, and no gas will be used. If it evaluates to `true`, any coins belonging to the address equal to the Merkle root of the predicate bytecode may be spent by the transaction.

## Private Key

A cryptographic key that is used to prove ownership by producing a digital signature. It should be kept private (or secret) as it can grant access to a wallet.

## Public Key

A cryptographic key that is generated from its associated private key and can be shared publicly. Addresses are derived from public keys.

## Receipt

A receipt is a data object that is emitted during a transaction and contains information about that transaction.

## Reentrancy attack

A type of attack in which the attacker is able to recursively call a contract function so that the function is exited before it is fully executed. This can result in the attacker being able to withdraw more funds than intended from a contract.

## Rollup

A rollup is a scaling solution for layer 1 blockchains that "rolls up" or batches transactions as calldata.

## Script

A script is runnable bytecode that executes once on-chain to perform some task. It does not represent ownership of any resources and it cannot be called by a contract. A script can return a single value of any type.

## Settlement

Settlement refers to how and where on-chain disputes are resolved or settled.

## Sidechain

A sidechain is a blockchain that runs independently but is connected to another blockchain (often Ethereum Mainnet) by a two-way bridge.

## Signature

A cryptographic signature from a wallet, usually in reference to a signature for a message.

## Smart Contract

Also referred to as a contract, a smart contract is a set of programming functions with persistent state that is deployed on a blockchain. Once deployed, the contract code can never be changed or deleted, and anyone can access public functions without permission.

## State Channel

State channels allow for users to conduct any number of off-chain transactions while only submitting two on-chain transactions to open and close the channel. This reduces the number of on-chain transactions needed, which reduces the cost and saves time.

## Sway

Sway is the official programming language for Fuel. It is a domain-specific language crafted for the FuelVM and inspired by Rust.

## Testnet

Testnet is short for test network. You can use a testnet to deploy and test contracts for free.

## Toolchain

A toolchain is a set of related tools. The Fuel toolchain includes `fuelup`, `forc`, `fuel-core`, and `fuels`.

## Transaction

A transaction is any interaction with the blockchain, for example sending coins from one address to another.

## Unlocked Wallet

An unlocked wallet can interact with both read and write smart contract methods.

## UTXO

UTXO stands for unspent transaction output.

## UTXO Model

A UTXO model is a blockchain model that doesn't keep track of account balances. Instead, it uses inputs and outputs to manage state, which allows for fast parallel transactions.

## Validator

A validator refers to a network validator or node. Validators help validate transactions and produce blocks.

## Witness

A witness refers to the cryptographic signatures from actors involved in authorizing a transaction, including the transaction signers, contract callers, and block producers.

## Zero-Knowledge Proof

A method that allows for the verification of secret information without revealing the secret.

## Zero-Knowledge Rollup

A rollup that uses zero-knowledge proofs to verify transactions. In ZK rollups, each rollup block posted to the contract must be accompanied by a validity proof (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.


---

### File: docs/intro/quickstart.md

# Quickstart

Get started with Fuel and discover the path that best suits your needs.

<QuickstartCards/>


---

### File: docs/intro/what-is-fuel.md

# What is Fuel?

Fuel is an operating system purpose built for Ethereum Rollups.
Fuel allows rollups to solve for PSI (parallelization, state minimized execution, interoperability) without making any sacrifices.

Here is how we do it:

## FuelVM

The FuelVM learns from the Ethereum ecosystem.
It implements improvements suggested to the Ethereum VM (EVM) for many years that couldn’t be implemented due to the need to maintain backward compatibility, including parallel transaction execution and multiple native assets.

Fuel delivers unmatched processing capacity through its ability to execute transactions in parallel by using strict state access lists in the form of a UTXO model.
With the FuelVM, Fuel full nodes identify the accounts a transaction touches, mapping out dependencies before execution.
This enables Fuel to use far more threads and cores of your CPU that are typically idle in single-threaded blockchains.
As a result, Fuel can deliver far more compute, state accesses, and transactional throughput than its single-threaded counterparts.

## Sway Language

Fuel provides a powerful and sleek developer experience with our own domain-specific language (DSL) called Sway.
Sway is based on Rust and includes syntax to leverage a blockchain VM without needlessly verbose boilerplate.
Sway was created alongside the FuelVM and designed for the high-compute Fuel environment.

### Rust + Solidity = Sway

Sway prioritizes compile-time analysis and safety, similar to Rust’s borrow checker and safety-first semantics.
Additionally, it has the syntax of Rust. From Solidity, Sway took the notion of a smart-contract-paradigm language with built-in top-level contract storage and blockchain mechanisms for ergonomic and safe contract programming.

Sway brings the notion of static auditing to smart contracts.
In addition, Sway is highly performant and has extensible optimization passes and a modular backend for targeting different blockchain architectures.

<CardSection
versionSet={props.versionSet}
cardsInfo={[
    {
        link: '/docs/sway',
        nightlyLink: '/docs/nightly/sway',
        isExternal: false,
        heading: 'Sway',
        headingIcon: 'Code',
        body: 'Read the official Sway documentation.',
    },
    {
        link: 'https://sway-playground.org/',
        isExternal: true,
        heading: 'Sway Playground',
        headingIcon: 'Browser',
        body: 'Get started experimenting with Sway in the browser.',
    },
    {
        link: 'https://swaybyexample.com/',
        isExternal: true,
        heading: 'Sway By Example',
        headingIcon: 'Beach',
        body: 'An introduction to Sway with bite-sized simple examples',
    },
    {
        link: 'https://github.com/FuelLabs/sway-examples',
        isExternal: true,
        heading: 'Sway Examples',
        headingIcon: 'Robot',
        body: 'Examples of full-stack DeFi applications',
    },
    {
        link: '/docs/sway-libs',
        nightlyLink: '/docs/nightly/sway-libs',
        isExternal: false,
        heading: 'Sway Libraries',
        headingIcon: 'Book',
        body: 'Find useful libraries written in Sway.',
    },
    {
        link: '/docs/sway-standards',
        nightlyLink: '/docs/nightly/sway-standards',
        isExternal: false,
        heading: 'Sway Standards',
        headingIcon: 'Book',
        body: 'Learn about standards for the Sway language',
    },
    {
        link: 'https://fuellabs.github.io/sway/master/std/',
        isExternal: true,
        heading: 'std-lib Reference',
        headingIcon: 'Book',
        body: 'Find definitions for helpful types and methods in Sway.',
    },
    {
        link: 'https://github.com/FuelLabs/sway-applications',
        isExternal: true,
        heading: 'Example Applications',
        headingIcon: 'Apps',
        body: 'Explore end-to-end applications written in Sway.',
    },
]}
/>

## Developer Tooling

Part of what makes Sway so powerful is the fantastic suite of developer tools surrounding it.
The Fuel development environment retains the benefits of smart contract languages like Solidity, while adopting the paradigms introduced in the Rust tooling ecosystem.

Now, developers can have a completely vertically integrated experience where every component, from the virtual machine to the CLI, works in harmony.

### Sway Tooling

<CardSection
versionSet={props.versionSet}
cardsInfo={[
     {
        link: '/docs/forc',
        nightlyLink:'/docs/nightly/forc',
        isExternal: false,
        heading: 'Forc',
        headingIcon: 'Tool',
        body: 'Explore the Fuel Orchestrator that helps you build, test, and deploy your Sway projects.',
    },
    {
        link: '/guides/installation/',
        nightlyLink: '/guides/installation/',
        isExternal: false,
        heading: 'Fuelup',
        headingIcon: 'Settings',
        body: 'Learn more about the official Fuel toolchain manager that helps install and manage versions.',
    }
]}
/>

### SDKs & API

<CardSection
versionSet={props.versionSet}
cardsInfo={[
{
          link: '/docs/fuels-rs',
          nightlyLink: '/docs/nightly/fuels-rs',
          isExternal: false,
          heading: 'Rust SDK',
          headingIcon: 'BrandRust',
          body: 'Test and interact with your Sway program in Rust.',
        },
        {
          link: '/docs/fuels-ts',
          nightlyLink: '/docs/nightly/fuels-ts',
          isExternal: false,
          heading: 'Typescript SDK',
          headingIcon: 'BrandTypescript',
          body: 'Test and interact with your Sway program in TypeScript.',
        },
        {
          link: '/docs/wallet',
          nightlyLink: '/docs/nightly/wallet',
          isExternal: false,
          heading: 'Wallet SDK',
          headingIcon: 'Wallet',
          body: 'Seamlessly integrate a wallet into your application.',
        },
        {
         link: '/docs/graphql',
          nightlyLink: '/docs/nightly/graphql',
          isExternal: false,
          heading: 'GraphQL API',
          headingIcon: 'ChartDots3',
          body: 'Learn about the GraphQL API and interact with the Fuel Network.',
        },
]}
/>

### Network

<CardSection
versionSet={props.versionSet}
cardsInfo={[
    {
        link: `/docs/specs`,
        nightlyLink: `/docs/nightly/specs`,
        isExternal: false,
        heading: 'Specs',
        headingIcon: 'ListDetails',
        body: 'Explore the specifications for the Fuel Network.',
    },
    {
        link: props.explorerUrl,
        isExternal: true,
        heading: 'Explorer',
        headingIcon: 'Search',
        body: 'Explore transactions on the Fuel network.',
    },
    {
        link: props.bridgeUrl,
        isExternal: true,
        heading: 'Bridge',
        headingIcon: 'BuildingBridge',
        body: 'Bridge assets to the Fuel network.',
    },
        {
        link: props.faucetUrl,
        isExternal: true,
        heading: 'Faucet',
        headingIcon: 'Coin',
        body: `Get ${props.fuelTestnet} testnet tokens.`,
    }
]}
/>


---

### File: docs/migrations-and-disclosures/docs/src/breaking-changes-archive.md

# Beta 3-5 Testnet Breaking Change Guide (Archive)

## April 30, 2024

### Sway

Release: [Sway v0.56.0](https://github.com/FuelLabs/sway/releases/tag/v0.56.0)

The `std::call_frames::second_param` function now returns a `u64` instead of a generic type `T`.

`contract_id()` has been removed in favor of `ContractId::this()`.

```rust
/* BEFORE */
let contract_id = contract_id();

/* AFTER */
let contract_id = ContractId::this();
```

`call_with_function_selector_vec` has been removed in favor of `call_with_function_selector`.

```rust
/* BEFORE */
pub fn call_with_function_selector_vec(
  target: ContractId,
  function_selector: Vec<u8>,
  calldata: Vec<u8>,
  single_value_type_arg: bool,
  call_params: CallParams
) {...}

/* AFTER */
pub fn call_with_function_selector_vec(
  target: ContractId,
  function_selector: Bytes // new
  calldata: Bytes, // new
  call_params: CallParams
) {...}
```

The `BASE_ASSET_ID` constant has been removed, and `AssetId::base_asset_id()` is now `AssetId::base()`.

```rust
/* BEFORE */
let base_asset_id = BASE_ASSET_ID;
/* OR */
let base_asset_id = AssetId::base_asset_id();

/* AFTER */
let base_asset_id = AssetId:base();
```

You can no longer access the following:

- `force_transfer_to_contract()`
- `transfer_to_address()`
- `mint_to_contract()`
- `mint_to_address()`

Instead use the `transfer()`, `mint()`, and `mint_to()` functions accordingly.

```rust
/* BEFORE */
let user = Address:from(address);
mint_to_address(user, ZERO_B256, amount);

/* AFTER */
mint_to(Identity::Address(user), ZERO_B256, amount);
```

The new encoding (encoding v1) is now set by default.  If you would like to build your forc project without v1 encoding then run the following command:

```sh
forc build --no-encoding-v1
```

`run_external` in sway-lib-std has been removed until LDC is stabilized.

Release: [Sway v0.55.0](https://github.com/FuelLabs/sway/releases/tag/v0.55.0)

`GTF` constants along with the following functions have been removed to match the current Fuel VM instruction set:

- `input_maturity()`
- `tx_receipts_root()`

`tx_gas_price` has been renamed `tx_tip`

```rust
/* BEFORE */
let gas_price = tx_gas_price();

/* AFTER */
let tip = tx_tip();
```

Release: [Sway v0.54.0](https://github.com/FuelLabs/sway/releases/tag/v0.54.0)

The `forc-client` and `forc-tx` plugins now take `u16` instead of `u8` for witness index types.

### TS-SDK

Release [v0.83.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.83.0)

`BaseAssetId` is no longer exported by `fuels`. It can be fetched from a `Provider`.

```ts
/* BEFORE */
import { BasedAssetId } from "fuels";

/* AFTER */
const provider = await Provider.create(FUEL_NETWORK_URL);
const baseAssetId = provider.getBaseAssetId();
```

`TransactionRequest.addCoinOutput` and `TransactionRequest.addChangeOutput` now requires an `assetId`, it no longer defaults to the `BaseAssetId`.

`TransactionRequest.fundWithFakeUtxos` now requires passing the `baseAssetId` as a function parameter. This is the only function that is base asset aware, so that it can be used specifically to estimate the transaction cost.

`CoinQuantityLike` now requires an `AssetId`. Previously most of it's usages would default to the `BaseAssetId`, as this must now be fetched, so it must be passed to the type.

```ts
/* BEFORE */
let coin: CoinQuantityLike = [1000];
coin = { amount: 1000 };

/* AFTER */
const assetId = "0x..";
let coin: CoinQuantityLike = [1000, assetId];
coin = { amount: 1000, assetId };
```

`gasPrice` is calculated by the VM so we do not need use it anymore.

```ts
/* BEFORE */
await factory.deployContract({ gasPrice });

/* AFTER */
await factory.deployContract();
```

`PolicyType.GasPrice` is now `PolicyType.Tip`.

The `Account.fund` function parameters changed.  Also the information returned by `Provider.getTransactionCost` is useful here because it can be passed as the second parameter to `Account.fund`.

```ts
/* BEFORE */
async fund<T extends TransactionRequest>(
    request: T,
    coinQuantities: CoinQuantity[],
    fee: BN,
    inputsWithEstimatedPredicates: TransactionRequestInput[],
    addedSignatures?: number
): Promise<T>

/* AFTER */
export type EstimatedTxParams = {
  maxFee: BN;
  estimatedPredicates: TransactionRequestInput[];
  addedSignatures: number;
  requiredQuantities: CoinQuantity[];
}
async fund<T extends TransactionRequest>(request: T, params: EstimatedTxParams): Promise<T>
```

GraphQL URL now includes a versioning path: `http://127.0.0.1:4000/v1/graphql`.

`calculateTransactionFee` now requires `tip`, `maxGasPerTx`, and `gasPrice`. Also `gasUsed` is not used anymore.

```ts
/* BEFORE */
const { fee } = calculateTransactionFee({
  gasUsed,
  rawPayload,
  consensusParameters: {
    gasCosts,
    feeParams: {
      gasPerByte,
      gasPriceFactor,
    },
  },
});

/* AFTER */
const { fee } = calculateTransactionFee({
  gasPrice, // new
  tip, // new
  consensusParameters: {
    maxGasPerTx, // new
    gasCosts,
    feeParams: {
      gasPerByte,
      gasPriceFactor,
    },
  },
  rawPayload,
});
```

Due to `forc` upgrade [v0.52.0](https://github.com/FuelLabs/sway/releases/tag/v0.52.0) `AssetId` and `EvmAddress` property `value` was renamed to `bits`

```ts
/* BEFORE */
export type EvmAddress = {
  value: B256AddressEvm;
};
export type AssetId = {
  value: B256Address;
};

/* AFTER */
export type EvmAddress = {
  bits: B256AddressEvm;
};
export type AssetId = {
  bits: B256Address;
};
```

Release [v0.80.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.80.0)

Removed unused property `usedFee` from `Provider.getTransactionCost` response.

Renamed `getAssetId` to `getMintedAssetId`.

### Rust SDK

Release [v0.58.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.58.0)

The new encoding is now the default encoding. Use the following command if you would like to run your cargo tests with the legacy encoding.

```sh
cargo test --features legacy_encoding
```

Release [v0.57.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.57.0)

The `BASE_ASSET_ID` constant has been removed and replaced by a new `Provider` function.

```rust
/* BEFORE */
let base_asset_id = BASE_ASSET_ID;

/* AFTER */
let base_asset_id = provider.base_asset_id();
```

`Config` was renamed to `NodeConfig`

```rust
/* BEFORE */
let node_config = Config::default();

/* AFTER */
let node_config = NodeConfig::default();
```

`FuelService::start()` now accepts `NodeConfig`, `ChainConfig`, and `StateConfig` as arguments to startup a node.

```rust
/* BEFORE */
let server = FuelService::start(Config::default()).await?;

/* AFTER */
let server = FuelService::start(
  NodeConfig::default(),
  ChainConfig::default(),
  StateConfig::default(),
)
.await?;
```

When instantiating `ConsensusParameters` you must make use of setters.

```rust
/* BEFORE */
let consensus_parameters = ConsensusParameters {
    tx_params,
    fee_params,
    ..Default::default()
};

/* AFTER */
let mut consensus_parameters = ConsensusParameters::default();
consensus_parameters.set_tx_params(tx_params);
consensus_parameters.set_fee_params(fee_params);
```

Fields now need to be accessed via methods.

```rust
/* BEFORE */
let chain_id = consensus_parameters.chain_id;

/* AFTER */
let chain_id = consensus_parameters.chain_id();
```

The same applies to other parameter structs used when setting up a node, such as `TxParameters`, `ContractParameters`, `PredicateParameters` etc.

The `witness_index` parameters in `CreateTransactionBuilder::with_bytecode_witness_index` are now a `u16`.

`NodeInfo` no longer has `min_gas_price`.

`CreateTransaction` no longer has `bytecode_length()`.

`Header` no longer has `message_receipt_root`, but gains:

```rust
pub message_outbox_root: Bytes32,
pub event_inbox_root: Bytes32,
pub consensus_parameters_version: u32,
pub state_transition_bytecode_version: u32
```

## March 27, 2024

### Sway

Release [Sway v0.52.0](https://github.com/FuelLabs/sway/releases/tag/v0.52.0)

The `bytes` field on `B512` and the `value` field `EvmAddress` have been renamed `bits`, made private, and made accessible via `bits()`.

```rust
/* BEFORE */
let bytes = myB12.bytes;
let value = myEvmAddress.value;

/* AFTER */
let bits = myB512.bits();
let bits = myEvmAddress.bits();
```

The fields on `U128` have been made private.

```rust
/* BEFORE */
let zero_u128 = U128 { upper: 0, lower: 0 };
let upper = zero_u128.upper;

/* AFTER */
let zero_u128 = U128::from(0, 0);
let upper = zero_u128.upper();
```

The fields on `StorageKey` have been made private and are now accessed via:

- `new()`
- `slot()`
- `offset()`
- `field_id()`

The following heap types have been updated to have private struct variables:

- `Bytes`
- `RawBytes`
- `Vec`
- `RawVec`
- `String`

```rust
/* BEFORE */
let bytes_ptr = bytes.buf.ptr();

/* AFTER */
let bytes_ptr = bytes.ptr();
```

The `value` field on `AssetId`, `ContractId`, and `Address` is now private and renamed `bits`.

```rust
/* BEFORE */
let value = assetId.value;

/* AFTER */
let bits = assetId.bits();
```

`predicate_id()` has been renamed to `predicate_address()`.

```rust
/* BEFORE */
let predicate = predicate_id();

/* AFTER */
let predicate = predicate_address();
```

`U256` has been removed use the native `u256` type instead.

```rust
/* BEFORE */
let my_U256 = U256::max();

/* AFTER */
let my_u256 = u256::max();
```

### TS-SDK

Release [v0.79.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.79.0)

`externalLoggedTypes` has been removed from the `Interface` class.

Release [v0.77.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.77.0)

Predicate data is now accepted on the `Predicate` constructor.

```ts
/* BEFORE */
const predicate = new Predicate(bytecode, provider, abi, configurableConstants);

/* AFTER */
const predicate = new Predicate({
  bytecode,
  abi, // optional
  provider,
  inputData, // optional
  configurableConstants, // optional
});
```

The `setData` method has been removed from `Predicate`. If you want to pass in predicate data after instantiating the `Predicate` or if you want to use different data than what was passed to the constructor, then you will have to create a new `Predicate` instance.

### Rust SDK

Release [v0.56.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.56.0)

Experimental encoding for logs was added. Use the following command to run your tests with the experimental encoding

```sh
cargo test --features experimental
```

**_NOTE_** experimental encoding is now the default encoding in [v0.57.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.57.0)

`Configurables` structs now need to be instantiated through a `::new(encoder_config)` or `::default()` method.

```rust
/* BEFORE */
let configurables = MyContractConfigurables::new().with_STRUCT(my_struct);

/* AFTER */
let configurables = MyContractConfigurables::default().with_STRUCT(my_struct);
/* OR */
let configurables = MyContractConfigurables::new(encoder_config).with_STRUCT(my_struct);
```

`Configurables::with_some_string_config(some_string)` methods now return a `Result<Configurables>` instead of `Configurables`.

`Predicates::encode_data` now returns a `Result<UnresolvedBytes>` instead of `UnresolvedBytes`.

`AbiEncoder` structs must be instantiated through a `::new(encoder_config)` or `::default()` method.

```rust
/* BEFORE */
let encoded = ABIEncoder::encode(&args).resolve(0);

/* AFTER */
let encoded = ABIEncoder::default().encode(&args).resolve(0);
/* OR */
let encoded = ABIEncoder::new(config).encode(&args).resolve(0);
```

`EnumVariants` are now imported through `param_types::EnumVariants`.

```rust
/* BEFORE */
use fuels::types::enum_variants::EnumVariants;

/* AFTER */
use fuels::types::param_types::EnumVariants;
```

`TxPolicies` `gas_price` is replaced with `tip`

```rust
/* BEFORE */
let tx_policies = TXPolicies::default().with_gas_price(1);

/* AFTER */
let tx_policies = TXPolicies::default().with_tip(1);
```

`checked_dry_run` has been removed from `Provider`.

`dry_run` now returns `Result<TxStatus>` instead of `Result<Vec<Receipt>>`. The receipts can be taken with `tx_status.take_receipts()`.

`TransactionResponse`'s `block_id` is replaced with `block_height`.

`estimate_transaction_cost` has a new argument `block_horizon: Option<u32>`.

```rust
/* BEFORE */
let transaction_cost = contract_instance
  .methods()
  .my_contract_call()
  .estimate_transaction_cost(Some(tolerance))
  .await?;

/* AFTER */
let transaction_cost = contract_instance
  .methods()
  .my_contract_call()
  .estimate_transaction_cost(tolerance, block_horizon)
  .await?;
```

## February 22, 2024

### Sway

Release: [Sway v0.51.0](https://github.com/FuelLabs/sway/releases/tag/v0.51.0)

You can no longer access private fields in structs.

```rust
/* BEFORE */
let private = my_struct.private // just a warning

/* AFTER */
let private = my_struct.private // ERROR
let private = my_struct.private() // you must create a function to access private variables
```

The `Never` type is now `!`.

```rust
/* BEFORE */
let x: NEVER = { return 123 };

/* AFTER */
let x: ! = { return 123 };
```

Release: [Sway v0.50.0](https://github.com/FuelLabs/sway/releases/tag/v0.50.0)

Configurables are now forbidden in const expressions.

```rust
// Not allowed
script;

configurable {
    VALUE: u64 = 42,
}

fn main() {
    const CONSTANT: u64 = VALUE;
}
```

Struct fields are now private by default.  You must explicitly mark a field public.

```rust
/* BEFORE */
pub struct Struct {
  public_field: u8,
}

/* AFTER */
pub struct Struct {
  pub public_field: u8,
  private_field: u8,
}
```

The `From` trait has been redesigned into the `From`/`Into` rust-like trait pair.

```rust
/* BEFORE */
impl From<b256> for Address {
  fn from(bits: b256) -> Self {
    Self { value: bits }
  }

  fn into(self) -> b256 {
    self.value
  }
}

let address = Address::from(ZERO_B256);
let b256_data = address.into();

/* AFTER */
impl From<b256> for Address {
  fn from(bits: b256) -> Self {
    Self { value: bits }
  }
}

impl From<Address> for b256 {
  fn from(address: Address) -> b256 {
    address.value
  }
}

let address = Address::from(ZERO_B256);
let b256_data: b256 = address.into();
let address: Address = b256_data.into();
```

### TS-SDK

Release: [v0.74.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.74.0)

`Provider` has been removed from `WalletManager` types.

```ts
/* Before */
const vault = new MnemonicVault({
  secret: mnemonic,
  provider,
});

/* After */
const vault = new MnemonicVault({
  secret: mnemonic,
});
```

The Account and account related packages have been restructured. Anything imported from the following packages will now be imported from `@fuel-ts/account`

- `@fuel-ts/hdwallet`
- `@fuel-ts/mnemonic`
- `@fuel-ts/predicate`
- `@fuel-ts/providers`
- `@fuel-ts/signer`
- `@fuel-ts/wallet-manager`
- `@fuel-ts/wallet`
- `@fuel-ts/wordlists`

## February 5, 2024 (Beta 5)

### Sway

Release: [Sway v0.49.2](https://github.com/FuelLabs/sway/releases/tag/v0.49.2)

Numerous elements in the standard library have undergone changes. The `token.sw` file has been renamed to `asset.sw`, impacting the `transfer()` and `mint_to()` functions. This modification aims to bring about greater consistency across all functions related to asset management.

```sway
/* BEFORE - v0.46.0 */
use std::{
    token::transfer

};
/* AFTER - v0.49.2 */
use std::{
    asset::transfer
};
```

The instructions `LW` (Load Word) and `SW` (Store Word) are now replaced with `LB` (Load Byte) and `SB` (Store Byte), specifically for smaller data types like `u8`. This adjustment allows these types to be contained within a single byte, rather than occupying a full word. However, for other data types such as `u16`, the original instruction format remains unchanged.

```sway
/* BEFORE - v0.46.0 */
sw   output r1 i0;

/* AFTER - v0.49.2 */
sb   output r1 i0;
```

`DEFAULT_SUB_ID` has been introduced to improve UX. It is equivalent to the `ZERO_B256` constant.

```sway
/* BEFORE - v0.46.0 */
use std::call_frames::contract_id;

fn foo(other_contract: ContractId) {
     let other_asset = AssetId::default(other_contract);
     let my_asset = AssetId::default(contract_id());
}

/* AFTER - v0.49.2 */
fn foo(other_contract: ContractId) {
     let other_asset = AssetId::new(other_contract, DEFAULT_SUB_ID);
     let my_asset = AssetId::default();
}
```

The `Eq` trait now exists for `Option`.

```sway
/* BEFORE - v0.46.0 */
let option1: Option<u64> = Some(5);
let option2: Option<u64> = Some(5);

match (option1, option2) {
    (Some(a), Some(b)) => a == b,
    (None, None) => true,
    _ => false,
}

/* AFTER - v0.49.2 */
let option1: Option<u64> = Some(5);
let option2: Option<u64> = Some(5);

if option1 == option2 {
    return true
} else {
    return false
}
```

The standard library `tx` introduces several new functions including `tx_max_fee()`, `tx_witness_limit()`, `script_gas_limit()`, and `policies()`. `tx_gas_limit()` has been deprecated to support the new `TxPolicy`, replacing `TxParameters`.

```sway
/* BEFORE - v0.46.0 */
fn get_tx_gas_limit() -> u64;

/* AFTER - v0.49.2 */
fn get_script_gas_limit() -> u64;
```

The existing functions inside the standard library `tx`, including `tx_gas_price()` and `tx_maturity()`, now return `Option<u64>` and `Option<u32>` respectively, instead of just `u64` and `u32`.

```sway
/* BEFORE - v0.46.0 */
fn get_tx_maturity() -> u32 {
    tx_maturity()
}

/* AFTER - v0.49.2 */
fn get_tx_maturity() -> u32 {
    tx_maturity().unwrap()
}
```

Along with these changes, GTF opcodes have been updated in the following standard libraries.

1. [inputs.sw](https://github.com/FuelLabs/sway/pull/5281/files#diff-427b18b1692c5ee5541b43013d9859363da2c2fa6e940b25045d2514cac97428)
2. [outputs.sw](https://github.com/FuelLabs/sway/pull/5281/files#diff-0625712126eb9f0c821b18e48379ad1213d6cbe0d38ba4fe721260232fb48eca)
3. [tx.sw](https://github.com/FuelLabs/sway/pull/5281/files#diff-038f9ff7e5241cc345c0d460a0100ab88fbc72ac76db0e9af923bc8342b5c0c9)

Byte conversions and array conversions for u256, u64, u32, u16, and b256 have been introduced into the standard library.

1. [Byte conversions](https://github.com/FuelLabs/sway/tree/master/sway-lib-std/src/bytes_conversions)

```sway
/* AFTER - v0.49.2 */
fn foo() {
  let x: u16 = 513;
  let result = x.to_le_bytes();

  assert(result[0] == 1_u8);
  assert(result[1] == 2_u8);
}
```

<!-- markdownlint-disable md029 -->

2. [Array conversions](https://github.com/FuelLabs/sway/tree/master/sway-lib-std/src/array_conversions)

```sway
/* AFTER - v0.49.2 */
fn foo() {
  let x: u16 = 513;
  let result = x.to_le_bytes();

  assert(result.get(0).unwrap() == 1_u8);
  assert(result.get(1).unwrap() == 2_u8);
}
```

<!-- markdownlint-enable md029 -->

Power uses a `u32` instead of self

```sway
/* BEFORE - v0.46.0 */
assert(2u16.pow(2u16) == 4u16);

/* AFTER - v0.49.2 */
assert(2u16.pow(2u32) == 4u16);
```

### TS SDK

Release: [TS SDK v0.73.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.73.0)

Several `fuel-core` configuration-related options have been removed from the `LaunchNodeOptions`. These include: `chainConfigPath`, `consensusKey`, `useInMemoryDb`, and `poaInstant`. These options can now only be passed through the `args` property.

```typescript
/* BEFORE - v0.60.0 */
const { cleanup, ip, port } = await launchNode({
  chainConfigPath,
  consensusKey = "0xa449b1ffee0e2205fa924c6740cc48b3b473aa28587df6dab12abc245d1f5298",
  args: defaultFuelCoreArgs,
});

/* AFTER - v0.73.0 */
const { cleanup, ip, port } = await launchNode({
  args: ["--poa-instant", "false", "--poa-interval-period", "400ms"],
});
```

Contract calls requires `gasLimit` and `gasPrice` to be specified in `txParams()`.

```typescript
/* BEFORE - v0.60.0 */
let resp = await contract.functions.count().simulate();

/* AFTER - v0.73.0 */
let resp = await contract.functions
  .count()
  .txParams({ gasPrice: 1, gasLimit: 100_000 })
  .simulate();
```

`chainInfoCache` and `nodeInfoCache` are now private methods, to prevent users from accessing invalid cached information after it becomes stale.

```typescript
/* BEFORE - v0.60.0 */
Provider.chainInfoCache[FUEL_NETWORK_URL];
Provider.nodeInfoCache[FUEL_NETWORK_URL];

/* AFTER - v0.73.0 */
provider.getChain();
provider.getNode();
```

The `switchURL()` method, used to update the URL for the provider, is now named `connect()`.

```typescript
/* BEFORE - v0.60.0 */
await provider.switchUrl(altProviderUrl);

/* AFTER - v0.73.0 */
await provider.connect(altProviderUrl);
```

Support for new Sway types has been introduced with:

1. Bytes

```typescript
/* AFTER - v0.73.0 */
const bytes = [40, 41, 42];
const { value } = await contract.functions.bytes_comparison(bytes).simulate();
```

<!-- markdownlint-disable md029 -->

2. Raw Slices

```typescript
/* AFTER - v0.73.0 */
const rawSlice = [40, 41, 42];
const { value } = await contract.functions
  .raw_slice_comparison(rawSlice)
  .simulate();
```

3. StdString

```typescript
/* AFTER - v0.73.0 */
const stdString = "Hello World";
const { value } = await contract.functions
  .string_comparison(stdString)
  .simulate();
```

<!-- markdownlint-enable md029 -->

Typegen attempts to resolve, auto-load, and embed the Storage Slots for your Contract within the `MyContract__factory` class. However, you can override this, along with other options, when calling the `deployContract` method:

```typescript
/* AFTER - v0.73.0 */
import storageSlots from "../contract/out/debug/storage-slots.json";

const contract = await MyContract__factory.deployContract(bytecode, wallet, {
  storageSlots,
});
```

`concat`, `arrayify`, and `hexlify` have been introduced to the utils to replace their respective functions from the ethers library, avoiding the reexporting of ethers functions.

```typescript
/* BEFORE - v0.60.0 */
import { concat, arrayify, hexlify } from "@ethersproject/bytes";

const someBytes = concat([
  new Uint8Array([1, 2, 3]),
  new Uint8Array([4, 5, 6]),
  new Uint8Array([7, 8, 9]),
]);
const someHex = hexlify(new Uint8Array([0, 1, 2, 3]));
const someArray = arrayify(new Uint8Array([0, 1, 2, 3]));

/* AFTER - v0.73.0 */
import { concat, arrayify, hexlify } from "@fuel-ts/utils";

const someBytes = concat([
  new Uint8Array([1, 2, 3]),
  new Uint8Array([4, 5, 6]),
  new Uint8Array([7, 8, 9]),
]);
const someHex = hexlify(new Uint8Array([0, 1, 2, 3]));
const someArray = arrayify(new Uint8Array([0, 1, 2, 3]));
```

`Address` types can no longer be used directly to represent a `b256` and must instead use the `toB256()` conversion method.

```typescript
/* BEFORE - v0.60.0 */
const addressId = {
  value: userWallet.address,
};

tokenContract.functions
  .transfer_coins_to_output(addressId, assetId, amount)
  .call();

/* AFTER - v0.73.0 */
const addressId = {
  value: userWallet.address.toB256(),
};

tokenContract.functions
  .transfer_coins_to_output(addressId, assetId, amount)
  .call();
```

The `Account` class's `fund()` method now takes in two new parameters: `quantities` and `fee`, of types `CoinQuantity[]` and `BN`, respectively. These can be derived from the provider's `getTransactionCost()` method.

```typescript
/* BEFORE - v0.60.0 */
await wallet.fund(transactionRequest);

/* AFTER - v0.73.0 */
const { maxFee, requiredQuantities } = await provider.getTransactionCost(
  transactionRequest
);

await wallet.fund(transactionRequest, quantities, fee);
```

The `provider`'s `getTransactionCost` now breaks down its old `fee` into `minFee`, `usedFee`, and `maxFee`, based on the actual calculation of the transaction. Additionally, `requiredQuantities`, `receipts`, `minGas`, and `maxGas`, of types `coinQuantity[]`, `TransactionResultReceipt[]`, `BN`, and `BN` respectively, have also been introduced to improve the granularity of cost estimation.

```typescript
/* BEFORE - v0.60.0 */
const { fee } = await this.account.provider.getTransactionCost(
  transactionRequest
);

/* AFTER - v0.73.0 */
const {
  requiredQuantities,
  receipts,
  minGas,
  maxGas,
  minFee,
  maxFee,
  usedFee,
} = await this.account.provider.getTransactionCost(transactionRequest);
```

The `getTransferOperations` function now takes in a `receipts` parameter as well, ensuring that contract transactions return the transfer asset.

```typescript
/* BEFORE - v0.60.0 */
const operations = getTransferOperations({ inputs: [], outputs: [] });

/* AFTER - v0.73.0 */
const operations = getTransferOperations({
  inputs: [],
  outputs: [],
  receipts: [],
});
```

The predicate introduces a new `getTransferTxId`, a method to calculate the transaction ID for a `Predicate.transfer` transaction.

```typescript
/* AFTER - v0.73.0 */
const txId = await predicate.getTransferTxId(address, amount, BaseAssetId, {
  gasPrice,
});
```

The `deployContract` method contains a new parameter, `storageSlotsPath`, to avoid issues that may arise if storage slots are not auto-loaded. Without auto-loading, some contracts will revert due to improper or missing initialization of storage slots.

```typescript
/* BEFORE - v0.60.0 */
const assetId = BaseAssetId;

/* AFTER - v0.73.0 */
const assetId: AssetId = { value: BaseAssetId };
```

`AssetId` has been introduced to match the Sway standard library as a `Struct` wrapper around an inner `Bits256` value.

### Rust SDK

Release: [Rust SDK v0.55.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.55.0)

The `sign_message()` and `sign_transaction` functions in the `Signer` trait have been consolidated into a single method, now simply named `sign`.

```rust
/* BEFORE - v0.48.0 */
let signature1: B512 = wallet.sign_message(data_to_sign).await?.as_ref().try_into()?;

/* AFTER - v0.55.0 */
let signature1: B512 = wallet.sign(data_to_sign).await?.as_ref().try_into()?;
```

The function `check_without_signatures` in the `Transaction` trait has been renamed to `check`. This updated `check` function retains its original capabilities and now includes the additional feature of checking with signatures.

```rust
/* BEFORE - v0.48.0 */
tx.check_without_signatures(chain_info.latest_block.header.height, self.consensus_parameters())?;

/* AFTER - v0.55.0 */
tx.check(chain_info.latest_block.header.height, self.consensus_parameters())?;
```

The typo in the `add_witnessses` function name under the `Account` trait has been fixed and is now `add_witnesses`.

```rust
/* BEFORE - v0.48.0 */
account.add_witnessses(&mut tb);

/* AFTER - v0.55.0 */
account.add_witnesses(&mut tb)?;
```

Use of `Message`, `PublicKey`, `SecretKey` and `Signature` can be found inside `fuels::crypto::` now.

```rust
/* BEFORE - v0.48.0 */
use fuels::accounts::fuel_crypto::SecretKey;

/* AFTER - v0.55.0 */
use fuels::crypto::SecretKey,
```

The `submit_and_await_commit()` function now returns a `TxStatus` instead of a `TxId`.

```rust
/* BEFORE - v0.48.0 */
let tx_id = self.client.submit_and_await_commit(&tx.clone().into()).await?.into();

/* AFTER - v0.55.0 */
let tx_status = self.client.submit_and_await_commit(&tx.clone().into()).await?.into();
```

When constructing a transaction, the provider already possesses all the necessary information, rendering `NetworkInfo` and all its related functions and methods obsolete. Consequently, `ScriptTransactionBuilder::new`, `CreateTransactionBuilder::new`, and `Provider::new` have been removed for `::default()`.

```rust
/* BEFORE - v0.48.0 */
use fuels_core::types::transaction_builders::{DryRunner, NetworkInfo}

ScriptTransactionBuilder::new(network_info)

/* AFTER - v0.55.0 */
use fuels_core::types::transaction_builders::{DryRunner}

ScriptTransactionBuilder::default()
```

In Sway, `U256` has been deprecated in favor of `u256`. It is no longer supported in the SDK. Usage of `U256` will now result in a runtime error.

`TxPolicies` supersedes `TxParameters`.

```rust
/* BEFORE - v0.48.0 */
let tx_parameters = TxParameters::default()

/* AFTER - v0.55.0 */
let tx_policies = TxPolicies::default()
```

Three new optional fields have been introduced in `TxPolicies`:

1. `WitnessLimit`, which sets a new restriction for transaction witnesses by introducing a limit on the maximum byte size of witnesses in transactions.
2. `MaxFee`, which sets an upper limit on the transaction fee that a user is willing to pay.
3. `ScriptGasLimit`, which no longer constrains predicate execution time but exclusively limits the gas limit of scripts. If this field is not set, the SDK will estimate gas consumption and set it automatically.

Additionally, `GasPrice` and `Maturity` fields within `TxPolicies` are now optional parameters.

```rust
/* BEFORE - v0.48.0 */
let tx_parameters = TxParameters::new(gas_price, gas_limit, maturity)

/* AFTER - v0.55.0 */
let tx_policies = TxPolicies::new(Some(gas_price), Some(witness_limit), Some(maturity), Some(max_fee), Some(script_gas_limit))
```

`TxPolicy` Pitfalls

1. If the `max_fee` is greater than `policies.max_fee`, then the transaction will be rejected.
2. If the `witnesses_size` is greater than `policies.witness_limit`, then the transaction will be rejected.

The predicate's `get_message_proof` now uses `nonce` instead of `msg_id`.

```rust
/* BEFORE - v0.48.0 */
let proof = predicate.try_provider()?
  .get_message_proof(&tx_id, &msg_id, None, Some(2))

/* AFTER - v0.55.0 */
let proof = predicate.try_provider()?
  .get_message_proof(&tx_id, &msg_nonce, None, Some(2))
```

When using local chain configs, the `manual_blocks_enabled` option is replaced by the new `debug` flag. Additionally, with `local_node()` being deprecated in favor of `default()`, the options `utxo_validation` and `manual_blocks_enabled` are enabled by default for the test providers.

```rust
/* BEFORE - v0.48.0 */
let config = Config {
    utxo_validation: true,
    manual_blocks_enabled: true,
    ..Config::local_node()
};

/* AFTER - v0.55.0 */
let config = Config {
    ..Config::default()
};
```

When using `transaction_builders`, the `BuildableTransaction` trait must be in scope.

```rust
/* BEFORE - v0.48.0 */
use fuels_core::{
    types::{
        transaction_builders::{TransactionBuilder, ScriptTransactionBuilder},
    },
};

/* AFTER - v0.55.0 */
use fuels_core::{
    types::{
        transaction_builders::{BuildableTransaction, ScriptTransactionBuilder},
    },
};
```

## October 2, 2023

### TS SDK

Release: [TS SDK v0.60.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.60.0)

`Provider` is used so widely in our SDK, there are multiple breaking changes that we need to be aware of and need to communicate to our users:

```typescript
/* BEFORE - v0.57.0 */
const provider = new Provider(url);

/* AFTER - v0.60.0 */
const provider = await Provider.create(url);
```

All of these methods now require a `Provider` to be passed in:

#### Wallet Methods

Some of these methods used to accept a URL instead of a `Provider` object. Note that the `provider` parameter _has_ to be a `Provider` object now.

```typescript
const provider = await Provider.create(url);
```

```typescript
/* BEFORE - v0.57.0 */
WalletUnlocked.fromSeed(seed, path);

WalletUnlocked.fromMnemonic(mnemonic, path, passphrase);

WalletUnlocked.fromExtendedKey(extendedKey);
await WalletUnlocked.fromEncryptedJson(jsonWallet, password);

Wallet.fromAddress(address);

Wallet.fromPrivateKey(pk);

Wallet.generate();

/* AFTER - v0.60.0 */
WalletUnlocked.fromSeed(seed, provider, path);

WalletUnlocked.fromMnemonic(mnemonic, provider, path, passphrase);

WalletUnlocked.fromExtendedKey(extendedKey, provider);
await WalletUnlocked.fromEncryptedJson(jsonWallet, password, provider);

Wallet.fromAddress(address, provider);

Wallet.fromPrivateKey(pk, provider);

Wallet.generate({ provider });
```

#### 'Account' Class

```typescript
/* BEFORE - v0.57.0 */
const account = new Account(address);

/* AFTER - v0.60.0 */
const account = new Account(address, provider);
```

#### `PrivateKeyVault`

These are the options that are accepted by the `PrivateKeyVault` constructor. `provider` is now a required input.

```typescript
/* BEFORE - v0.57.0 */
interface PkVaultOptions {
  secret?: string;
  accounts?: Array<string>;
}

/* AFTER - v0.60.0 */
interface PkVaultOptions {
  secret?: string;
  accounts?: Array<string>;
  provider: Provider;
}
```

#### `MnemonicVault`

```typescript
/* BEFORE - v0.57.0 */
interface MnemonicVaultOptions {
  secret?: string;
  accounts?: Array<string>;
}

/* AFTER - v0.60.0 */
interface MnemonicVaultOptions {
  secret?: string;
  accounts?: Array<string>;
  provider: Provider;
}
```

#### `WalletManager`

```typescript
/* BEFORE - v0.57.0 */
export type VaultConfig = {
  type: string;
  title?: string;
  secret?: string;
};

/* AFTER - v0.60.0 */
export type VaultConfig = {
  type: string;
  title?: string;
  secret?: string;
  provider: Provider;
};
```

#### Predicates

The `provider` is no longer optional. Note the change in parameter order, and that `chainId` is no longer required to be passed.

```typescript
/* BEFORE - v0.57.0 */
const predicate = new Predicate(bytes, chainId, jsonAbi);

/* AFTER - v0.60.0 */
const predicate = new Predicate(bytes, provider, jsonAbi);
```

## September 18, 2023

### Sway

Release: [Sway v0.46.0](https://github.com/FuelLabs/sway/releases/tag/v0.46.0)

From now on, string literals produce the `str` slice type instead of the string array type. To convert between string arrays and slices, you can use the newly provided intrinsics.

```sway
/* BEFORE - v0.45.0 */
let my_string: str[4] = "fuel";

/* AFTER - v0.46.0 */
let my_string: str = "fuel";
```

If you use a function that needs a specific trait and you don't import that trait, the compiler now will raise an error. This is because the compiler isn't aware of the trait in the current context.

For the example below you would now get an error if the `Hash` trait for `u64` isn't imported. To solve this, ensure you import the "Hash" trait.

```sway
/* BEFORE - v0.45.0 */
storage {
    item_map: StorageMap<u64, Item> = StorageMap {},
}

/* AFTER - v0.46.0 */
use std::{
    hash::Hash,
};

storage {
    item_map: StorageMap<u64, Item> = StorageMap {},
}
```

### TS SDK

Release: [TS SDK v0.57.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.57.0)

The `addResourceInputsAndOutputs()` function has been renamed to `addResources()`, streamlining its name.

```typescript
/* BEFORE - v0.55.0 */
request.addResourceInputsAndOutputs(resources);

/* AFTER - v0.57.0 */
request.addResources(resources);
```

Similarly, `addPredicateResourcesInputsAndOutputs()` is now more concisely known as `addPredicateResources()`.

The reason we have a distinct method for adding predicate resources is that the creation of predicate inputs mandates the presence of both the predicate's bytes and data bytes. With these methods, there's no longer a need to manually create and set up an instance of a `ScriptTransactionRequest`, simplifying the process further.

```typescript
/* BEFORE - v0.55.0 */
const predicateInputs: TransactionRequestInput[] = predicateUtxos.map(
  (utxo) => ({
    id: utxo.id,
    type: InputType.Coin,
    amount: utxo.amount,
    assetId: utxo.assetId,
    owner: utxo.owner.toB256(),
    txPointer: "0x00000000000000000000000000000000",
    witnessIndex: 0,
    maturity: 0,
    predicate: predicate.bytes,
    predicateData: predicate.predicateData,
  })
);

/* AFTER - v0.57.0 */
request.addPredicateResources(
  predicateUtxos,
  predicate.bytes,
  predicate.predicateData
);
```

### Rust SDK

Release: [Rust SDK v0.48.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.48.0)

The function `calculate_base_amount_with_fee()` currently returns a value of type `Option<64>`.

```rust
/* BEFORE - v0.47.0 */
let new_base_amount = calculate_base_amount_with_fee(&tb, &consensus_parameters, previous_base_amount)

/* AFTER - v0.48.0 */
let new_base_amount = calculate_base_amount_with_fee(&tb, &consensus_parameters, previous_base_amount)?
```

The function `calculate_base_amount_with_fee()` now returns a value of type `Result<Option<TransactionFee>>` instead of `Option<TransactionFee>`.

```rust
/* BEFORE - v0.47.0 */
let transaction_fee = tb.fee_checked_from_tx(consensus_params).expect("Error calculating TransactionFee");

/* AFTER - v0.48.0 */
let transaction_fee = tb.fee_checked_from_tx(consensus_params)?.ok_or(error!(InvalidData, "Error calculating TransactionFee"))?;
```

Storage slots are now automatically loaded in when using the default configuration.

```rust
/* BEFORE - v0.47.0 */
let storage_config =
StorageConfiguration::load_from("out/debug/contract-storage_slots.json").unwrap();

let load_config = LoadConfiguration::default().with_storage_configuration(storage_config);

let id = Contract::load_from(
    "./out/debug/contract.bin",
    load_config,
)
.unwrap()
.deploy(&wallet, TxParameters::default())
.await
.unwrap();

/* AFTER - v0.48.0 */
let id = Contract::load_from(
    "./out/debug/contract.bin",
    LoadConfiguration::default(),
)
.unwrap()
.deploy(&wallet, TxParameters::default())
.await
.unwrap();
```


---

### File: docs/migrations-and-disclosures/docs/src/index.md

# Migrations and Disclosures

## Audits

All public audits conducted on the Fuel network can be found [here](https://github.com/FuelLabs/audits)

## Breaking Changes

Throughout Fuel's development journey, numerous testnets have been created to ensure a seamless transition to the mainnet launch.
Given the dynamic nature of learning and adapting during these testing phases, it's common to encounter breaking changes.

Learn how to migrate to the latest versions of Sway and the SDKs [here](./migrations/index.md)!


---

### File: docs/migrations-and-disclosures/docs/src/migrations/index.md

# Migrations

This section provides information to help with breaking changes, but for full releases, please reference the GitHub release notes tagged in the respective modules.

## Sway

Full migration reference can be found [here](./sway.md)

## Rust SDK

Full migration reference can be found [here](./rust-sdk.md)

## Typescript SDK

Full migration reference can be found [here](./typescript-sdk.md)


---

### File: docs/migrations-and-disclosures/docs/src/migrations/rust-sdk.md

# Rust SDK Migrations Guide

## March 17, 2025

[Release v0.71.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.71.0)

### Bump minimum `fuel-core-*` versions - [#1600](https://github.com/FuelLabs/fuels-rs/pull/1600)

Minimum `fuel-core-*` versions bumped to `0.41.7`

```rust
// before
fuel-core = { version = "0.41.3", default-features = false, features = [
  "wasm-executor",
] }
fuel-core-chain-config = { version = "0.41.3", default-features = false }
...
```

```rust
// after
fuel-core = { version = "0.41.7", default-features = false, features = [
  "wasm-executor",
] }
fuel-core-chain-config = { version = "0.41.7", default-features = false }
...
```

### Wallet refactoring - [#1620](https://github.com/FuelLabs/fuels-rs/pull/1620)

#### `ImpersonatedAccount` is removed

To achieve the same functionality instantiate a `FakeSigner:

```rust
// before
let address =
    Address::from_str("0x17f46f562778f4bb5fe368eeae4985197db51d80c83494ea7f84c530172dedd1")
        .unwrap();
let address = Bech32Address::from(address);
let impersonator = ImpersonatedAccount::new(address, Some(provider.clone()));
```

```rust
// after
let some_address = wallet.address().clone();
let fake_signer = FakeSigner::new(some_address);
let impersonator = Wallet::new(fake_signer, provider.clone());
```

#### `AwsKmsSigner` and `GoogleKmsSigner` moved

under `fuels::accounts::signers::kms::aws` and `fuels::accounts::signers::kms::google`, respectfully.

```rust
// before
use fuels::accounts::kms::AwsKmsSigner;
use fuels::accounts::kms::GoogleKmsSigner;
```

```rust
// after
use fuels::accounts::signers::kms::aws::AwsKmsSigner;
use fuels::accounts::signers::kms::google::GoogleKmsSigner;
```

#### `KmsWallet` removed

use an ordinary `Wallet` now with a kms signer (aws or google)

#### `WalletUnlocked` and `Wallet` substituted by `Wallet<Unlocked<S = PrivateKeySigner>>` or `Wallet<Locked>`

```rust
// before
wallet.set_provider(provider.clone());

...

let mut wallet = WalletUnlocked::new_random(None);

let coins: Vec<Coin> = setup_single_asset_coins(
    wallet.address(),
    Default::default(),
    DEFAULT_NUM_COINS,
    DEFAULT_COIN_AMOUNT,
);

let chain_config = ChainConfig {
    consensus_parameters: consensus_parameters.clone(),
    ..ChainConfig::default()
};

let provider = setup_test_provider(coins, vec![], None, Some(chain_config)).await?;
wallet.set_provider(provider.clone());
assert_eq!(consensus_parameters, provider.consensus_parameters().await?);

...

let wallet = WalletUnlocked::new_random(None);
```

```rust
// after
let wallet = Wallet::new(signer, provider.clone());

...

let mut rng = thread_rng();
let signer = PrivateKeySigner::random(&mut rng);

let coins: Vec<Coin> = setup_single_asset_coins(
    signer.address(),
    Default::default(),
    DEFAULT_NUM_COINS,
    DEFAULT_COIN_AMOUNT,
);
let chain_config = ChainConfig {
    consensus_parameters: consensus_parameters.clone(),
    ..ChainConfig::default()
};

let provider = setup_test_provider(coins, vec![], None, Some(chain_config)).await?;
let wallet = Wallet::new(signer, provider.clone());
assert_eq!(consensus_parameters, provider.consensus_parameters().await?);

...

let wallet = launch_provider_and_get_wallet().await?;
```

The provider is now mandatory for `Wallet::new`.

Common operations in the new API:

##### Creating a random wallet

a) Two step (useful when you haven't started the node but need the address)

```rust
    // Create a random private key signer
    let signer = PrivateKeySigner::random(&mut rng);
    let coins = setup_single_asset_coins(signer.address(), asset_id, 1, DEFAULT_COIN_AMOUNT);
    let provider = setup_test_provider(coins.clone(), vec![], None, None).await?;
    let wallet = Wallet::new(signer, provider);
 ```

b) One step (when you already have a provider)

```rust
    let wallet = Wallet::random(&mut rng, provider.clone());
```

##### Locking a wallet

```rust
    let locked_wallet = wallet.lock();
```

##### Creating a locked wallet

```rust
    let wallet = Wallet::new_locked(addr, provider.clone());
```

##### Wallets no longer sign

You use one of the signers for that. Or, if your wallet is unlocked, get its signer by calling `wallet.signer()`.

#### `ViewOnlyAccount` no longer requires `core::fmt::Debug` and `core::clone::Clone` as supertraits

#### `Wallet` no longer handles encrypting keys for disk storage

Use the `fuels::accounts::Keystore` for that (feature-gated under `accounts-keystore`)

#### AWS/Google kms feature flags changed

They're now `accounts-signer-aws-kms` and `accounts-signer-google-kms`.

### Use `total_gas` and `total_fee` from tx status - [#1574](https://github.com/FuelLabs/fuels-rs/pull/1574)

- Removed `get_response_from` method from `CallHandlers`
- `CallResponse` refactored and added `tx_status: Success` field
- Method `get_response` accepts `TxStatus` instead of `Vec<Receipts>`
- Method `new` is removed form `CallResponse`
- `GasValidation` trait is removed from transaction builders
- `Account`s  `transfer` method returns `Result<TxResponse>`
- `Account`s  `force_transfer_to_contract` method returns `Result<TxResponse>`
- `Account`s  `withdraw_to_base_layer` method returns `Result<WithdrawToBaseResponse>`
- `Executable<Loader>`'s `upload_blob` returns `Result<Option<TxResponse>>`
- Contract's `deploy` and `deploy_if_not_exists` return `Result<DeployResponse>` and `Response<Option<DeployResponse>>` respectively
- `TransactionCost`'s field `gas_used` renamed to `script_gas`

## August 16, 2024

[Release v0.66.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.66.0)

### Unfunded read only calls - [#1412](https://github.com/FuelLabs/fuels-rs/pull/1412)

`SizedAsciiString` no longer implements `AsRef<[u8]>`. To get the underlying bytes you can turn it into a `&str` via the new `AsRef<str>` and call `as_bytes()` on the `&str`: `sized_string.as_ref().as_bytes()``

```rust
// before
let bytes: &[u8] = sized_str.as_ref();
```

```rust
// after
let bytes: &[u8] = sized_str.as_ref().as_bytes();
```

`build_without_signatures` is now achieved by setting the build strategy to `BuildStrategy::NoSignatures` on the transaction builder before calling `build`

```rust
// before
let mut tx = tb.build_without_signatures(provider).await?;
```

```rust
// after
let mut tx = tb.with_build_strategy(ScriptBuildStrategy::NoSignatures).build(provider).await?;
```

`.simulate()` now accepts an `Execution` argument allowing for `Realistic` or `StateReadOnly` simulations.

```rust
// before
let stored = contract_methods.read().simulate().await?;
```

```rust
// after
let stored = contract_methods.read().simulate(Execution::StateReadOnly).await?;
```

### Accounts now cover max fee increase due to tolerance - [#1464](https://github.com/FuelLabs/fuels-rs/pull/1464)

`fee_checked_from_tx` is removed from all transaction builders. max fee can now be estimated using the new method `estimate_max_fee` which takes into account the max fee estimation tolerance set on the builders.

```rust
// before
let transaction_fee = tb.fee_checked_from_tx(provider)
    .await?
    .ok_or(error_transaction!(
        Other,
        "error calculating `TransactionFee`"
    ))?;

let total_used = transaction_fee.max_fee() + reserved_base_amount;
```

```rust
// after
let max_fee = tb.estimate_max_fee(provider).await?;

let total_used = max_fee + reserved_base_amount;
```

### Account impersonation - [#1473](https://github.com/FuelLabs/fuels-rs/pull/1473)

The SDK previously performed transaction validity checks, including signature verification, before sending a transaction to the network. This was problematic since the checks also included signature verification even when utxo validation was turned off. To enable this feature and prevent future issues like failed validation checks due to version mismatches between the network and the SDK's upstream dependencies, we decided to remove the check. Since the SDK already abstracts building transactions for common cases (contract calls, transfers, etc.), validity issues are unlikely. If needed, we can still expose the validity checks as part of the transaction builder or our transaction structs.

```rust
/*

A `ImpersonatedAccount` simulates ownership of assets held by an account with a given address.
`ImpersonatedAccount` will only succeed in unlocking assets if the the network is setup with
utxo_validation set to false.

*/

let node_config = NodeConfig {
    utxo_validation: false,
    ..Default::default()
};
```

### Deploying large contracts (loader + blob support) - [#1472](https://github.com/FuelLabs/fuels-rs/pull/1472)

`Contract::new` is removed, replaced with `Contract::regular` with three states

First: A regular contract

What you're used to seeing. It is either initialized from raw code or loaded from a file:

```rust
let contract = Contract::regular(contract_binary, Salt::zeroed(), vec![]);
```

or

```rust
let contract = Contract::load_from(
    "sway/contracts/storage/out/release/storage.bin",
    LoadConfiguration::default(),
)?;
```

With the notable addition of being able to set `configurables` (previously possible only when using `load_from`):

```rust
let contract = Contract::regular(binary, Salt::zeroed(), vec![]).with_configurables(configurables);
```

a regular contract can be deployed via `deploy`, which hasn't changed, or via `smart_deploy` that will use blobs/loader if the contract is above what can be deployed in a create tx:

```rust
let contract_id = Contract::load_from(
    contract_binary,
    LoadConfiguration::default().with_salt(random_salt()),
)?
.smart_deploy(&wallet, TxPolicies::default(), max_words_per_blob)
.await?;
```

Second: Loader contract, blobs pending upload

You can turn a regular contract into a loader contract:

```rust
let contract = Contract::load_from(
    contract_binary,
    LoadConfiguration::default(),
)?
.convert_to_loader(max_words_per_blob)?
```

or, if you have the blobs, create it directly:

```rust
let contract = Contract::loader_for_blobs(blobs, random_salt(), vec![])?;
```

You can also revert back to the regular contract via `revert_to_regular`.

If you now call `deploy` the contract will first deploy the blobs and then the loader itself.

You can also split this into two parts by first calling `upload_blobs` and then `deploy`:

```rust
let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())?
    .convert_to_loader(1024)?
    .upload_blobs(&wallet, TxPolicies::default())
    .await?
    .deploy(&wallet, TxPolicies::default())
    .await?;
```

doing so will have `deploy` only submit the create tx while the uploading will be done in `upload_blobs`.

Third: Loader, with blobs deployed

You arrive at this contract type by either having the blob ids and creating it manually:

```rust
let contract = Contract::loader_for_blob_ids(all_blob_ids, random_salt(), vec![])?;
```

or by calling `upload_blobs` as in the previous case:

```rust
let contract = Contract::load_from(
    contract_binary,
    LoadConfiguration::default().with_salt(random_salt()),
)?
.convert_to_loader(max_words_per_blob)?
.upload_blobs(&wallet, TxPolicies::default())
.await?;
```

Calling deploy on this contract only deploys the loader.


---

### File: docs/migrations-and-disclosures/docs/src/migrations/sway.md

# Sway Migrations Guide

## March 13, 2024

[Release v0.67.0](https://github.com/FuelLabs/sway/releases/tag/v0.67.0)

### New `forc migrate`

Below is a simplified example of how to migrate your project quickly. For more information on how to use `forc migrate` please refer to the [`forc migrate` docs](https://docs.fuel.network/docs/forc/plugins/forc_migrate/#forc-migrate).

> Important: Using `forc migrate` requires you to use the version of Sway right before the breaking change version.

For example, breaking changes for Sway will come in version `v0.67.0`, you will need to use `v0.66.10` to run `forc migrate`, in order to migrate properly.

You can compile and migrate using the previous latest version by running the following command:

```bash
fuelup component add forc@0.66.10
```

#### 1. Run `forc migrate show`

Running `forc migrate show` will inform you about all the breaking changes in the next release. For example:

```sh
Breaking change features:
  - storage_domains            (https://github.com/FuelLabs/sway/issues/6701)
  - partial_eq                 (https://github.com/FuelLabs/sway/issues/6883)
  - try_from_bytes_for_b256    (https://github.com/FuelLabs/sway/issues/6994)
  - merge_core_std             (https://github.com/FuelLabs/sway/issues/7006)

Migration steps (1 manual, 3 semiautomatic, and 3 automatic):
storage_domains
  [M] Review explicitly defined slot keys in storage declarations (`in` keywords)
  [S] Explicitly define storage slot keys if they need to be backward compatible

partial_eq
  [A] Implement experimental `PartialEq` and `Eq` traits
  [S] Remove deprecated `Eq` trait implementations and `experimental_partial_eq` attributes

try_from_bytes_for_b256
  [A] Replace `b256::from(<bytes>)` calls with `b256::try_from(<bytes>).unwrap()`
  [A] Replace `<bytes>.into()` calls with `<bytes>.try_into().unwrap()`

merge_core_std
  [S] Replace `core` with `std` in paths

Experimental feature flags:
- for Forc.toml:  experimental = { storage_domains = true, partial_eq = true, try_from_bytes_for_b256 = true, merge_core_std = true }
- for CLI:        --experimental storage_domains,partial_eq,try_from_bytes_for_b256,merge_core_std
```

#### 2. Update `forc.toml` dependencies

In your Sway project, update the `forc.toml` file to use the previous latest version of Sway.

```toml
// before

[dependencies]
standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.1" }
sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.24.0" }
```

```toml
// after

[dependencies]
standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.3" }
sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.24.2" }
```

#### 3. Run `forc migrate run`

Running `forc migrate run` walks you through each of the breaking changes and helps you apply them to your project.
If you just want to see the breaking changes in your project without migrating them, you can run `forc migrate check`.

```sh
   Compiling mira_amm_contract (/mira-v1-core/contracts/mira_amm_contract)
warning: unused manifest key: build-profile.?.release.experimental
   Migrating Breaking change feature storage_domains
     Checked [storage_domains]  Review explicitly defined slot keys in storage declarations (`in` keywords)
      Review [storage_domains]  Explicitly define storage slot keys if they need to be backward compatible
info: [storage_domains] Explicitly define storage slot keys if they need to be backward compatible
  --> /mira-v1-core/contracts/mira_amm_contract/src/main.sw:65:1
   |
63 |   
64 |   
65 | / storage {
66 | |     /// Pools storage
...  |
79 | |     hook: Option<ContractId> = None,
80 | | }
   | |_-
   |
   = help: If the contract owning this storage is behind a proxy, or for any other reason needs
   = help: to use previous storage slot keys, those keys must be explicitly assigned to the
   = help: storage fields by using the `in` keyword.
   = help:  
   = help: E.g.:
   = help:     storage {
   = help:         field in <previous slot key>: u64 = 0,
   = help:     }
   = help:  
   = help: The previous formula for calculating storage keys was: `sha256("storage.<field name>")`.
   = help: The new formula is:                                    `sha256((0u8, "storage.<field name>"))`.
   = help:  
   = help: This migration step will interactively modify the code, based on your input.
   = help:  
   = help: For a detailed migration guide see: https://github.com/FuelLabs/sway/issues/6701
____

The following storage fields will have slot keys calculated by using the new formula:
  - storage.pools
  - storage.total_pools
  - storage.total_reserves
  - storage.lp_total_supply
  - storage.lp_name
  - storage.protocol_fees
  - storage.hook

Do you want these fields to have backward compatible storage slot keys, calculated
by using the previous formula?

If yes, this migration step will insert `in` keywords to all of the above fields,
and calculate the storage slot keys by using the previous formula.

1. Yes, assign the backward compatible storage slot keys.
2. No, this contract does not require backwards compatibility.
Enter your choice [1..2]: 1
    Changing [storage_domains]  Explicitly define storage slot keys if they need to be backward compatible
Source code successfully changed (7 changes).
    Finished Project is compatible with the next breaking change version of Sway
```

#### 4. Switch to the latest version of Sway

```sh
// Assuming you have 0.67.0 installed
fuelup default latest
```

#### 5. Compile your project

```sh
forc build
```

> Using the `forc migrate` tool is highly recommended, and the changes below are only for reference.

### Compiler/std-lib: storage collison between variables and StorageMap, allows hidden backdoors, likely loss of funds - [#6701](https://github.com/FuelLabs/sway/issues/6701)

Certain storage types, like, e.g., `StorageMap` allow storage slots of their contained elements to be defined based on developer's input. E.g., the key in a `StorageMap` used to calculate the storage slot is a developer input.

To ensure that pre-images of such storage slots can never be the same as a pre-image of compiler generated key of a storage field, we will prefix the pre-images of storage fields with a single byte that denotes the storage field domain. Storage types like `StorageMap` must have a different domain prefix than this storage field domain which will be set to 0u8.

```sway
// before
sha256("storage::<optional namespace 1>::<optional namespace 2>.<field name>")
```

```sway
// after
sha256((0u8, "storage::<optional namespace 1>::<optional namespace 2>.<field name>"))
```

If the contract owning the storage is behind a proxy, its storage field keys must be backward compatible and the same as the old keys. In this, and any other case where the backward compatibility of the storage slot keys is needed, the old keys must be explicitly defined for storage fields, by using the in keyword and the old keys.

E.g., assume we have a contract with the following storage behind a proxy:

```sway
// before
storage {
    x: u64 = 0,
    namespace_1 {
        y: u64 = 0,
        namespace_2 {
            z: u64 = 0,
        }
    }
}
```

```sway
// after
storage {
    x in 0xc979570128d5f52725e9a343a7f4992d8ed386d7c8cfd25f1c646c51c2ac6b4b: u64 = 0,
    namespace_1 {
        y in 0x2f055029200cd7fa6751421635c722fcda6ed2261de0f1e0d19d7f257e760589: u64 = 0,
        namespace_2 {
            z in 0x03d2ee7fb8f3f5e1084e86b02d9d742ede96559e44875c6210c7008e2d184694: u64 = 0,
        }
    }
}
```

### Replace `Eq` trait implementations with `PartialEq` and `Eq` implementations - [#6883](https://github.com/FuelLabs/sway/issues/6883)

Partial equivalence feature renames the current `Eq` trait to `PartialEq` and adds a new, empty `Eq` trait with `PartialEq` as a supertrait.

Every existing `Eq` trait implementation needs to be renamed to `PartialEq`, and in addition, an empty `Eq` implementations needs to be added.

```sway
// before
impl Eq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}
```

```sway
// after
impl PartialEq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}

impl Eq for SomeType {}
```

If the original implementation implements Eq for a generic type and in addition has Eq on trait constraints, those Eq trait constraints must be replaced by PartialEq in the new PartialEq impl, and remain Eq in the new, empty, Eq impl.

```sway
// before
impl<A, B> Eq for (A, B)
where
    A: Eq,
    B: Eq,
{
    fn eq(self, other: Self) -> bool {
        self.0 == other.0 && self.1 == other.1
    }
}
```

```sway
// after
impl<A, B> PartialEq for (A, B)
where
    A: PartialEq,
    B: PartialEq,
{
    fn eq(self, other: Self) -> bool {
        self.0 == other.0 && self.1 == other.1
    }
}

impl<A, B> Eq for (A, B)
where
    A: Eq,
    B: Eq,
{}
```

### Implement `TryFrom<Bytes>` for `b256` - [#6994](https://github.com/FuelLabs/sway/issues/6994)

Replace calls to `from(bytes)/bytes.into()` with `try_from(bytes)/bytes.try_into()`.

Calls to `from`:

```sway
// before
let result = b256::from(some_bytes);
```

```sway
// after
let result = b256::try_from(some_bytes).unwrap();
```

Calls to `into`:

```sway
// before
let result = some_bytes.into();
```

```sway
// after
let result = some_bytes.try_into().unwrap();
```

### Merge `core` and `std` libraries - [#7006](https://github.com/FuelLabs/sway/issues/7006)

Currently, we have two standard libraries, `core` and `std`. The distinction between them is rather arbitrary, and we want to merge them into a single library called `std`. All the existing modules in the `core` library will be moved to the `std` library, but their content will not be changed.

```sway
// before
use core::ops::*;

impl core::ops::Eq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}

let _ = core::codec::encode(0u64);
```

```sway
// after
use std::ops::*;

impl std::ops::Eq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}

let _ = std::codec::encode(0u64);
```

## August 16, 2024

[Release v0.63.0](https://github.com/FuelLabs/sway/releases/tag/v0.63.0)

### `#[namespace()]` attribute is no longer supported - [#6279](https://github.com/FuelLabs/sway/pull/6279)

We no longer support the `#[namespace()]` attribute.  If you use it, notably with SRC14, you should migrate to using the `in` keyword if you want backwards compatibility.  If you just care about namespacing, you should use the new namespacing syntax.

Backwards compatibility places `foo` at `sha256("storage_example_namespace_0")`

```sway
// before
#[namespace(example_namespace)]
storage {
    foo: u64 = 0,
}
```

```sway
// after
storage {
    foo in 0x1102bf23d7c2114d6b409df4a1f8f7982eda775e800267be65c1cc2a93cb6c5c: u64 = 0,
}
```

New / recommended method places `foo` at `sha256("storage::example_namespace.foo")`

```sway
// new
storage {
    example_namespace {
        foo: u64 = 0,
    },
}
```

### Configurables are no longer allowed in pattern matching and shadowing - [#6289](https://github.com/FuelLabs/sway/pull/6289)

The code below does not compile any more.

```sway
configurable {
    X: u8 = 10,
}

fn main() {
    let X = 101u8; // ERROR: Variable "X" shadows configurable of the same name.
}
```

```sway
configurable {
    X: u8 = 10,
}

fn main() {
    match var {
        (0, X) => true // ERROR: "X" is a configurable and configurables cannot be matched against.
    }
}
```

### New ABI specification format - [#6254](https://github.com/FuelLabs/sway/pull/6254)

The new ABI specification format is hash based to improve support for indexing.  There were also updates to support the latest VM features.

### Added variable length message support when verifying ed signatures - [#6419](https://github.com/FuelLabs/sway/pull/6419)

`ed_verify` was changed to use `Bytes` for the message instead of `b256` for a message hash.

```sway
// before
pub fn ed_verify(public_key: b256, signature: B512, msg_hash: b256)
```

```sway
// after
pub fn ed_verify(public_key: b256, signature: B512, msg: Bytes)
```

### Some STD functions now return an `Option` instead of reverting - [#6405](https://github.com/FuelLabs/sway/pull/6405), [#6414](https://github.com/FuelLabs/sway/pull/6414), [#6418](https://github.com/FuelLabs/sway/pull/6418)

Some functions in the STD now return an `Option` instead of reverting.  This allows developers to fail gracefully.  More functions will do this in the future.

```sway
// before
let my_predicate_address: Address = predicate_address();
```

```sway
// after
let my_predicate_address: Address = predicate_address().unwrap();
```

### Some STD functions now return types have been updated to match the Fuel Specifications

- `output_count()` now returns a `u16` over a `u64`

Before:

```sway
let output_count: u64 = output_count();
```

After:

```sway
let my_output_count: u16 = output_count();
```

- `tx_maturity` now returns an `Option<u32>` over an `Option<u64>`

Before:

```sway
let my_tx_maturity: u64 = tx_maturity().unwrap()
```

After:

```sway
let my_tx_maturity: u32 = tx_maturity().unwrap()
```

### Some STD functions have been made private. These will no longer be available for developers to use

- `input_pointer()`
- `output_pointer()`
- `tx_witness_pointer()`
- `tx_script_start_pointer()`
- `tx_script_data_start_pointer()`

The following functions now follow this format:

Inputs:

- `input_type()`
- `input_predicate_data()`
- `input_predicate()`
- `input_message_sender()`
- `input_message_recipient()`
- `input_message_data_length()`
- `input_message_data()`
- `input_message_nonce()`

Outputs:

- `output_type()`
- `output_amount()`

Transactions:

- `tx_script_length()`
- `tx_script_data_length()`
- `tx_witness_data_length()`
- `tx_witness_data()`
- `tx_script_data()`
- `tx_script_bytecode()`
- `tx_script_bytecode_hash()`

### Non-breaking Changes

New partial support for slices.

Automated proxy creation and deployment with forc.


---

### File: docs/migrations-and-disclosures/docs/src/migrations/typescript-sdk.md

# TypeScript SDK Migrations Guide

## May 19, 2025

[Release v0.101.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.101.0)

### Enforce `predicateData` when predicate has arguments - [#3886](https://github.com/FuelLabs/fuels-ts/pull/3886)

Predicates that define arguments must now be instantiated with the data property. It is no longer allowed to omit data when the predicate expects input arguments.

For example, for the given predicate:

```rs
predicate;

fn main(pin: u64) -> bool {
    return 999 == pin;
}
```

The following code would compile, even though the predicate expects arguments:

```ts
// before
const predicateNoData = new PredicatePin({ provider }) // ✅ Allowed (incorrectly)

const predicate = new PredicatePin({ provider, data: [100] }) // ✅ Correct
```

TypeScript now enforces that data must be provided:

```ts
// after
const predicateNoData = new PredicatePin({ provider }) // ❌ Error: missing required `data`

const predicate = new PredicatePin({ provider, data: [100] }) // ✅ Correct
```

### Remove `BaseInvocationScope.getTransactionId()` - [#3864](https://github.com/FuelLabs/fuels-ts/pull/3864)

- `getTransactionId()` is no longer available on the `BaseInvocationScope`.

```ts
// before
const contract = new CounterContract(contractId, wallet)

const scope = contract.functions.get_counter()

const txId = await scope.getTransactionId()
```

```ts
// after
const contract = new CounterContract(contractId, wallet)

const request = contract.functions.get_counter().fundWithRequiredCoins()

const chainId = await provider.getChainId()

const txId = await scope.getTransactionId(chainId)
```

## March 17, 2025

[Release v0.100.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.100.0)

### Made `ResourceCache` consider resource owner - [#3697](https://github.com/FuelLabs/fuels-ts/pull/3697)

```ts
//before
provider.cache?.getActiveData();
provider.cache?.isCached(key);
```

```ts
//after
const owner = wallet.address.toB256();

provider.cache?.getActiveData(owner)
provider.cache?.isCached(owner, key);
```

### Upgrade `fuel-core` to `0.41.7` - [#3590](https://github.com/FuelLabs/fuels-ts/pull/3590)

Because of the latest `fuel-core` changes, TS SDK does not throw the following error codes and messages anymore:

#### 1. **NOT_ENOUGH_FUNDS**

```ts
// before
"The account(s) sending the transaction don't have enough funds to cover the transaction."
```

```ts
// after
"Insufficient funds or too many small value coins. Consider combining UTXOs."
```

#### 2. **MAX_COINS_REACHED**

```ts
// before
"The account retrieving coins has exceeded the maximum number of coins per asset. Please consider combining your coins into a single UTXO."
```

```ts
// after
"Insufficient funds or too many small value coins. Consider combining UTXOs."
```

Both error codes were removed in favor of `INSUFFICIENT_FUNDS_OR_MAX_COINS`

## February 4, 2025

[Release v0.99.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.99.0)

### Remove `pageInfo` from `getBalances` GraphQL operations - [#3652](https://github.com/FuelLabs/fuels-ts/pull/3652)

- The `pageInfo` field has been removed from the response of the `provider.operations.getBalances` query.

```ts
// before
const { balances, pageInfo } = await provider.operations.getBalances({
  first: 100,
  filter: { owner: wallet.address.toB256() },
});
```

```ts
// after
const { balances } = await provider.operations.getBalances({
  first: 100,
  filter: { owner: wallet.address.toB256() },
});
```

The `getBalances` method of the Provider class remains unchanged, as it never returned pageInfo:

```ts
// not affected
const { balances } = await provider.getBalances();
```

### Remove `ContractUtils` namespaced export - [#3570](https://github.com/FuelLabs/fuels-ts/pull/3570)

- `ContractUtils` was removed and the underlying functions `getContractRoot()`, `getContractStorageRoot()`, `getContractId()`, `hexlifyWithPrefix()` are now exported directly from `fuels`.

```ts
// before
import { ContractUtils } from 'fuels';
```

```ts
// after
import { getContractRoot, getContractStorageRoot, getContractId, hexlifyWithPrefix } from 'fuels';
```

## January 10, 2025

[Release v0.98.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.98.0)

### Making `provider` initialization `sync` again - [#3514](https://github.com/FuelLabs/fuels-ts/pull/3514)

#### 1. `Provider` Instantiation

- Going from `async` to `sync`

```ts
// before
const provider = await Provider.create(NETWORK_URL);
```

```ts
// after
const provider = new Provider(NETWORK_URL);
```

#### 2. `Provider` methods

- The following methods are now `async`

```ts
// before
provider.getNode();
provider.getChain();
provider.getChainId();
provider.getBaseAssetId();
provider.getGasConfig();
provider.validateTransaction();
```

```ts
// after
await provider.getNode();
await provider.getChain();
await provider.getChainId();
await provider.getBaseAssetId();
await provider.getGasConfig();
await provider.validateTransaction();
```

#### 3. `TransferParams` and `ContractTransferParams`

- Property `assetId` is now required by [`TransferParams`](https://github.com/FuelLabs/fuels-ts/blob/5d96eb6748e4210029bcbca0490172de81487e05/packages/account/src/account.ts#L56-L60) and [`ContractTransferParams`](https://github.com/FuelLabs/fuels-ts/blob/5d96eb6748e4210029bcbca0490172de81487e05/packages/account/src/account.ts#L62-L66)

```diff
export type TransferParams = {
  destination: string | AbstractAddress;
  amount: BigNumberish;
-  assetId?: BytesLike;
+  assetId: BytesLike;
};

export type ContractTransferParams = {
  contractId: string | AbstractAddress;
  amount: BigNumberish;
-  assetId?: BytesLike;
+  assetId: BytesLike;
};
```

#### 4. Transaction Response

- The constructor now requires a `chainId`

```ts
// before
new TransactionResponse('0x..', provider);
```

```ts
// after
new TransactionResponse('0x..', provider, chainId);
```

### `autoCost` for transaction estimation and funding - [#3539](https://github.com/FuelLabs/fuels-ts/pull/3539)

  To be brought inline with `autoCost`, funding a contract and script call has been migrated from `fundWithRequiredCoins` to `autoCost`:

```ts
// before
const request: ScriptTransactionRequest = contract.functions.add(1).fundWithRequiredCoins();
```

```ts
// after
const request: ScriptTransactionRequest = contract.functions.add(1).autoCost();
```

### Remove redundant gas price call for tx summary - [#3559](https://github.com/FuelLabs/fuels-ts/pull/3559)

- `calculateTXFeeForSummary` and subsequently the `CalculateTXFeeForSummaryParams` no longer accept a `totalFee` property. If you have the `totalFee`, then there is no need to call the `calculateTxFeeForSummary()` function.

```ts
// before
const totalFee = bn(..):
calculateTXFeeForSummary({ ..., totalFee } as CalculateTXFeeForSummaryParams);
```

```ts
// after
calculateTXFeeForSummary({ ... } as CalculateTXFeeForSummaryParams);
```

### Prevent implicit asset burn - [#3540](https://github.com/FuelLabs/fuels-ts/pull/3540)

  ```ts
// before
const transactionRequest = new ScriptTransactionRequest();
transactionRequest.inputs.push({ ... });

// since outputs weren't added, assets would be burned
await sender.sendTransaction(transactionRequest);
```

```ts
// after
const transactionRequest = new ScriptTransactionRequest();
transactionRequest.inputs.push({ ... });

// now, an error will be thrown unless `enableAssetBurn`is true,
// in which case, assets can still be burned
await sender.sendTransaction(transactionRequest, {
  enableAssetBurn: true,
});
```

### Remove unused operations - [#3553](https://github.com/FuelLabs/fuels-ts/pull/3553)

  The following operations have been removed from the `OperationName` enum, as they were never used to assemble operations:

- `OperationName.mint`
- `OperationName.predicatecall`
- `OperationName.script`
- `OperationName.sent`

### Remove receipts deprecated properties - [#3552](https://github.com/FuelLabs/fuels-ts/pull/3552)

  All receipts deprecated properties were removed:

```ts
// before
ReceiptCall.from

ReceiptLog.val0
ReceiptLog.val1
ReceiptLog.val2
ReceiptLog.val3

ReceiptLogData.val0
ReceiptLogData.val1

ReceiptTransfer.from

ReceiptTransferOut.from
```

```ts
// after
ReceiptCall.id

ReceiptLog.ra
ReceiptLog.rb
ReceiptLog.rc
ReceiptLog.rd

ReceiptLogData.ra
ReceiptLogData.rb

ReceiptTransfer.id

ReceiptTransferOut.id
```

### Remove receipt coders - [#3551](https://github.com/FuelLabs/fuels-ts/pull/3551)

  All previously deprecated receipt coders have been removed. These classes were barely used aside from a few internal helpers, which were converted to utility functions.

```ts
// before
const messageId = ReceiptMessageOutCoder.getMessageId({
  sender,
  recipient,
  nonce,
  amount,
  data,
});

const assetId = ReceiptMintCoder.getAssetId(contractId, subId);

const assetId = ReceiptBurnCoder.getAssetId(contractId, subId);
```

```ts
// after
import { getMessageId, getAssetId } from 'fuels'

const messageId = getMessageId({
  sender,
  recipient,
  nonce,
  amount,
  data,
});

const assetId = getAssetId(contractId, subId);
```

### Remove deprecated `submitAndAwait` operation - [#3548](https://github.com/FuelLabs/fuels-ts/pull/3548)

- `submitAndAwait` operation was removed

After being deprecated since #3101, we have removed this operation altogether. Please use the `submitAndAwaitStatus` method instead which gives the same results as `submitAndAwait`. If you are interested in the deprecation/removal reasons, please refer to https://github.com/FuelLabs/fuel-core/issues/2108.

```ts
// before
const response = await provider.operations.submitAndAwait(txRequest);
```

```ts
// after
const response = await provider.operations.submitAndAwaitStatus(txRequest);
```

### Remove Bech32 address - [#3493](https://github.com/FuelLabs/fuels-ts/pull/3493)

- We no longer support Bech32 addresses

```ts
// before
import { Address, Bech32Address } from "fuels";

const bech32Address: Bech32Address = "fuel1234";
const address = new Address(bech32Address);
```

```ts
// after
import { Address, B256Address } from "fuels";

const b256Address: B256Address = "0x1234";
const address = new Address(b256Address);
```

- Removed `INVALID_BECH32_ADDRESS` error code.

- Removed associated Bech32 helper functions.
  - `normalizeBech32`
  - `isBech32`
  - `toB256`
  - `getBytesFromBech32`
  - `toBech32`
  - `clearFirst12BytesFromB256`

### Redistributed the `@fuel-ts/interfaces` package - [#3492](https://github.com/FuelLabs/fuels-ts/pull/3492)

- Removed the `AbstractAddress` class; use the `Address` class instead.

```ts
// before
import { AbstractAddress } from 'fuels';
```

```ts
// after
import { Address } from 'fuels';
```

- Removed the `@fuel-ts/interfaces` package; use the `fuels` package instead.

```ts
// before
import { BytesLike } from '@fuel-ts/interfaces'
```

```ts
// after
import { BytesLike } from 'fuels'
```

### Optimizing frontend apps - [#3573](https://github.com/FuelLabs/fuels-ts/pull/3573)

- `ScriptTransactionRequest.autoCost()` has been renamed to `ScriptTransactionRequest.estimateAndFund()`, initially introduced by #3535

```ts
// before
await request.autoCost(wallet);
```

```ts
// after
await request.estimateAndFund(wallet);
```

- `BaseInvocationScope.autoCost()` has been renamed back to `BaseInvocationScope.fundWithRequiredCoins()`, initially introduced by #3535

```ts
// before
const request = await contract.functions.increment().autoCost();
```

```ts
// after
const request = await contract.functions.increment().fundWithRequiredCoins();
```

## November 15, 2024

[Release v0.97.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.97.0)

### `onDeploy` fuels config supports all Sway program types - [#3383](https://github.com/FuelLabs/fuels-ts/pull/3383)

- Changed the outputted data from the `onDeploy` callback method for the `fuels.config.ts`. Instead of just emitting the deployed contracts (as an array), it will now emit an object with `contracts`, `predicates` and `scripts`.

```ts
// Before (fuels.config.ts)
import { createConfig, FuelsConfig, DeployedContract } from 'fuels';

export default createConfig({
  output: 'dir/out',
  onDeploy: (config: FuelsConfig, deployedContracts: DeployedContract[]) => {
    console.log('contracts', deployedContracts);
  }
});
```

```ts
// After (fuels.config.ts)
import { createConfig, FuelsConfig, DeployedData } from 'fuels';

export default createConfig({
  output: 'dir/out',
  onDeploy: (config: FuelsConfig, deployed: DeployedData[]) => {
    console.log('contracts', deployed.contracts);
    console.log('predicates', deployed.predicates);
    console.log('scripts', deployed.scripts);
  }
});
```

### Remove unnecessary nonce from message gql queries - [#3298](https://github.com/FuelLabs/fuels-ts/pull/3298)

- Removed the `nonce` property from `Provider.operations.getMessageByNonce()`. This can still be retrieved by `Provider.getMessageByNonce()`.

### Refactor predicate and script deployment - [#3389](https://github.com/FuelLabs/fuels-ts/pull/3389)

  `ContractFactory.deployAsBlobTxForScript` has been removed in favor of `Predicate.deploy` and `Script.deploy`:

```ts
// before
const factory = new ContractFactory(scriptBytecode, scriptAbi, wallet);
const { waitForResult } = await factory.deployAsBlobTxForScript();
const { loaderBytecode, configurableOffsetDiff } = await waitForResult();

// after
const script = new Script(scriptBytecode, scriptAbi, wallet);
const { blobId, waitForResult } = await script.deploy(deployerWallet);
const loaderScript = await waitForResult();

const predicate = new Predicate({ bytecode, abi, provider });
const { blobId, waitForResult } = await predicate.deploy(deployerWallet);
const loaderPredicate = await waitForResult();
```

### Mandate `abi` in `Predicate` constructor - [#3387](https://github.com/FuelLabs/fuels-ts/pull/3387)

- Instantiating a `Predicate` now requires providing its `abi`. If you want to use the `Predicate` as an `Account`, please instantiate it via the `Account` class

```ts
// before
const predicate = new Predicate({ provider, bytecode }); // worked even though abi is missing

// after
const predicate = new Predicate({ abi, provider, bytecode }); // abi is now mandatory

// predicate as account
const account = new Account(predicateAddress, provider);
```

### Optimize `getTransactions` query - [#3336](https://github.com/FuelLabs/fuels-ts/pull/3336)

- The response format for `Provider.getTransactions` remains the same. However, the response format for the query `Provider.operations.getTransactions` has been modified.

```graphql
// before
query getTransactions {
  id
  rawPayload
  status {
    ...
  }
}
```

```graphql
// after
query getTransactions {
  rawPayload
}
```

### Limit TX pagination number for `getTransactionsSummaries` - [#3400](https://github.com/FuelLabs/fuels-ts/pull/3400)

- The pagination number for `getTransactionsSummaries` is limited to `60` now

```ts
// before
const { transactions } = await getTransactionsSummaries({
  provider,
  filters: {
    owner: account.address.toB256(),
    first: 200,
  },
});
```

```ts
// after
const { transactions } = await getTransactionsSummaries({
  provider,
  filters: {
    owner: account.address.toB256(),
    first: 60, // Limit is 60 now. A higher value will result in an error
  },
});
```

### Remove `blockId` in transaction list responses - [#3379](https://github.com/FuelLabs/fuels-ts/pull/3379)

- The `blockId` property has been removed from the following GraphQL queries used to list past transactions:

```ts
const { transactions } = await getTransactionsSummaries({ ... });

const { transactionsByOwner } = await provider.operations.getTransactionsByOwner({ ... });
```

If the `blockId` is required for a given transaction, it needs to be queried separately with `getTransactionSummary` helper:

```ts
import { getTransactionSummary } from 'fuels';

const transaction = await getTransactionSummary({
  id,
  provider,
});
```

*Note: The `blockId` is still available in the result for a submitted transaction.*

### Optimize coin gql queries - [#3301](https://github.com/FuelLabs/fuels-ts/pull/3301)

- The `Provider.operations.getCoins()` and  `Provider.operations.getCoinsToSpend` function no longer return the owner. These methods shouldn't be called directly but are used internally to formulate responses from the SDK.

- Removed the property `owner` from the `Provider.operations.getCoinsToSpend()` function. Suggest to use the owner from the input parameters.

## October 13, 2024

[Release v0.96.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.96.0)

### Checksum method to remove `0x` before hashing - [#3313](https://github.com/FuelLabs/fuels-ts/pull/3313)

  We fixed the checksum utilities:

- `Address.toChecksum()`
- `Address.isChecksumValid()`

Now, we correctly remove the leading `0x` before hashing the address.

Because of this, previous values were invalid, and the update is required.

## October 10, 2024

[Release v0.95.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.95.0)

### Bump transaction pagination limit to 60 - [#3306](https://github.com/FuelLabs/fuels-ts/pull/3306)

- A limit was added of 60 transactions to the `provider.getTransactions()` method.

### Made Address `toString` and `valueOf` returns checksum - [#3310](https://github.com/FuelLabs/fuels-ts/pull/3310)

  The return of both `Address.toString()` and `Address.valueOf` was modified to return the address checksum instead of the Bech32 string

```ts
// before
const address = new Address('fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e');

address.toString()
// fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e

address.valueOf()
// fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e
```

```ts
// after
const address = new Address('fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e');

address.toString()
// 0xEf86aFa9696Cf0dc6385e2C407A6e159A1103cEfB7E2Ae0636FB33d3cb2A9E4A

address.valueOf()
// 0xEf86aFa9696Cf0dc6385e2C407A6e159A1103cEfB7E2Ae0636FB33d3cb2A9E4A
```

### Slim down `chainInfoFragment` and `GasCostsFragment` - [#3286](https://github.com/FuelLabs/fuels-ts/pull/3286)

- `latestBlock` is no longer part of the `ChainInfo` return of `provider.getChain()`. You can fetch it via `provider.getBlock('latest')`.
- `ChainInfo['consensusParameters']['gasCosts']` has been slimmed down to only contain data necessary for the operation of the SDK. Up until now, the SDK was fetching more than it needed. If this change affects you, you will have to create a custom graphql query for `gasCosts` for the additional data you need.

### Optimize balance queries - [#3296](https://github.com/FuelLabs/fuels-ts/pull/3296)

- Removed the `owner` and `assetId` properties from the response of `Provider.operations.getBalance()`. These properties are also required arguments to execute the function so are redundant in the response. Should you require these values, you should take them from the values that you passed to the function.
- Removed the `owner` property from the response of `Provider.operations.getBalances()`. This property is a required argument to execute the function so is redundant in the response. Should you require this value, you should take it from the value that you passed to the function.

## August 30, 2024

[Release v0.94.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.94.0)

### Consider message on resources cache - [#2872](https://github.com/FuelLabs/fuels-ts/pull/2872)

  The provider option flag `cacheUtxo` was renamed to `resourceCacheTTL`

```ts
// before
const provider = await Provider.create(FUEL_NETWORK_URL, {
  cacheUtxo: 5000,
});


using launched = await launchTestNode({
  providerOptions: {
    cacheUtxo: 5000,
  },
});
```

```ts
// after
const provider = await Provider.create(FUEL_NETWORK_URL, {
  resourceCacheTTL: 5000,
});

using launched = await launchTestNode({
  providerOptions: {
    resourceCacheTTL: 5000,
  },
});
```

### Prettify `typegen` api - [#2824](https://github.com/FuelLabs/fuels-ts/pull/2824)

### `Predicate` class

- `Predicate` class constructor parameters renamed: `inputData` > `data`

```ts
// before
import { Predicate } from 'fuels';

const predicate = new Predicate({
  ...unchangedParameters,
  inputData,
});
```

```ts
// after
import { Predicate } from 'fuels';

const predicate = new Predicate({
  ...unchangedParameters,
  data,
});
```

- Typegen extended/generated `Predicate` now accepts a single parameter for initialization

```ts
// before
import { TestPredicateAbi__factory } from './typegend';

TestPredicateAbi__factory.createInstance(provider, data, configurableConstants);
```

```ts
// after
import { TestPredicate } from './typegen';

new TestPredicate({
  provider,
  data,
  configurableConstants
});
```

### `launchTestNode` utility

- Renamed `contractsConfigs[].deployer` to  `contractsConfigs[].factory`
- Removed `contractsConfigs[].bytecode` and `.hex.ts` file

The bytecode is now saved within the factory class, so you don't have to deal with it.

```ts
// before
import { TokenAbi__factory } from './typegend';
import TokenAbiHex from './typegend/contracts/TokenAbi.hex';

using launched = await launchTestNode({
  contractsConfigs: [{
    deployer: TokenAbi__factory,
    bytecode: TokenAbiHex
  }],
});
```

```ts
// after
import { TokenFactory } from './typegend';

using launched = await launchTestNode({
  contractsConfigs: [{
    factory: TokenFactory,
  }],
})
```

### Renamed method `deployContract` to `deploy`

Removed the redundant suffix on the `ContractFactory` class method name.

```ts
// before
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(wallet);

factory.deployContract();
```

```ts
// after
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(wallet);

factory.deploy();
```

### Typegen `Contract` template

- Removed `Abi__factory` suffix from class names
- The file `<name>.hex` was removed (access it via `<Name>.bytecode`)
- The files `<name>__factory.ts` and `<name>.d.dts` were merged into `<name>.ts`
- The class `<Name>` and the interface `<Name>Abi` are now just `<Name>`
- Method `<Name>Factory.deployContract()` renamed to `<Name>Factory.deploy()`
- You may need to remove the previously generated `<typegenDir>/contracts/factories` directory

```ts
// before
import { TestContractAbi, TestContract__factory } from './typegen'
import testContractBytecode from './typegen/contracts/TestContract.hex'

const instance = await TestContract__factory.connect(id, wallet);

const deploy = await TestContract__factory.deployContract(testContractBytecode, wallet);
const { contract } = await deploy.waitForResult();
```

```ts
// after
import { TestContract, TestContractFactory } from './typegen'

const instance = new TestContract(id, wallet);

const deploy = await TestContractFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();
```

### Typegen `Predicate` template

- Removed `Abi__factory` suffix from class names
- Started accepting a single parameter object in constructor
- You may need to remove the previously generated `<typegenDir>/predicates/factories` directory

```ts
// before
import { TestPredicateAbi__factory } from './typegen'

const predicate = TestPredicateAbi__factory.createInstance(provider);
```

```ts
// after
import { TestPredicate } from './typegen'

const predicate = new TestPredicate({ provider });
```

### Typegen `Script` template

- Removed `Abi__factory` suffix from class names
- You may need to remove the previously generated `<typegenDir>/scripts/factories` directory

```ts
// before
import { TestPredicateAbi__factory } from './typegen'

const script = TestScriptAbi__factory.createInstance(wallet);
```

```ts
// after
import { TestPredicate } from './typegen'

const script = new TestScript(wallet);
```

### Non-blocking blob deployment - [#2929](https://github.com/FuelLabs/fuels-ts/pull/2929)

The transaction ID from a contract deployment is now returned as a promise.

```ts
// before
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(bytecode, abi, wallet);
const { waitForResult, contractId, transactionId } = await factory.deploy();
console.log(transactionId); // 0x123....
```

```ts
// after
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(bytecode, abi, wallet);
const { waitForResult, contractId, waitForTransactionId } = await factory.deploy();
const transactionId = await waitForTransactionId();
console.log(transactionId); // 0x123....
```

### Improve `()` and `Option<T>` type handling - [#2777](https://github.com/FuelLabs/fuels-ts/pull/2777)

- `()` and `Option<T>` Sway types are now either required or optional, dependent on where the argument appears in the function arguments.

Given these Sway functions:

```sway
fn type_then_void_then_type(x: u8, y: (), z: u8) -> ()
fn type_then_void_then_void(x: u8, y: (), z: ()) -> ()

fn type_then_option_then_type(x: u8, y: Option<u8>, z: u8) -> ()
fn type_then_option_then_option(x: u8, y: Option<u8>, z: Option<u8>) -> ()
```

This is what changes:

```ts
// before
contract.functions.type_then_void_then_type(42, 43)
contract.functions.type_then_void_then_void(42) // Unchanged

contract.functions.type_then_option_then_type(42, undefined, 43)
contract.functions.type_then_option_then_option(42, undefined, undefined)
```

```ts
// after
contract.functions.type_then_void_then_type(42, undefined, 43)
contract.functions.type_then_void_then_void(42) // Unchanged

contract.functions.type_then_option_then_type(42, undefined, 43)
contract.functions.type_then_option_then_option(42)
```

### `fuel-core@0.32.1` and large contract deployments - [#2827](https://github.com/FuelLabs/fuels-ts/pull/2827)

  `MAX_CONTRACT_SIZE` is no longer exported, it should now be fetched from the chain.

```ts
// before
import { MAX_CONTRACT_SIZE } from 'fuels';
```

```ts
// after
import { Provider, FUEL_NETWORK_URL } from 'fuels';

const provider = await Provider.create(FUEL_NETWORK_URL);
const { consensusParameters } = provider.getChain();
const maxContractSize = consensusParameters.contractParameters.contractMaxSize.toNumber();
```

### Deprecate `FUEL_NETWORK_URL` and `LOCAL_NETWORK_URL`- [#2915](https://github.com/FuelLabs/fuels-ts/pull/2915)

  Removed `FUEL_NETWORK_URL` constant.

```ts
// before
import { FUEL_NETWORK_URL } from 'fuels';

const provider = await Provider.create(FUEL_NETWORK_URL);
```

```ts
// after
const provider = await Provider.create('https://127.0.0.1:4000/v1/graphql');
```

Removed `LOCAL_NETWORK_URL` constant.

```ts
// before
import { LOCAL_NETWORK_URL } from 'fuels';

const provider = await Provider.create(LOCAL_NETWORK_URL);
```

```ts
// after
const provider = await Provider.create('https://127.0.0.1:4000/v1/graphql');
```

### Integrate `launchTestNode` in remaining packages - [#2811](https://github.com/FuelLabs/fuels-ts/pull/2811)

  Removed `generateTestWallet` and `seedTestWallet` utilities.

```ts
// before
import { bn } from "@fuel-ts/math";
import {
  seedTestWallet,
  generateTestWallet,
} from "@fuel-ts/account/test-utils";

const provider = await Provider.create("http://127.0.0.1:4000/v1/graphql");

// seeding
const walletA = Wallet.fromPrivateKey("0x...", provider);
const baseAssetId = provider.getBaseAssetId();
seedTestWallet(wallet, [{ assetId: baseAssetId, amount: bn(100_000) }]);

// generating
const walletB = await generateTestWallet(provider, [[1_000, baseAssetId]]);
```

```ts
// after
import { launchTestNode } from 'fuels/test-utils';

// create two wallets seeded with 100_000 units of the base asset
using launched = await launchTestNode({
  walletsConfig: {
    count: 2,
    amountPerCoin: 100_000,
  },
});

const {
  wallets: [walletA, walletB]
} = launched;

const balance = await walletA.getBalance() // 100_000
```

Removed `launchNodeAndGetWallets` utility.

```ts
// before
import { launchNodeAndGetWallets } from 'fuels/test-utils';

const { provider, wallets } = await launchNodeAndGetWallets();
```

```ts
// after
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode();

const { provider, wallets } = launched;
```

### Renamed `AssetId` to `TestAssetId`- [#2905](https://github.com/FuelLabs/fuels-ts/pull/2905)

  Renamed testing class `AssetId` to `TestAssetId`.

```ts
// before
import { AssetId } from 'fuels/test-utils';

const [assetA] = AssetId.random();
```

```ts
// after
import { TestAssetId } from 'fuels/test-utils';

const [assetA] = TestAssetId.random();
```

### Adding abi transpiler - [#2856](https://github.com/FuelLabs/fuels-ts/pull/2856)

New ABI spec

The SDK now adheres to the new specs introduced via:

- https://github.com/FuelLabs/fuel-specs/pull/596
- https://github.com/FuelLabs/fuel-specs/pull/599

Check these out to understand all its changes.

The class `AbiCoder` is no longer exported, and the way to do encoding and decoding of specific types is now via the `Interface.encodeType` and `Interface.decodeType` methods:

```ts
// before
const abi = yourAbi;
const functionArg = abi.functions.inputs[0];

const encoded = AbiCoder.encode(abi, functionArg, valueToEncode);
const decoded = AbiCoder.decode(abi, functionArg, valueToDecode, 0);
```

```ts
// after
import { Interface } from 'fuels';

const abi = yourAbi;
const functionArg = abi.functions.inputs[0];

const abiInterface = new Interface(abi);

const encoded = abiInterface.encodeType(functionArg.concreteTypeId, valueToEncode);
const decoded = abiInterface.decodeType(functionArg.concreteTypeId, valueToDecode);
```

Previously, you could get a type from the ABI via the `Interface.findTypeById`. This method has been removed after introducing the new abi specification because the concept of a *type* has been split into concrete types and metadata types. If you want a specific type, you can get it directly from the ABI.

```ts
// before
const abiInterface = new Interface(abi);

// internally this method searched the abi types:
// abi.types.find(t => t.typeId === id);
const type = abiInterface.findTypeById(id);
```

```ts
// after
import { Interface } from 'fuels';

// search the types on the abi directly
const concreteType = abi.concreteTypes.find(ct => ct.concreteTypeId === id);
const metadataType = abiInterface.jsonAbi.metadataTypes.find(mt => mt.metadataTypeId === id);
```

The `JsonAbiArgument` type isn't part of the new ABI spec *([#596](https://github.com/FuelLabs/fuel-specs/pull/596), [#599](https://github.com/FuelLabs/fuel-specs/pull/599))* as such so we stopped exporting it. Its closest equivalent now would be a concrete type because it fully defines a type.

```ts
// before
const arg: JsonAbiArgument = {...};
```

```ts
// after
import { Interface } from 'fuels';

type ConcreteType = JsonAbi["concreteTypes"][number]
const arg: ConcreteType = {...};
```

### Read malleable fields from transaction status on subscription - [#2962](https://github.com/FuelLabs/fuels-ts/pull/2962)

Removed `TransactionResult.gqlTransaction`. You can use the `TransactionResult.transaction` field instead, which has all the data that `TransactionResult.gqlTransaction` has but already decoded.

```ts
// before
const { gqlTransaction } = await new TransactionResponse('your-tx-id').waitForResult();
```

```ts
// after
const { transaction } = await new TransactionResponse('your-tx-id').waitForResult();
```

### Fix assembly process for account transfer operation - [#2963](https://github.com/FuelLabs/fuels-ts/pull/2963)

The `getTransferOperations` helper function now requires an additional `baseAssetId` parameter.

```ts
// before
const transferOperations = getTransferOperations({ inputs, outputs, receipts })
```

```ts
// after
const transferOperations = getTransferOperations({ inputs, outputs, receipts, baseAssetId })
```

### Wrap subscriptions in promise - [#2964](https://github.com/FuelLabs/fuels-ts/pull/2964)

```ts
// before
const subscription = provider.operations.statusChange({ transactionId });
for await (const response of subscription) { ... }
```

```ts
// after
const subscription = await provider.operations.statusChange({ transactionId });
for await (const response of subscription) { ... }
```

## July 30, 2024

[Release v0.93.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.93.0)

### Deploy contract validation - [#2796](https://github.com/FuelLabs/fuels-ts/pull/2796)

`ErrorCode.INVALID_TRANSACTION_TYPE` was migrated to `ErrorCode.UNSUPPORTED_TRANSACTION_TYPE`.

```ts
// before
const code = ErrorCode.INVALID_TRANSACTION_TYPE;
```

```ts
// after
const code = ErrorCode.UNSUPPORTED_TRANSACTION_TYPE;
```

### Remove `awaitExecution` functionality - [#2820](https://github.com/FuelLabs/fuels-ts/pull/2820)

  It is no longer possible to submit transactions using the `awaitExecution` flag and wait for the transaction to be processed at submission:

```ts
// before
const response = await account.sendTransaction(transactionRequest, { awaitExecution: true });
```

```ts
// after
const submit = await account.sendTransaction(transactionRequest);

const response = await submit.waitForResult();
```

### Refactored the `getTransactionCost` method - [#2643](https://github.com/FuelLabs/fuels-ts/pull/2643)

  Refactored functionality for `Provider.getTransactionCost` to `Account.getTransactionCost` **and** changed estimation parameter from `quantitiesToContract` to `quantities`.

```ts
// before
const provider = Provider.create(...);
const account = Wallet.generate({ ... }) || new Predicate(...);
const quantities: Array<CoinQuantityLike> = [
  { amount: 1000, assetId: provider.getBaseAssetId() }
];

const cost = provider.getTransactionCost(txRequest, {
  resourceOwner: account,
  quantitiesToContract: quantities,
})
```

```ts
// after
const provider = Provider.create(...);
const account = Wallet.generate({ ... }) || new Predicate(...);
const quantities: Array<CoinQuantityLike> = [
  { amount: 1000, assetId: provider.getBaseAssetId() }
];

const cost = account.getTransactionCost(txRequest, { quantities });
```

## July 11, 2024

Release [v0.92.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.92.0)

### Implement non-blocking contract call - [#2692](https://github.com/FuelLabs/fuels-ts/pull/2692)

  The `call` method in the `BaseInvocationScope` class no longer waits for transaction execution, making it non-blocking. This change affects how transaction responses are handled.

```ts
// before
const { logs, value, transactionResult } = await contract.functions.xyz().call()
```

```ts
// after
const { transactionId, waitForResult } = await contract.functions.xyz().call();

const { logs, value, transactionResult } = await waitForResult();
```

### Made `deployContract` a non-blocking call - [#2597](https://github.com/FuelLabs/fuels-ts/pull/2597)

  The `deployContract` method no longer returns the contract instance directly. Instead, it returns an object containing the `transactionId` , the `contractId`, and a `waitForResult` function.

```ts
// before
const factory = new ContractFactory(contractByteCode, contractAbi, wallet);

const contract = await factory.deployContract();

const { value } = await contract.functions.xyz().call();

// after
const factory = new ContractFactory(contractByteCode, contractAbi, wallet);

const { waitForResult, transactionId, contractId } = await factory.deployContract();

const { contract, transactionResult } = await waitForResult();

const { value } = await contract.functions.xyz().call();
```

### Implement pagination for `Account` methods - [#2408](https://github.com/FuelLabs/fuels-ts/pull/2408)

```ts
// before
const coins = await myWallet.getCoins(baseAssetId);
const messages = await myWallet.getMessages();
const balances = await myWallet.getBalances();
const blocks = await provider.getBlocks();

// after
const { coins, pageInfo } = await myWallet.getCoins(baseAssetId);
const { messages, pageInfo } = await myWallet.getMessages();
const { balances } = await myWallet.getBalances();
const { blocks, pageInfo } = await provider.getBlocks();

/*
  The `pageInfo` object contains cursor pagination information one
  can use to fetch subsequent pages selectively and on demand.
*/
```

### `launchNode.cleanup` not killing node in last test of test group - [#2718](https://github.com/FuelLabs/fuels-ts/pull/2718)

  The `killNode` and `KillNodeParams` functionality has been internalized and the method and interface have been deleted so they're no longer exported.  It's marked as a breaking change for pedantic reasons and there shouldn't really be any affected users given that they kill nodes via `cleanup` which is unchanged, so no migration notes are necessary.

### Remove `InvocationResult` from `program` package - [#2652](https://github.com/FuelLabs/fuels-ts/pull/2652)

  The classes `FunctionInvocationResult`, `InvocationCallResult`, and `InvocationResult` have been removed. This change will not affect most users as the response for a contract call or script call remains the same; only the type name has changed.

```ts
// before
const callResult: FunctionInvocationResult = await contract.functions.xyz().call()

const dryRunResult: InvocationCallResult = await contract.functions.xyz().get()
const dryRunResult: InvocationCallResult = await contract.functions.xyz().dryRun()
const dryRunResult: InvocationCallResult = await contract.functions.xyz().simulate()


// after
const callResult: FunctionResult = await contract.functions.xyz().call()

const dryRunResult: DryRunResult = await contract.functions.xyz().get()
const dryRunResult: DryRunResult = await contract.functions.xyz().dryRun()
const dryRunResult: DryRunResult = await contract.functions.xyz().simulate()
```


---

### File: docs/nightly/ai/docs/src/index.md

# AI

This section contains guides and resources for using AI to develop on Fuel.


---

### File: docs/nightly/fuel-book/docs/src/conclusion/index.md

# Conclusion

Thank you for exploring the Fuel Book. We hope it has provided you with a deeper understanding of the motivations, philosophies, and technical innovations that drive our work. Fuel represents more than just a high-performance blockchain solution—it’s a vision for a decentralized future built on speed, security, and scalability.

As you continue your journey with Fuel, remember that our community thrives on collaboration and shared learning. Whether you're a developer, researcher, or blockchain enthusiast, we invite you to engage with our growing ecosystem, contribute your ideas, and help shape the future of decentralized technology.


---

### File: docs/nightly/fuel-book/docs/src/fuels-future/data-streaming.md

# Data Streaming

While many projects have focused energy on improving the performance of writing data to blockchains, less attention has been paid to optimizing how to read data from a blockchain. In the future, Fuel will radically restructure how data gets propagated from block-producers out to the various end-users of a network.

Current blockchain applications read data from a network by repeatedly “pinging” an RPC node, asking that node to provide the current state of the network and then checking for updates locally. This method of “polling” for new data is extremely inefficient for all parties, placing computational and network burdens on both the client and server. Furthermore, the “pull” nature of this system means that there will always be some extra latency introduced into the transaction. And in the world of finance, time is money.

Fuel aims to flip the data model on its head, creating a push/subscription model of disseminating data across a network. Fuel will enable block-producers to stream every phase of the transaction supply chain from their own servers, out through a network of lightweight relayers, on to end users. This allows users to have fast access to blockchain data without requiring unnecessary “polling”, and allows financial actors to have the fastest access to the financial information they care about.


---

### File: docs/nightly/fuel-book/docs/src/fuels-future/decentralized-block-building.md

# Decentralized Block Building

Fully decentralizing block production is the final step towards creating rollups that fully embody the important values of decentralized blockchains.

In addition to simply ensuring that blockchains remain permissionless and censorship-resistant, decentralized block-building will also expand the surface area for how applications can be developed.


---

### File: docs/nightly/fuel-book/docs/src/fuels-future/index.md

# Chapter 3 - Fuel's Future

Fuel Ignition's launch establishes the groundwork for a network of high-performance blockchains and diverse infrastructure, supporting numerous decentralized applications.

Post-mainnet, Fuel will introduce a range of advanced features to elevate blockchain technology.

- [3.1 - A Network of Interconnected L2s & L3s](./network-of-interconnection.md)
- [3.2 - Decentralized Block Building](./decentralized-block-building.md)
- [3.3 - SNAP Fast Finality Gadget](./snap-fast-finality-gadget.md)
- [3.4 - State Rehydration](./state-rehydration.md)
- [3.5 - Data Streaming](./data-streaming.md)


---

### File: docs/nightly/fuel-book/docs/src/fuels-future/network-of-interconnection.md

# A Network of Interconnected L2s & L3s

Fuel Ignition is the beach-head network, introducing the Fuel technology to the world. However, as the technology matures and the ecosystem grows, this technology will be used to power a growing ecosystem of modular rollups. Developers choose to launch independent chains either to customize the stack, to capture economic value, or simply to build an independent ecosystem for community building.

Fuel’s technology already enables the fastest execution and lowest fees, and future development will ensure these chains can easily interoperate with other chains throughout the ecosystem. Fuel’s light-clients, shared sequencer, combined with the SNAP finality gadget (described below) allow these chains to reduce their friction.


---

### File: docs/nightly/fuel-book/docs/src/fuels-future/snap-fast-finality-gadget.md

# SNAP Fast Finality Gadget

One of the most well-known limitations of rollups is the long periods of time needed to send messages from the layer-2 back up to the layer-1 chain. Users of optimistic rollups such as Arbitrum and Optimism face a notable drawback: a week-long wait period for asset withdrawals from the network.While ZK-rollups do offer reduced settlement times, the economics of proving mean that proofs (and therefore withdrawals) can still take up to 24 hours to process.

Fuel has proposed a theoretical new mechanism for substantially reducing the finality time of optimistic rollups. While the full details are [outlined in a post on ETHResearch](https://ethresear.ch/t/why-wait-a-week-fast-finality-optimistic-rollups/18868), the mechanism can be understood at a high level as using a bonded committee of operators to attest to both the validity of the chain, as well as the state of Ethereum not being censored.


---

### File: docs/nightly/fuel-book/docs/src/fuels-future/state-rehydration.md

# State Rehydration

Typical blockchain applications treat the chain’s state as a large, public, distributed database. These applications write data to the chain in a similar manner to how a Web2 application would write to a cloud-hosted database.
However, this imposes a large burden on the network, which must maintain this data on all nodes. The immutable nature of blockchains means this data is generally stored forever.

Fuel aims to address this issue using a technique known as “state rehydration”. This technique uses the blockchain as a system for maintaining consensus over state commitments, as opposed to a system for syncing a large database.

Specifically, this technique takes advantage of the fact that “calldata” and hashing are relatively inexpensive compared to state storage. State rehydration means that a transaction includes all the state data needed for an action, and this state will be validated against a single on-chain hash as a state commitment. In turn, an application will update the state by hashing the new state values, storing this “dehydrated” commitment in state, and emitting the full state in a log so it can be made available off-chain.

Many current parts of Fuel are considered “state rehydration”, such as predicates which require users to provide the account’s bytecode. Furthermore, some applications have taken state rehydration a step further, using UTXOs and predicates to provide further state reductions.

However, Fuel’s roadmap aims to bring state-rehydration to a level where it can power any arbitrary blockchain application. This requires a full integration between users, block-builders, and off-chain indexers, allowing various parties to pay to reconstruct the state in a completed block. This technique will leverage Fuel’s planned decentralized block-building mechanisms.


---

### File: docs/nightly/fuel-book/docs/src/glossary/index.md

# Glossary

**Contract:** Primitives allowing for building stateful applications on Fuel, facilitates complex stateful applications like AMMs, Vaults, etc.

**Context:** Provides policies that determine what features can some running FuelVM bytecode use, for example the ability to call smart contracts, use persistent storage, etc.

**Cryptography:** The practice of securing information and communications through mathematical techniques, ensuring data confidentiality, integrity, and authenticity in blockchain systems.

**Ephemeral scripting:** Scripts or code that are temporary and designed for short-term, single-use purposes. These scripts are typically used for tasks that do not require persistent state or long-term execution and are often discarded or removed after they fulfill their function.

**Ethereum Virtual Machine (EVM):** A decentralized computing environment that executes smart contracts on the Ethereum blockchain.

**Finality:** The point at which a transaction is considered permanently recorded on the blockchain and cannot be altered or reversed, providing assurance that it is completed.

**Forc:** A command-line toolchain that serves as the backbone of Fuel development. It supports everything from compiling Sway smart contracts to managing dependencies and deploying applications.

**Fuel Ignition:** Will be the first Fuel V2 rollup to go live on Ethereum Mainnet. It aims to surpass traditional EVM rollups by delivering a vastly improved execution design.

**Fuel Rust SDK:** A developer tool that allows developers to interact with Fuel’s blockchain using the Rust programming language. It offers a seamless experience for creating system-level applications and managing interactions with the Fuel Network.

**Fuel Typescript SDK:** A developer tool that allows developers to integrate Fuel into web applications. It simplifies interaction with the Fuel blockchain, making it easy for frontend developers to build decentralized applications that interact with Fuel’s infrastructure.

**Fuel Virtual Machine (FuelVM):** A high-performance execution environment for the Fuel Network that enables parallel transaction processing, achieving up to 21,000 transactions per second per core. It optimizes resource use and minimizes demands on full nodes, enhancing network sustainability and decentralization.

**Fuel Wallet SDK:** A developer tool that provides developers with the tools to create secure, user-friendly wallets that natively interact with the Fuel ecosystem. It ensures developers can easily build wallets that integrate into decentralized applications.

**Interoperability:** The ability of different networks to communicate and exchange assets or data seamlessly, enabling cross-chain functionality without intermediaries.

**Layer 1:** A base blockchain network (e.g., Bitcoin, Ethereum) responsible for processing and finalizing transactions directly on its ledger.

**Layer 2:** An off-chain scaling solution built on top of a Layer 1 blockchain to improve transaction speed and reduce costs while still relying on Layer 1 for security and finality.

**Merkle Tree:** A data structure used in blockchains to efficiently and securely verify large sets of transactions, by organizing them into a tree-like structure where each node is a cryptographic hash of its children.

**Native Assets:** Cryptocurrencies or tokens that are built into and exist directly on a blockchain, serving as the primary currency for that network.

**Optimistic Rollup:** A Layer 2 scaling solution that processes transactions off-chain while assuming they are valid by default, requiring participants to challenge fraudulent transactions within a specific time frame. If no challenges are made, the transactions are considered valid and finalized on the Layer 1 blockchain.

**Parallelism:** The ability to process multiple transactions simultaneously.

**Predicate:** A stateless smart account that allows transactions to execute in parallel without conflict.

**Proposer-Builder Separation (PBS):** Proposer-builder separation (PBS) is an Ethereum concept designed to enhance network scalability and security by splitting block building responsibilities into two distinct roles: block proposers and block builders.

**Rollup:** A Layer 2 scaling solution that batches multiple transactions into a single one and processes them off-chain, while still ensuring security and finality on the Layer 1 blockchain.

**Scalability:** The capability of a blockchain to handle an increasing number of transactions or users without compromising performance, security, or decentralization.

**Script:** Entrypoint for fuel transactions which dictates what happens as part of a Fuel transaction.

**State:** All the data a blockchain needs to store and maintain.

**State Tree:** A data structure used in blockchains to represent the current state of all accounts, smart contracts, and their balances. It allows for efficient storage and retrieval of state information, often enabling quick verification and updates during transaction processing.

**Sway:** a domain specific language (DSL) for modern blockchain programming which has familiar syntax, grammar and design ideology to Rust while incorporating blockchain specific functionality such as smart contract interface concepts.

**Throughput:** The number of transactions a blockchain can process within a given time frame, often measured in transactions per second (TPS).

**Unspent Transaction Output (UTXO):** The model used for tracking asset ownership, contracts, messages and transactions.

**Virtual Machine (VM):** An environment that executes smart contracts on a blockchain, enabling developers to run code in a decentralized manner without needing to interact with the underlying hardware.

**Zero Knowledge:** A cryptographic method that allows one party to prove to another that they know a value without revealing the value itself or any other information.


---

### File: docs/nightly/fuel-book/docs/src/index.md

# Introduction

Welcome to the Fuel Book, your comprehensive guide to Fuel. This book serves not only as a reference but also reflects our motivations for building Fuel and the philosophies we have incorporated into it.

Our main goal is to dive deeper into the "why" behind Fuel, moving beyond just the technicalities to explore the foundational philosophies and inspirations that guide our work.

We recognize that our audience encompasses developers, researchers, and blockchain enthusiasts. We’ve made it easier to find relevant information, and structured the book with specific sections tailored to different user needs:

**Table of Contents:** Quickly locate specific sections of interest.

**Key Terms and Glossary:** Throughout the book, you will come across terminology unique to the Fuel ecosystem and blockchain, so we included a glossary at the end.

**Visuals:** We also included diagrams and illustrations to clarify complex ideas.

**Further Reading:** At the end of each section, you’ll find recommendations for further reading and resources to deepen your understanding and provide additional context.

**Interactive Components:** For our hands-on learners, we’ve included links to our online resources and community forums. Connect with like-minded Fuel community members and developers to collaborate on learning or building!


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/block-building-in-fuel.md

# Block Building in Fuel

Highlights:

- The Block Builder plays a pivotal role in block building within Fuel by processing messages and transactions, constructing blocks, and submitting them to Layer 1 while ensuring soft-finality on Layer 2.

- The Fuel Block Builder uses a messaging system to facilitate the transfer of information between Layer 1 and Layer 2, enabling both regular transactions and forced transaction inclusion. This feature empowers users to bypass potential censorship by relaying their transactions directly from Layer 1.

- To guarantee reliable processing of messages and transactions, the Block Builder appends a data height (da_height) to each block, linking it to a specific Layer 1 block. By utilizing Merkle trees to store commitments, the system ensures that all events are processed in a deterministic manner, allowing for transparent validation and slashing of the Block Builder if necessary.

- The Block Builder also processes local transactions, allowing users to send transactions directly to it for more efficient batching and compression. This method reduces transaction costs and accelerates soft finality, providing users - with quicker confirmations compared to traditional Layer 1 submissions.

- The Block Builder determines transaction ordering and manages miner extractable value (MEV) in Fuel. It prioritizes transactions based on the tips provided, contrasting with the first-in-first-out approach found in many other Layer 2 solutions, which optimizes user incentives within the network.

This section focuses on block building in Fuel and the role that the Block Builder plays in this process.

The Fuel Block Builder is a component in Fuel rollups, which is responsible for:

- Processing messages from L1 → L2

- Processing transactions in the mempool

- Building blocks and submitting them to the Layer 1

- Providing soft-finality on the Layer 2

## L1 → L2 processing

Fuel rollups have a messaging system (from L1 → L2 and vice versa), which we will discuss further in the next section on bridging. In addition to relaying bridge messages, this system allows transactions to be sent directly from L1, which is used for forced transaction inclusion.

The Fuel Block Builder uses a relay to receive messages and transactions from L1 → L2, we will discuss both of these cases individually now.

### L1 Messages

Block Builder receives relayed messages from Layer 1 emitted as L1 events. The message is then picked up as part of the block-building process; each message sent from the L1 has the following format:

| name      | type      | description                                                  |
|-----------|-----------|--------------------------------------------------------------|
| sender    | bytes[32] | The identity of the sender of the message on the L1          |
| recipient | bytes[32] | The recipient of the message on the Fuel Blockchain          |
| nonce     | bytes[32] | Unique identifier of the message assigned by the L1 contract |
| amount    | uint64    | The amount of the base asset transfer                        |
| data      | byte[]    | Arbitrary message data                                       |

The block builder creates an output of type `OutputMessage`, and after creating this output, it completes the message processing.

Applications can leverage these `OutputMessage(s)` as they see fit. One example is the deposit process, where the bridge contract mints new ETH on the L2 after receiving specific messages that prove deposits on the L1 (we will discuss this further in the next section).

### L1 Transactions and Forced Inclusion

Fuel provides forced inclusion of transactions. If a user feels the L2 block builder is attempting to censor, they can emit a serialized transaction from the L1 as an event, forcing the L2 block builder to include the transaction in the block building. This process, called “Forced Inclusion,” guarantees user censorship resistance.

The Fuel transactions sent from L1 are emitted as events via the L1 and have the following format:

| name                   | type      | description                                                        |
|------------------------|-----------|--------------------------------------------------------------------|
| nonce                  | bytes[32] | Unique identifier of the transaction assigned by the L1 contract   |
| max_gas                | uint64    | The maximum amount of gas allowed to use on Fuel Blockchain        |
| serialized_transaction | byte[]    | The serialized transaction bytes following canonical serialization |

Forced Inclusion allows the processing of all transaction types except `Mint`, which can only be created by the Fuel Block Builder. This exception does not restrict security guarantees for users' censorship resistance.

### Guarantees around L1 processing

How does the L2 guarantee it will always process messages or transactions sent from L1?

This is done by appending the `da_height`, i.e., the L1 block up to which the current block processes messages and transactions. A commitment for all the events and transactions is stored as part of the block header, using a Merkle tree and its root.

All events from L1 → L2 (both inbox messages and forced transactions), are ordered by their block number and the index in that block. Following this order allows us to find a deterministic way of creating this Merkle tree.

We create this Merkle tree and store the root in the `event_inbox_root` field as part of the block header.

Fuel blocks are subject to later challenges. If it's proven that a specific message or transaction was omitted or not processed, the responsible block builder can be penalized.

## Processing Local Transactions

Apart from processing messages and transactions from L1 → L2, the Block Builder is responsible for processing transactions sent to it locally. Users can send transactions to the Block Builder locally, collected in its Mempool, and then processed and sent to Layer 1.

By using clever batching and compression techniques (gzip or zstd) this system offers users lower transaction costs compared to direct Layer 1 submissions.

Another advantage of sending transactions directly to the Block Builder is getting faster soft finality on the L2. For a transaction sent via L1 to be processed, the L1 block must be finalized first.

## Block Building and Proposing

The Fuel Block Builder is required to bundle transactions into blocks and propose them to Layer 1 as part of processing transactions. Committed blocks on Fuel enter a ['Challenge Window'](./fuel-and-ethereum.md#challenge-window) after commitment. Once this window closes, the block and its corresponding state are considered to have reached 'L1 finality'.

Fuel Block Builder currently sends the block hash and block height as new updates to the onchain message portal, along with blobs containing transactions and other data,  to provide DA for that specific block.

## Transaction Ordering and MEV

The current Fuel Block Builder decides the priority of a transaction by sorting with `tip/max_gas`, which means unlike many other L2s, the network isn’t FIFO (First In First Out); this also means that in Fuel, the Priority of your transaction inclusion is:

- Directly proportional to the `tip` you provide as part of the transaction

- Inversely proportional to the `max_gas` you permit for your transaction

## Soft Finality

The Block Builder also plays a major role in providing soft finality for L2 transactions. As an L2 participant, you can choose the level of finality at which you're comfortable making business decisions.

When the Block Builder orders and processes your transaction, it provides a soft finality. This can be considered confirmed unless the Block Builder fails to finalize it on L1.

## Appendix

### Full Nodes

The [fuel-core](https://github.com/FuelLabs/fuel-core) software also allows you to run a Full Node. A Full Node collects the latest updates on Layer 2 from the peers and broadcasts incoming transactions to the network.

Full Nodes cannot build blocks; instead, they receive them as updates via p2p and re-execute them locally to maintain the correct state with complete verification.

By running the Full Node, you can, as a user, be given the ability to keep verifying the L2 yourself and, hence, also be able to send fraud proofs. You also get your own GraphQL endpoint, which can broadcast your transactions to the network.

All Fuel GraphQL providers run Full Nodes themselves to provide you with the latest Fuel state and allow you to broadcast transactions.


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/fees-on-fuel.md

# Fees on Fuel

The Fuel ignition process introduces various fees and costs essential for utilizing the permissionless network. These can be categorized into the following types:

- **Transaction Fees:** A mandatory fee paid to validators for processing transactions and executing instructions on the network.
- **Tip:** An optional fee that allows users to boost their transactions in the processing order, ensuring faster execution.

## Fuel’s Approach to Transaction Fees

### Fee Structure

Fuel operates on a modular execution layer, emphasizing efficiency in gas computation and storage fees. Instead of relying on inflationary rewards, Fuel focuses on sustainable economics driven by transaction fees. [Learn more.](https://docs.fuel.network/docs/specs/fuel-vm/#script-execution)

### Parallel Execution for Low Fees

Fuel’s unique parallel transaction execution significantly reduces congestion. This results in:

- Lower transaction fees.
- Faster settlement times, which encourages a high volume of transactions.
  
This aligns with the long-term vision of most blockchains to sustain security through transaction fees rather than inflation.

## Transaction Fees in the Fuel Network

In the Fuel network, transaction fees are essential for incentivizing block builders to prioritize transactions and for maintaining network security and efficiency. Understanding how transaction fees are calculated and how they are used helps users make informed decisions on how to interact with the network.

## What Are Transaction Fees?

Transaction fees in Fuel are the costs that users must pay to process and execute their transactions on the network. These fees are dynamic and depend on several factors, including the gas consumed by the transaction, the gas price, and the gas limit set by the user.

Transaction fees are calculated based on gas consumption during the execution of the transaction. There are two main components that determine the cost:

- **Intrinsic Fees:** The fundamental costs associated with a transaction, including the byte size, processing of inputs/outputs, predicates and signature verification, and initializing the virtual machine (VM). These fees are incurred regardless of whether the transaction is successfully executed.  
- **Execution Fees:** Costs associated with the computational work performed during the transaction, determined by the complexity of operations such as smart contract execution, data manipulation, and VM computations.  

## Gas Consumption Breakdown  

- **Intrinsic Gas Fees:** These cover the basic costs of transaction handling, which include:  
  - Byte size of the transaction.  
  - Input/output processing.  
  - Predicate evaluation and signature verification.  
  - VM initialization (prior to executing scripts or predicates).  

- **Execution Gas Fees:** These fees account for the gas consumed during the execution phase of the transaction, such as:  
  - Smart contract execution.  
  - Data processing and storage.  
  - Interactions with decentralized applications (dApps) or other smart contracts.  
The total fee for a transaction is calculated using the following formula:

```python
def cost(tx, gasPrice) -> int:
   return gas_to_fee(min_gas(tx) + tx.gasLimit - unspentGas, gasPrice)
```

Where:

- `min_gas(tx)`: Minimum gas required for the transaction, covering intrinsic fees.
- `tx.gasLimit`: The maximum amount of gas that the user is willing to spend for this transaction.
- `unspentGas`: Gas left over after intrinsic costs and execution. This is collected by the block producer as a reward in the Fuel
  network.
- `gas_to_fee()`: Converts the total gas used (after considering min gas, gas limit, and unspent gas) into a fee based on the gasPrice.

The final transaction fee depends on the amount of gas consumed during execution and the gas price specified by the user.

If the transaction uses less gas than the gas limit set by the user, the leftover gas (referred to as unspent gas) is collected by  block builder as a reward.

`The block gas limit is 30000000`

## Tips in the Fuel Network

Tips are an additional fee provided by the user to incentivize block builders to prioritize their transaction. In Fuel, the priority of your transaction’s inclusion in the block is determined by both the tip and the max_gas (gas limit) you set for the transaction.

## What is a Tip?

A tip is an extra fee that the user adds on top of the minimum transaction fees to increase the likelihood that their transaction will be included in the next block. This tip directly incentivizes the block builder to prioritize the transaction.

- **Setting the Tip in a Transaction**

To set the tip in a transaction using the Fuel SDK, you can specify it in the transaction parameters. Here’s an example in TypeScript using the fuels library:

```typescript
import { bn, ScriptTransactionRequest } from 'fuels';

const transactionRequest = new ScriptTransactionRequest({
  tip: bn(10), // Sets the tip policy
  maxFee: bn(1), // Sets the max fee policy
});
```

In this example, the tip is set to 10 using the bn function to handle big numbers. The tip is an optional amount added to incentivize the block producer to include the transaction, ensuring faster processing for those willing to pay more.

## Fee Structure and Incentives

Fuel uses a dynamic fee model where transaction fees are adjusted based on network congestion, transaction complexity, and the user’s willingness to pay higher fees. Block builders are incentivized based on both the tip and max_gas (gas limit), creating a flexible and efficient system.

## Transaction Prioritization

In Fuel, transactions are prioritized by the block builder based on two main factors:

- **Tip:** The additional gas fee provided by the user to incentivize faster processing of the transaction. A higher tip means higher priority for inclusion in the block.
- **max_gas:** The maximum gas limit specified by the user for the transaction. A higher max_gas means the transaction may take longer to process, lowering its priority.

The priority of a transaction is:

- Directly proportional to the tip: Higher tips increase the transaction’s priority.
- Inversely proportional to the max_gas: A higher gas limit decreases the transaction’s priority.

This model encourages users to offer a higher tip to ensure quicker inclusion, while also considering the transaction’s gas limit to avoid excessively large transactions.

## Unspent Gas and Block Producer Rewards

After a transaction is executed, any leftover gas (`unspentGas`) is collected by the block producer as a reward.

- **UnspentGas:** The remaining Gas left over after intrinsic costs and execution. This is collected by the block producer as a reward in the Fuel
- **Block Producer Incentives:** Block producers are rewarded for processing transactions, both through the minimum fee (guaranteed for each transaction) and the unspent gas collected.

The unspent gas ensures that block producers are incentivized to prioritize transactions with higher tips and to optimize block space for better overall performance.

## Example Gas Calculation

Here’s a simplified example of how gas works in Fuel:

- **Transaction:** A user sends tokens to another account.
- **Gas Calculation:**
  - Compute Gas: CPU work required to validate the transaction.
  - Storage Gas: Updating the account balance in the blockchain.

If the gas limit is set to 10,000 and the gas price is 1 gwei, the total fee would be:

- 10,000 x 1 gwei = 10,000 gwei (or 0.00001 ETH ).

When a transaction involves script execution, the system sets up the virtual machine (VM) to run the transaction. It checks the amount of gas available for the transaction and starts running the script step by step.

For each step in the script, the system calculates how much gas it needs. If there isn’t enough gas left to run a step, it stops the process and “reverts” the transaction, meaning nothing changes except for the gas spent. If there’s enough gas, it continues running the script and deducts the gas used. [Learn more](https://docs.fuel.network/docs/fuel-book/the-architecture/transactions-on-fuel)

At the end of the transaction, the system updates a record (called the `receiptsRoot`) to show the results of the transaction. This process helps ensure that the transaction is handled efficiently and fairly, with gas being used properly.

## Fee Calculation Example

Let’s consider a transaction with the following parameters:

- Intrinsic Gas (`min_gas(tx)`): 10,000 gas
- Gas Limit (`tx.gasLimit`): 50,000 gas
- Unspent Gas (`unspentGas`): 5,000 gas
- Gas Price (`gasPrice`): 0.001 Fuel per gas unit

The transaction fee will be calculated as:

```python
min_gas = 10000
gasLimit = 50000
unspentGas = 5000
gasPrice = 0.001

# Total gas used for the transaction
totalGas = min_gas + gasLimit - unspentGas

# Convert gas to fee
fee = gas_to_fee(totalGas, gasPrice)
```

This fee is the final cost that the user will pay for the transaction, which includes both intrinsic and execution gas fees, adjusted based on the gas price. Note that `gasLimit` applies to transactions of type Script. `gasLimit` is not applicable for transactions of type Create and is defined to equal 0 in the above formula.

## Transaction Parameters

The following are the available parameters to control transaction behavior:

```typescript
const txParams: TxParams = {
  gasLimit: bn(70935),
  maxFee: bn(69242),
  tip: bn(100),
};
```

### Explanation of Parameters

- **Gas Limit (`gasLimit`):** The maximum amount of gas you're willing to allow the transaction to consume. If the transaction requires more gas than this limit, it will fail.
  - Example: `gasLimit: bn(70935)`
- **Max Fee (`maxFee`):** The maximum amount you're willing to pay for the transaction using the base asset. This allows users to set an upper limit on the transaction fee they are willing to pay, preventing unexpected high costs due to sudden network congestion or fee spikes.
  - Example: `maxFee: bn(69242)`
- **Tip (`tip`):** An optional amount of the base asset to incentivize the block producer to include the transaction, ensuring faster processing for those willing to pay more. The value set here will be added to the transaction maxFee.
  - Example: `tip: bn(100)`

--------

Fuel’s transaction fee model provides a balanced approach to cost and incentivization:

- Transaction Fees are composed of intrinsic and execution gas fees, with the `gasPrice` determining the final transaction cost.
- Tip and `max_gas` determine transaction priority, allowing users to prioritize their transactions by increasing the tip or adjusting the gas limit.

By setting parameters such as `gasLimit`, `maxFee`, `tip`, and others, users have full control over the cost and priority of their transactions, ensuring a flexible and efficient experience within the Fuel network.


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/fuel-and-ethereum.md

# Fuel and Ethereum

Highlights:

- Fuel Ignition leverages Ethereum as its Layer 1 for settlement and data availability, aligning with Ethereum's core values of sustainability, security, and accessibility for everyday users. This choice emphasizes Fuel's commitment to building a long-term, decentralized ecosystem.

- By utilizing one of the most established and decentralized Layer 1 networks, Ethereum provides a robust foundation for Fuel’s rollup, ensuring reliable performance and security. Fuel's rollup inherits Ethereum's security model, which safeguards user funds and enables fraud-proof mechanisms directly on the Ethereum blockchain.

- Fuel allows seamless messaging between Layer 1 and Layer 2, ensuring that any message sent to Ethereum must be processed on Fuel and vice versa. This capability enhances user experience and guarantees censorship resistance.

- Users can easily deposit and withdraw ETH, transferring assets between Layer 1 and Layer 2. They can deposit ETH directly to Fuel and initiate withdrawals by burning tokens on Layer 2, with the system ensuring timely and secure processing.

- Fuel actively pursues innovation through techniques like hybrid proving, optimizing the proving system by reducing complexity and shortening challenge windows. By embracing a modular tech stack, Fuel remains adaptable, exploring integration with alternative Layer 1s and data availability solutions to enhance its ecosystem.

Fuel Ignition uses Ethereum as a Layer 1. We chose Ethereum as Fuel’s L1 for both Settlement and Data availability of the L2, because we think Fuel shares many of Ethereum’s values:

- Building for long-term sustainably

- Building with an emphasis on security

- Focus on consumer hardware and making participation in the protocol accessible  for ordinary people

Ethereum is one of the most decentralized L2s. Ethereum has a long-standing presence and has focused on a rollup-centric roadmap for years. These factors make it the ideal foundation for building a rollup.

![2.5 Fuel and Ethereum](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.5-fuel-and-ethereum-light.png)

## Inheriting Ethereum’s Security

Fuel’s flagship rollup, Ignition, inherits Ethereum’s security. The natural question from the previous statement is, what do we mean by inheriting Ethereum’s security?

Fuel uses Ethereum as the layer to keep users’ funds and propose its latest blocks and corresponding state updates. We deploy smart contracts that continuously get updates of Fuel Layer 2.

Then, we have fraud-proving performed directly on the Ethereum L1 to prove that something about the posted blocks or related state updates is wrong. We also allow permissionless messaging and transaction inclusion via the L1 to ensure the user doesn’t experience any censorship resistance.

This gives the user guarantees that as long as Ethereum is secure and the honest majority assumption for it is held:

- No fraud blocks or state updates can be sent
- Their funds are always safe on the Layer 1
- They can never be stopped from withdrawing them or being able to send any transaction to the L2 (forced inclusion)

Now, we will discuss each of the properties we described above.

## Messaging

Fuel allows for messaging between L1 → L2 and L2 → L1, which means you can send any arbitrary message from Layer 1 to Layer 2 and vice versa. The protocol guarantees that if a message is included in the L1, it has to be processed on the L2 and vice versa. Let’s discuss both of these cases individually.

### L1 → L2 Messaging

The [Fuel Message Portal](https://github.com/FuelLabs/fuel-bridge/blob/main/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol) facilitates message processing from L1 -> L2. Its method, [sendMessage](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L250), accepts the L2 recipient (a Fuel Address) and the corresponding message to be sent. After a successful call to this method, a [MessageSent](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L49) event is emitted on Layer 1.

As discussed in the section on block building, part of processing the Fuel blocks requires committing to some L1 block height, up to which the block builder processes messages and transactions, this forces the Block builder to include all messages from the L1 (as in case of failure, the builder can be slashed).

![2.5 L1 → L2 Messaging](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.5-l1-l2-messaging-light.png)

As part of processing the message blocks from the L1, the block builder looks at the event and mints an OutputMessage transaction to the particular Fuel address with the specific data.

### L2 → L1 Messaging

Fuel also allows messages from the L2 -> L1 to be sent using [MessageOut](https://github.com/FuelLabs/fuel-specs/blob/master/src/abi/receipts.md#messageout-receipt) receipts. Every Fuel block includes a receipt root, the root of all receipts that were part of the block. This allows anyone to make a call to the [relayMessage](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L188) function of the Fuel Message Portal; a Merkle proof of inclusion is required to perform for the message you are trying to process along with that, it checks whether the block for which the message is being processed has been finalized or not (i.e., it outside of the challenge window).

![2.5 L2 → L1 Messaging](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.5-l2-l1-messaging-light.png)

Processing the message on the L1 coming from the L2 is done by calling the specific L1 address to which the message is sent to with some desired payload.

## ETH Deposits and Withdrawals

A core part of using the Fuel rollup is depositing ETH from the L1 to Fuel and withdrawing it from the L2. We will discuss both of these scenarios individually.

### ETH Deposits

The user can call the [depositEth](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L256) function on the L1 to create a deposit. The method is payable, and emits a [messageSent](https://github.com/FuelLabs/fuel-bridge/blob/6030a40ce9c58a533c09f73e837f85ab4784ef58/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L49) event with an empty payload, this makes the sequencer recognize this is a deposit made on the L1 and it mints a new eth coin corresponding to the value of the deposit for the user.

### ETH Withdrawals

Withdrawals on the L2 are made by burning the tokens on the L2 via the [L2 gateway](https://github.com/FuelLabs/fuel-bridge/blob/main/packages/fungible-token/bridge-fungible-token/implementation/src/main.sw#L147). Then, the gateway emits a [MessageOut](https://docs.fuel.network/docs/specs/abi/receipts/#messageout-receipt) receipt, which is part of the block header, allowing the relay of this message to Layer 1.

The Layer 1 [Message Portal](https://github.com/FuelLabs/fuel-bridge/blob/de18552d4a23c6ec1477c6532732dbcdc05a8c16/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol) contract has a [relayMessage](https://github.com/FuelLabs/fuel-bridge/blob/de18552d4a23c6ec1477c6532732dbcdc05a8c16/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol#L188) function (read [L2 → L1](#l2--l1-messaging) messaging for details); which allows for processing L2 messages aimed for L1, in the case of withdrawals, we send a message with the amount corresponding to the value the user has burned on the L2, and hence the [Message Portal](https://github.com/FuelLabs/fuel-bridge/blob/de18552d4a23c6ec1477c6532732dbcdc05a8c16/packages/solidity-contracts/contracts/fuelchain/FuelMessagePortal.sol) contract provides the L1 recipient with their funds for withdrawal.

Note: A withdrawal requires the '[Challenge Window](#challenge-window)' to be cleared before being processed, and hence the user has to wait till the 'Challenge Window' (although there are [fast finality gadgets](http://ethresear.ch/t/why-wait-a-week-fast-finality-optimistic-rollups/18868) which can bring this down.)

## State Updates

Fuel uses Ethereum to submit new state updates. This is done using the [State Contract](https://github.com/FuelLabs/fuel-bridge/blob/main/packages/solidity-contracts/contracts/fuelchain/FuelChainState.sol) on Layer 1, where the blocks are committed by sending the block hash and block height. The contract also records the timestamp as part of the commitment for a particular block.

These state updates and the data posted as Blobs on Ethereum allow for challenging any state updates sent to the L1.

## Challenge Window

The challenge window is the time it takes for a block and related state posted on the L1 to be considered finalized. Finalization means any withdrawal or message part of this block can be processed on the L1. For now, the challenge window for Fuel is seven days.

Techniques like hybrid proving and other fast finality gadgets can reduce the duration of the challenge window; we are actively researching these areas and would encourage you to read [Nick Dodson’s post](http://ethresear.ch/t/why-wait-a-week-fast-finality-optimistic-rollups/18868) on faster finality gadgets for optimistic rollups.

## Hybrid Proving

Fuel believes in a philosophy of [zk-pragmatism](../why-fuel/the-fuel-way.md#zk-pragmatism); rather than playing bisection games on-chain like other rollups (which increase the complexity of the proving system)  or sending zk proofs for every bath like zk rollups (which increase the cost per transaction), Fuel makes a hybrid approach for its proving system.

The system runs in an optimistic setting. If someone in the system believes that a fraud state has been sent, they create a zk-proof off-chain of the claim and prove fraud in a single interaction with the L1. This reduces the proving system's complexity and limits the challenge window.

Hybrid proving is being developed, and prototyping is done with RISC-V-based zkVMs like SP-1 and RISC-0. You can read more about the proving system [here](https://fuel.mirror.xyz/gY0Clw114Ipnel1Bhrey9LCsxX94ly3I9yAfnSWYWTg).

## Appendix

### Alt-DAs and L1s

We have launched our flagship rollup with Eth as our L1 for settlement and data availability, but Fuel believes in creating a neutral and modular tech stack. The Fuel tech stack can be extended to launch on alt L1s like Bitcoin and Solana and with alt DAs like Celestia and Avail. If someone wants, they can even use the Fuel stack to launch their L1.

We will keep progressing our tech stack to be adaptable in multiple scenarios, resilient, and feasible on consumer-grade hardware.

### Blobs

EIP 4844 introduced Blobs as a cheaper way to get Data Availability for Ethereum rollups. Fuel block builders also use blobs, although this is a work in progress.

Fuel blocks are batched together in a bundle, compressed via popular techniques (gzip or zstd), and posted as blobs. Because blobs are fixed in size, uploading has to be done via a series of transactions.

Blobs and their exact implementation are still being finalized and will be live soon, but the above text summarizes the general approach for now.


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/fuel-blocks.md

# Fuel Blocks

Highlights:

- In Fuel, blocks are constructed by Block Builders, who process both transactions and messages to create the blocks. Users send transactions either directly to the builder or through layer 1, while messages originate from layer 1. The Fuel and Ethereum section of the book provides further details on this process.

- Each Fuel block begins with a header that consists of three main fields: the Application Header, the Consensus Header, and Block Header Metadata. This structure facilitates efficient management and processing of block-related information.

- The Application Header records critical operational details for the Fuel rollup, comprising four essential components: the da_height, consensus_parameters_version, state_transition_bytecode_version, and generated fields. These components work together to ensure the rollup operates correctly and efficiently.

- The Consensus Header tracks the hash of the Application Header, providing a secure and verifiable method for maintaining consensus within the Fuel network. This header is crucial for ensuring the integrity of the block.

- Fuel blocks also include a Coinbase transaction, which enables block producers to collect fees for their work. This Mint transaction must be the last in the block and is capped at the total fees processed from all transactions within that block, ensuring a fair and controlled fee structure.

Blocks in Fuel are built by entities called Block Builders. Fuel blocks are made by processing transactions and messages. Transactions can be sent directly to the builder or via layer 1, while messages are sent from layer 1. In the Fuel and Ethereum section of the book, we expand further on messages and transactions sent from the L1.

## Block Header

A Fuel block header at the top consists of three fields:

- Application Header
- Consensus Header
- Block Header Metadata

```c++
pub struct BlockHeaderV1 {

    pub application: ApplicationHeader<GeneratedApplicationFields>,

    pub consensus: ConsensusHeader<GeneratedConsensusFields>,

    metadata: Option<BlockHeaderMetadata>,
}
```

### Application Header

The application header records essential information regarding the operation of the Fuel rollup.

The application header at the high level consists of four essential components:

```c++
pub struct ApplicationHeader<Generated> {

    pub da_height: DaBlockHeight,
 
    pub consensus_parameters_version: ConsensusParametersVersion,

    pub state_transition_bytecode_version: StateTransitionBytecodeVersion,

    pub generated: Generated,
}
```

#### da_height

The `da_height` field records the latest block L1 block until the messages sent from the L1 → L2 have been processed; this is helpful later in fraud proving to establish that a particular message was sent from the L1 to the L2 rollup but wasn’t processed as part of the block that included the messages up to the block of which it was part.

#### consensus_parameters_version

The Fuel rollup has a set of upgradeable [consensus parameters](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/#consensus-parameters), which are upgradable via Transactions of type `Upgrade`. For each consensus parameter upgrade, a new version for `consensus_paramters_version` must be assigned, helping us track which set of consensus parameters we are using while building a particular block.

#### state_transition_bytecode_version

The Fuel rollups keep the WASM compiled bytecode of their state transition function as part of the chain facilitating forkless upgrades for the Fuel rollups.

The new state transition function is uploaded via the `Upload` transactions, while the upgrade is done via the `Upgrade` transactions. Each upgrade updates the `state_transition_bytecode_version`, and this version helps keep track of which state transition function is being used to process transactions for a given block.

#### generated

The section contains various rollup-specific fields around execution for a specific block. The Fuel flagship rollup has the following fields for `generated`:

```c++
pub struct GeneratedApplicationFields {
    /// Number of transactions in this block.
    pub transactions_count: u16,
    /// Number of message receipts in this block.
    pub message_receipt_count: u32,
    /// Merkle root of transactions.
    pub transactions_root: Bytes32,
    /// Merkle root of message receipts in this block.
    pub message_outbox_root: Bytes32,
    /// Root hash of all imported events from L1
    pub event_inbox_root: Bytes32,
}
```

### Consensus Header

The consensus header is another top-level field for the Block Header for Fuel rollups, it is configurable and for the flagship Fuel rollup only keeps track of the hash of the Application Header.

```c++
pub struct GeneratedConsensusFields {
    /// Hash of the application header.
    pub application_hash: Bytes32,
}
```

### Block Header Metadata

The Block Header Metadata is used to track metadata. The current flagship Fuel rollup includes a field tracking the block ID, which represents the hash of the block header.

```c++
pub struct BlockHeaderMetadata {
    /// Hash of the header.
    id: BlockId,
}
```

## Coinbase Transaction

Fuel blocks contain a Coinbase transaction; block producers use Coinbase transactions to collect fees for building blocks. The Coinbase transaction is a `Mint` transaction, where the `mintAmount` cannot exceed the fees processed from all transactions in the block. The protocol also requires the Coinbase transaction to always be the last transaction in the block.


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/index.md

# Chapter 2 - The Architecture

- [2.1 - The FuelVM](./the-fuelvm.md)
- [2.2 - Transactions on Fuel](./transactions-on-fuel.md)
- [2.3 - Fuel Blocks](./fuel-blocks.md)
- [2.4 - Block Building in Fuel](./block-building-in-fuel.md)
- [2.5 - Fuel and Ethereum](./fuel-and-ethereum.md)
- [2.6 - Security on Fuel](./security-on-fuel.md)
- [2.7 - Fees on Fuel](./fees-on-fuel.md)


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/security-on-fuel.md

# Security on Fuel

Highlights:

- Fuel emphasizes security across its rollup ecosystem, particularly through its Security Council, which operates multi-signature wallets to oversee and upgrade various components of the stack. This council plays a critical role in safeguarding the network as Fuel navigates its transition to a fully permissionless system.

- The project recognizes the current centralization of block building and sequencing as a challenge. To address this, Fuel plans a phased approach to decentralize these processes, beginning with a shared sequencer accessible to all block builders before moving towards fully decentralized block building.

- Fuel proactively identifies and mitigates potential security attack vectors, including bugs in bridge contracts, Layer 2 client implementations, and the Sway compiler. By collaborating with diverse teams and engaging top security organizations, Fuel works to establish robust security protocols and multiple implementations to reduce the likelihood of vulnerabilities.

- The platform also tackles application-level bugs by developing secure support libraries in Sway and promoting best practices among developers. This focus on security fosters a more resilient ecosystem for application development.

- Fuel continuously upgrades its protocol to further enhance security, reducing reliance on the Security Council and minimizing risks associated with multi-signature compromise. The project also prioritizes rigorous auditing and testing of fraud-proving implementations to protect against false claims and ensure that legitimate builders receive fair treatment.

This section discusses the current security of Fuel Ignition and rollups.

## Fuel Security Council

Fuel currently has a security council that operates various multi-sigs to upgrade different parts of the stack.

Rollups are in an early stage of development, necessitating a security council to exercise caution before full decentralization. Network issues can be difficult to resolve, making this oversight crucial.

Developing a stack with type-2 security guarantees is a top priority in Fuel's roadmap.

## Block Building

Currently, block building and sequencing are centralized. Decentralizing these processes, especially block building, requires further development and careful consideration. Block building rights give the builder access to extract MEV from the system, which can impact user’s transactions and experience on the network.

Fuel is implementing a phased approach to decentralize block builders and sequencers.

Fuel will start with a decentralized sequencer set, i.e., a shared sequencer that block builders can use for all Fuel rollups. Decentralized block building will follow in the next phase.

## Security Attack Vectors

In this section, we list various attack vectors for the current system and we explore a path forward to tightening security.

### Bridge Contract Bugs

Fuel has a bridge that allows for messaging between L1 and L2; this messaging system creates the base for building a deposit and withdrawal system along with abilities like forced transaction inclusion and calling contracts L2 on L1.

If a bug in the contract implementation on the L1 or L2 compromises the roll-up system, which can include relaying fake messages and transactions from the L1 and L2. A compromise of the mult-sig can also lead to potential malicious upgrades of these contracts.

Fuel undergoes rigorous audits of its smart contracts with the best-in-class security auditors in the space and also participates in bug bounties to keep the possibility of this very low. These issues become more concerning in stage 2 settings, as the stage 1 setting does allow for reverting potential issues regarding bridge contracts.

### Layer 2 Client Bugs

Like any software, the Fuel execution client could have bugs that might be exploited to enable unintended behavior. If there is only one implementation of the execution client, a malicious actor might manipulate the system without being caught by a fraud-proof mechanism, as no alternative client would exist to validate or challenge the state. This risk is particularly relevant in L2 solutions that rely on a single execution client for ZK proving games or fraud-proof verification, making it a potential attack vector.

Fuel attempts to strengthen security around such scenarios by inviting various teams to collaborate on the stack and aiming for multiple implementations, followed by rigorous testing and security audits by the best security organizations in the industry.

### Sway Compiler Bugs

The Sway Language is a dominant language built on the Fuel VM. A bug in the Sway compiler could allow malicious bytecode to be part of a particular predicate, smart contract, or script, which the implementation didn’t desire. A similar issue was seen in the ETH ecosystem with Vyper, which you can follow [here](https://medium.com/rektify-ai/the-vyper-compiler-saga-unraveling-the-reentrancy-bug-that-shook-defi-86ade6c54265).

Fuel aims to avoid such a scenario by having some of the best talent working on its compiler, followed by rigorous testing and audits by leading security organizations in the industry. In the future, we also aim to have multiple implementations of the compiler, which could help discover a bug in the other implementations.

### Application Level Bugs

Application implementations often have bugs because they avoid some required checks or are built on top of libraries with an underlying bug.

Fuel aims to avoid these by creating best-in-class support libraries in Sway, which are well-audited and tested and safe to build on. These Sway libraries also promotes the usage of secure patterns through developer evangelism.

### Multisig Compromisation

If compromised, the security council's multi-sig can lead to severe issues, such as malicious upgrades or behavior in various parts of the stack.

Fuel aims to solve this by having a security council with a very high reputation and a lot of social capital attached to it. At the same time, continuous protocol upgrades minimize the need for the security council and always accelerate towards allowing for a stage 2 rollup stack.

### Fraud Proving Bugs

A bug in the fraud-proving implementation can cause challenges and slash for block builders who built correct blocks or could allow someone to fail to prove a faulty block. This can result in good builders being slashed or wrong states being finalized.

Fuel aims to solve this by initially correcting any such issues with the help of the security council while aiming for multiple implementations of the fraud-proving client or, if possible, multiple-proving system. The implementation is done with best security practices in mind and with regular system audits.


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/the-fuelvm.md

# The FuelVM

Highlights:

- The FuelVM serves as the core of the Fuel stack, informed by insights from various virtual machine designs like the EVM and Solana's SVM.

- It supports state-minimized application development through features such as native assets and ephemeral scripting, promoting decentralized and accessible architecture.

- The UTXO model facilitates parallelized transaction execution, enhancing throughput and reducing latency by allowing concurrent processing of non-conflicting transactions.
The FuelVM is a register-based virtual machine, providing better performance compared to traditional stack-based designs and offering a structured instruction set for efficient operations.

- Predicates, scripts, and contracts are essential components of the FuelVM, enabling flexible spending conditions, transaction processing, and state management within its execution environments.

The FuelVM lies at the core of the whole Fuel stack; it was created by taking into account  years of learning from other virtual machine designs, like the EVM, Solana’s SVM and more.

The FuelVM enables developers to move away from stateful application designs often enabled by smart contracts by providing more feature-rich state-minimized facilities such as native assets, ephemeral scripting, and ephemeral spending conditions. By offering alternative methods for developers to build state-minimized applications, we enhance full node sustainability while maintaining a decentralized and accessible architecture, aligning with Ethereum’s core values.

In the following sections, we will discuss the key features of the FuelVM in detail.

## UTXO Model and Parallelization

Fuel’s parallelized transaction execution model serves as a cornerstone for its efficiency and scalability. Parallelization dramatically improves throughput and reduces latency compared to traditional sequential processing methods. It breaks tasks into smaller sub-tasks, executing them simultaneously across multiple processing units.

Parallelization is built upon a foundation of [Access Lists](https://docs.fuel.network/docs/specs/protocol/tx-validity/#access-lists) and the UTXO (Unspent Transaction Output) model, which works in tandem to enable concurrent processing of non-conflicting transactions.

Our tech leverages the UTXO model for performing transactions on Fuel. Transactions modeled through UTXOs handle everything from token transfers to smart contract calls.

Addresses on Fuel own unspent coins, allowing them to spend and perform transactions through the FuelVM.

![2.1 UTXO Model and Parallelization](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-utxo-model-and-parallelization-light.png)

Using the UTXO model helps achieve transaction parallelization. At runtime, users provide the inputs and outputs for their transaction. Transactions without overlap process in parallel, enabling Fuel to scale horizontally with the number of cores per machine.

## Register based design

The FuelVM operates as a register-based virtual machine, unlike the EVM and many others, which use a stack-based architecture.

Register-based virtual machines consistently outperform stack-based virtual machines.

The FuelVM includes 64 registers, each 8 bytes, with 16 reserved and 6-bit addressable.

| value | register |         name        |                                    description                                   |
|:-----:|:--------:|:-------------------:|:--------------------------------------------------------------------------------:|
| 0x00  | $zero    | zero                | Contains zero (0), for convenience.                                              |
| 0x01  | $one     | one                 | Contains one (1), for convenience.                                               |
| 0x02  | $of      | overflow            | Contains overflow/underflow of addition, subtraction, and multiplication.        |
| 0x03  | $pc      | program counter     | The program counter. Memory address of the current instruction.                  |
| 0x04  | $ssp     | stack start pointer | Memory address of bottom of current writable stack area.                         |
| 0x05  | $sp      | stack pointer       | Memory address on top of current writable stack area (points to free memory).    |
| 0x06  | $fp      | frame pointer       | Memory address of beginning of current call frame.                               |
| 0x07  | $hp      | heap pointer        | Memory address below the current bottom of the heap (points to used/OOB memory). |
| 0x08  | $err     | error               | Error codes for particular operations.                                           |
| 0x09  | $ggas    | global gas          | Remaining gas globally.                                                          |
| 0x0A  | $cgas    | context gas         | Remaining gas in the context.                                                    |
| 0x0B  | $bal     | balance             | Received balance for this context.                                               |
| 0x0C  | $is      | instructions start  | Pointer to the start of the currently-executing code.                            |
| 0x0D  | $ret     | return value        | Return value or pointer.                                                         |
| 0x0E  | $retl    | return length       | Return value length in bytes.                                                    |
| 0x0F  | $flag    | flags               | Flags register.                                                                  |

## The FuelVM Instruction Set

The FuelVM instructions are 4 bytes wide and have the following structure:

- Opcode: 8 bits
- Register Identifier: 6 bits
- Immediate value: 12, 18, or 24 bits, depending on the operation.

The FuelVM instruction set has been documented in detail here: <https://docs.fuel.network/docs/specs/fuel-vm/instruction-set>.

## Memory

FuelVM uses byte-indexed memory, configurable with the VM_MAX_RAM parameter. Hence, each instance of FuelVM can decide how much memory it wants to allocate for the VM.

Memory follows a stack and heap model. The stack begins from the left, immediately after the initialized VM data and call frame in a call context, while the heap starts at the byte indexed by VM_MAX_RAM.

Each byte allocation on the Stack increases the stack index by 1, and each byte allocation on the heap decreases its writable index by 1. Hence, the stack grows upwards, and the heap grows downwards.

![2.1 FuelVM Memory](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-memory-light.png)

The stack and the heap have the following essential registers associated with them:

- `$ssp` ( 0x05 ): Memory address of bottom of the current writable stack area.
- `$sp` ( 0x06 ): Memory address on top of current writable stack area (points to free memory).
- `$hp` ( 0x07 ): Memory address below the current bottom of the heap (points to used/OOB memory).

The FuelVM has ownership checks to ensure that contexts have a defined sense of ownership over particular regions in the memory and can only access memory from the region they own. We will elaborate more on this topic in later sections.

## Predicates, Scripts and Contracts

Understanding further concepts for Fuel requires grasping:

- Predicates
- Scripts
- Contracts

Let’s dive deeper.

### Predicates

Predicates are stateless programs that define spending conditions for native assets. Native assets go to predicates, and to determine whether they are spendable in a transaction, the FuelVM executes the bytecode and checks the boolean return value. If the returned value is true, the asset can be spent; if the returned value is false, then the transaction is invalid!

People can program various spending conditions, such as spending only if three out of five approve a transaction or if a transaction includes specific desired inputs and outputs, commonly known as intents.

Predicates operate statelessly, without persistent storage, and cannot call other smart contracts.

### Scripts

Scripts serve as the entry point for Fuel transactions, dictating the flow of the transaction. Like predicates, they lack persistent storage. However, they can call contract Inputs, which are part of the Fuel transaction and can have persistent storage of their own.

This enables Fuel to natively support advanced features such as multi-calls, conditional contract execution, and more.

### Contracts

Fuel provides support for smart contracts in its UTXO model. Smart contracts are stateful and can be called by other contracts. In Fuel, smart contracts are represented by the `InputContract` type. To learn more, refer to the section on InputContract.

The first call to a contract in a transaction occurs through a script, after which the contract can call other contracts.

Contracts have persistent storage, a key-value pair of 32-byte and 32-byte values. Various data structures are being considered to determine the optimal approach for committing to contract storage.

## Contexts

A context is a way to isolate the execution of various execution environments for predicate estimation and verification, scripts, and contracts. Each context has its memory ownership, which we will expand on later.

There are four types of contexts in Fuel:

- Predicate Estimation
- Predicate Verification
- Script Execution
- Calls

The first three are called External contexts, as the `$fp` is zero, while Calls are called Internal contexts and will have a non-zero value for `$fp`.

### Predicate Estimation

Fuel transactions provide `predicateGasUsed` for each predicate used. During verification, if predicateGasUsed is less than the total gas consumed during verification, the transaction reverts.

![2.1 Predicate Estimation](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-predicate-estimation-light.png)

The user performs Predictive Estimation locally or by calling a remote full node, which executes the predicate in the FuelVM and returns the total gas consumed.

Predicate estimation context cannot do persistent storage or make calls to Contracts.

### Predicate Verification

All predicate parts of the transaction are verified to return true before executing the transaction script. The FuelVM is used in the Predicate Verification context when verifying a transaction's predicates.

![2.1 Predicate Verification](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-predicate-verification-light.png)

Predicate verification context cannot do persistent storage or make calls to contracts.

### Script Execution

After verifying all predicates, the transaction script is executed; the script execution context cannot do persistent storage but can make calls to contract.

![2.1 Script Execution](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-script-execution-light.png)

### Calls

Call contexts execute contracts, offering flexibility, storing data persistently, and making contract calls.

Call context is created by either:

1. Script calling a smart contract
2. Contract calling a contract input

![2.1 Call Context](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-call-context-light.png)

Each call creates a “Call Frame”, which is pushed to the Stack. A call frame holds metadata on the stack, aiding the execution of the call context in the FuelVM. A call context cannot mutate the caller's state and only access its stack and heap.

<!-- markdownlint-disable MD052 -->
|          bytes          |     type    |   value  |                                  description                                  |
|:-----------------------:|:-----------:|:--------:|:-----------------------------------------------------------------------------:|
| Unwritable area begins. |             |          |                                                                               |
| 32                      | byte[32]    | to       | Contract ID for this call.                                                    |
| 32                      | byte[32]    | asset_id | asset ID of forwarded coins.                                                  |
| 8*64                    | byte[8][64] | regs     | Saved registers from previous context.                                        |
| 8                       | uint64      | codesize | Code size in bytes, padded to the next word boundary.                         |
| 8                       | byte[8]     | param1   | First parameter.                                                              |
| 8                       | byte[8]     | param2   | Second parameter.                                                             |
| 1*                      | byte[]      | code     | Zero-padded to 8-byte alignment, but individual instructions are not aligned. |
|  Unwritable area ends.  |             |          |                                                                               |
| *                       |             |          | Call frame's stack.                                                           |
<!-- markdownlint-enable MD052 -->

After a call context has successfully ended, its call frame is popped from the stack. However, any space allocated on the heap during the execution of the call context persists in memory.

A call context returns its value using the `$ret` and `$retl` registers. Large return values can be written to the heap and later read from the caller contexts.

## Memory Policies

After understanding the various contexts for executing the FuelVM, we now discuss the policies for reading and writing to memory in contexts.

### Read Policies for Context

A context can read any data from the stack in the range from the byte at index `0` (i.e., from the start of the memory ) to the highest ever `$sp` and between the current `$hp` and `VM_MAX_RAM` (i.e., until the end of the memory ) of the previous context that created the current context.

Any attempt to read from the region between the highest ever `$sp` during the context execution and the current `$hp` will return an error.

![2.1 Memory Read Policies](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-memory-read-policies-light.png)

What do we mean by the highest ever `$sp`?

Since the stack can be grown and shrunk in size, it is possible that during the execution of some context, the `$sp` went until, for example, index 1000, but then elements were popped out of the stack, and now the current `$sp` is 900. In this scenario, the highest ever `$sp` during the execution of this call context is 1000, and hence, the memory region until 1000 is readable for the stack!

### Write Policies for Context

A given context can write to any region between its `$ssp` and current `$hp`; hence, that memory region can be allocated and used for writing data.

Before writing to this memory region, allocate the bytes first. In the case of a stack, this is done using `CFE` and `CFEI` opcodes, while in the case of the heap, it is done via `an ALOC` opcode.

![2.1 Memory Write Policies](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.1-memory-write-policies-light.png)

Note: Remember that once a context completes, all values on the stack (i.e., the call frame and all values allocated on the stack during execution ) are wiped down. Still, heap allocation stays, and the following context can only write data below the `$hp` of the existing context.

## VM Initialization & Configuration

### Configuration

The VM can be configured by setting the following parameters:

|          name         |  type  | value |                   note                  |
|:---------------------:|:------:|:-----:|:---------------------------------------:|
| CONTRACT_MAX_SIZE     | uint64 |       | Maximum contract size, in bytes.        |
| VM_MAX_RAM            | uint64 | 2**26 | 64 MiB.                                 |
| MESSAGE_MAX_DATA_SIZE | uint64 |       | Maximum size of message data, in bytes. |

### VM Initialization

This section outlines the process during VM initialization for every VM run.
To initialize the VM, the following pushes to the stack sequentially:

1. Transaction hash (byte[32], word-aligned), computed as defined [here](https://docs.fuel.network/docs/specs/identifiers/transaction-id/).

2. Base asset ID (byte[32], word-aligned)

3. [MAX_INPUTS](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/) pairs of (asset_id: byte[32], balance: uint64), of:

    1. For [predicate estimation](https://docs.fuel.network/docs/specs/fuel-vm/#predicate-estimation) and [predicate verification](https://docs.fuel.network/docs/specs/fuel-vm/#predicate-verification), zeroes.

    2. For [script execution](https://docs.fuel.network/docs/specs/fuel-vm/#script-execution), the free balance for each asset ID seen in the transaction's inputs is ordered in ascending order. If there are fewer than MAX_INPUTS asset IDs, the pair has a zero value.

4. Transaction length, in bytes (uint64, word-aligned).

5. The [transaction, serialized](https://docs.fuel.network/docs/specs/tx-format/).

The following registers are then initialized (without explicit initialization, all registers are initialized to zero):

1. `$ssp = 32 + 32 + MAX_INPUTS*(32+8) + size(tx))`: the writable stack area starts immediately after the serialized transaction in memory (see above).

2. `$sp = $ssp:` writable stack area is empty to start.

3. `$hp = VM_MAX_RAM:` the heap area begins at the top and is empty to start.

## Further Readings

- Nick Dodson’s tweet on what makes FuelVM unique: https://x.com/IAmNickDodson/status/1542516357886988288
- Blockchain Capital’s blog on FuelVM and Sway: https://medium.com/blockchain-capital-blog/exploring-the-fuelvm-86cf9ccdc159
- UTXO Model by River.com: https://river.com/learn/bitcoins-utxo-model/


---

### File: docs/nightly/fuel-book/docs/src/the-architecture/transactions-on-fuel.md

# Transactions on Fuel

Highlights:

- Fuel utilizes the UTXO model for transactions, a method famously employed in the Bitcoin protocol. This method allows for advantages like parallel transaction execution. In this model, addresses can own native assets and spend these coins through transactions.

- There are five distinct categories of transactions in Fuel, classified based on their operations: Script, Create, Mint, Upgrade, and Upload. Categorization helps define the various functionalities that users can perform within the Fuel ecosystem.

- Fuel transactions are composed of several key components: Inputs, Scripts, Outputs, and Witnesses. Inputs consist of state elements that users access during the transaction and can include Coins, Contracts, and Messages.

- The structure of a Fuel transaction allows for the inclusion of smart contracts as inputs, which can maintain persistent storage and can be utilized to execute complex operations beyond simple transactions, unlike the limitations faced by the Bitcoin protocol.

- Witnesses play a crucial role in Fuel transactions by providing digital signatures and verification for spending coins. Block builders fill in these fields and exclude them from the transaction ID, allowing for flexible data handling in transaction processing.

Fuel uses the UTXO model for transactions on its blockchain. The model is popularly used in the Bitcoin protocol and has various advantages, including parallel transaction execution.

In Fuel, addresses can own native assets and spend coins with transactions. Fuel categorizes transactions into five types based on their blockchain operations:

1. Script
2. Create
3. Mint
4. Upgrade
5. Upload

![2.2 Transaction Types](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-types-light.png)

Fuel uses the UTXO model for transactions, introducing specific constructs we'll explore before examining the various transaction types:

- Inputs
- Script
- Outputs
- Witnesses

We'll explore Fuel transaction components in detail before examining individual transaction types.

## Inputs

Fuel transactions use three types of Inputs, which are state elements accessed by users:

1. Coins
2. Contracts
3. Messages

### Coins

Coins are units for some asset that a user can spend as part of the transaction. Fuel natively supports multiple assets, unlike chains that only support one base asset (such as ETH for Ethereum). Asset creation is built into Fuel's protocol. For more details, see the native assets section in the appendix.

Users can own various denominations of certain assets in different numbers of Coins. For example, a Fuel address A can have a balance of some asset 100, with four coins of 25 denominations each, and some address B can have a balance of 100 for the same asset, but three coins of denomination 10, 40, 50.

![2.2 Input Coins](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-input-coins-light.png)

An Input Coin has the following parameters attached:

|         name        |    type   |                     description                     |
|:-------------------:|:---------:|:---------------------------------------------------:|
| txID                | byte[32]  | Hash of transaction.                                |
| outputIndex         | uint16    | Index of transaction output.                        |
| owner               | byte[32]  | Owning address or predicate root.                   |
| amount              | uint64    | Amount of coins.                                    |
| asset_id            | byte[32]  | Asset ID of the coins.                              |
| txPointer           | TXPointer | Points to the TX whose output is being spent.       |
| witnessIndex        | uint16    | Index of witness that authorizes spending the coin. |
| predicateGasUsed    | uint64    | Gas used by predicate.                              |
| predicateLength     | uint64    | Length of predicate, in instructions.               |
| predicateDataLength | uint64    | Length of predicate input data, in bytes.           |
| predicate           | byte[]    | Predicate bytecode.                                 |
| predicateData       | byte[]    | Predicate input data (parameters).                  |

The transaction invalidity rules for this input type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/input/#inputcoin).

### Contracts

A common question about the UTXO model concerns implementing smart contracts beyond ephemeral scripts.

Bitcoin's limited support for complex smart contracts stems from several core issues:

- Bitcoin script is not Turing complete, meaning you cannot do things like loops inside Bitcoin

- Bitcoin scripts in transactions lack persistent storage, limiting the blockchain's functionality.

Many incorrectly attribute Bitcoin's limitations to its UTXO model. However, these constraints stem from deliberate design choices. At Fuel, we embrace the UTXO model while supporting full Turing-complete smart contracts with persistent storage. We solve this problem by making stateful smart contracts an input for Fuel transactions.

Contracts have persistent storage and can own native assets. Users consume contracts by using the contracts as input for transactions. Then, users can call various external functions attached to contracts via the ephemeral script attached to the transaction.

![2.2 Input Contracts](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-input-contracts-light.png)

| name        | type      | description                                                             |
|-------------|-----------|-------------------------------------------------------------------------|
| txID        |  byte[32] | Hash of transaction.                                                    |
| outputIndex | uint16    | Index of transaction output.                                            |
| balanceRoot | byte[32]  | Root of amount of coins owned by contract before transaction execution. |
| stateRoot   | byte[32]  | State root of contract before transaction execution.                    |
| txPointer   | TXPointer | Points to the TX whose output is being spent.                           |
| contractID  | byte[32]  | Contract ID.                                                            |

When signing over contracts, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are initialized to zero values, which the block builder later fills in. This helps avoid concurrency issues with Contracts, as previously seen in the Cardano model.

When interacting with an AMM contract on Fuel, the process follows a specific flow. You begin by including the contract as an input to your transaction. Next, you call the external methods within an ephemeral script. Finally, you emit the contract as an output. This emitted contract can then be consumed as an input for the subsequent transaction involving this particular AMM contract. This approach allows for efficient state management and seamless interaction with the AMM on the Fuel platform.

The transaction invalidity rules for this input type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/input/#inputcontract).

### Messages

The Block Builder creates messages created as part of sending messages from the L1 to the L2. Messages make deposits to the Fuel rollups from the L1 possible, and we will discuss them in better detail later in the Fuel & Ethereum section.

**NOTE:** An Input Message can only be consumed as an Input as part of a transaction, and is then destroyed from the UTXO set.

![2.2 Input Messages](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-input-messages-light.png)

A fuel InputMessage consists of the following parameters:

|         name        |   type   |                       description                       |
|:-------------------:|:--------:|:-------------------------------------------------------:|
| sender              | byte[32] | The address of the message sender.                      |
| recipient           | byte[32] | The address or predicate root of the message recipient. |
| amount              | uint64   | Amount of base asset coins sent with message.           |
| nonce               | byte[32] | The message nonce.                                      |
| witnessIndex        | uint16   | Index of witness that authorizes spending the coin.     |
| predicateGasUsed    | uint64   | Gas used by predicate execution.                        |
| dataLength          | uint64   | Length of message data, in bytes.                       |
| predicateLength     | uint64   | Length of predicate, in instructions.                   |
| predicateDataLength | uint64   | Length of predicate input data, in bytes.               |
| data                | byte[]   | The message data.                                       |
| predicate           | byte[]   | Predicate bytecode.                                     |
| predicateData       | byte[]   | Predicate input data (parameters).                      |

The transaction invalidity rules for this input type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/input/#inputmessage).

## Scripts

Fuel scripts are ephemeral scripts that express the various actions taken during a transaction; a script can call the contracts provided as inputs or perform other arbitrary computation.

Fuel implements multi-call functionality through scripts, enabling efficient batch transactions. This approach allows users to:

1. Provide up to [MAX_INPUTS](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/) contracts in a single transaction

2. Call external methods on these multiple contracts

As mentioned in the FuelVM section, the FuelVM is in the Script Context, scripts cannot have their own persistent storage.

## Outputs

Fuel transactions have Outputs, which define the creation of new UTXOs post-transaction; these Outputs can then be inputs for the next set of transactions.

There are five types of possible Output types in a Fuel transaction:

1. Coin
2. Contract
3. Change
4. Variable
5. ContractCreated

One thing to note is we have three Outputs dealing with Coins, and the table below summarizes the core differences (we will expand more in further sections):

|         | OutputCoin | OutputChange      | OutputVariable         |
|---------|------------|-------------------|------------------------|
| Amount  | Static     | Automatically set | Set by script/contract |
| AssetID | Static     | Static            | Set by script/contract |
| To      | Static     | Static            | Set by script/contract |

**NOTE:** A Coin Output (Coin, Change, Variable) with an amount of zero leads to the pruning of the output from the UTXO set, which means coin outputs of amount zero are not part of the UTXO set.

### OutputCoin

Output Coins are new coins sent to a Fuel Address, which become spendable as Input Coins in further transactions.

|   name   |   type   |              description             |
|:--------:|:--------:|:------------------------------------:|
| to       | byte[32] | Receiving address or predicate root. |
| amount   | uint64   | Amount of coins to send.             |
| asset_id | byte[32] | Asset ID of coins.                   |

![2.2 Output Coins](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-coin-light.png)

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputcoin).

### OutputContract

OutputContracts are newly generated contract outputs that become available as InputContracts for a specific contract ID in subsequent transactions utilizing this contract as an Input. They contain the newly updated index, balanceRoot, and stateRoot of the contract after being processed as part of the transaction.

**NOTE:** Every InputContract part of the transaction must always have a corresponding Output Contract.

![2.2 Output Contract](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-contract-light.png)

|     name    |   type   |                               description                              |
|:-----------:|:--------:|:----------------------------------------------------------------------:|
| inputIndex  | uint16   | Index of input contract.                                               |
| balanceRoot | byte[32] | Root of amount of coins owned by contract after transaction execution. |
| stateRoot   | byte[32] | State root of contract after transaction execution.                    |

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputcontract).

### OutputChange

An OutputChange, included as one of our outputs for a specific assetId, enables the recovery of any unused balance from the total input balance provided in the transaction for that assetId.

For example, an OutputChange can collect any ETH not spent as gas or any USDC not swapped as part of a DEX transaction.

![2.2 Output Change](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-change-light.png)

**NOTE:** There can only be one OutputChange per `asset_id in a transaction`.

|   name   |   type   |              description             |
|:--------:|:--------:|:------------------------------------:|
| to       | byte[32] | Receiving address or predicate root. |
| amount   | uint64   | Amount of coins to send.             |
| asset_id | byte[32] | Asset ID of coins.                   |

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputchange).

### OutputVariable

OutputVariable acts as a placeholder for coins created in the execution of scripts and contracts since they can create a coin of an arbitrary amount and to an arbitrary user. This is useful in scenarios where the exact output amount and owner cannot be determined beforehand.

**NOTE:** This means every transaction using mint internally will need an OutputVariable for that particular assetID.

![2.2 Output Variable](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-output-variable-light.png)

Consider a scenario where a contract transfers its output coin to a user only upon receiving a correct value. In this case, we can utilize a variable output at the end of the transaction. This output may or may not have a value attached to it, depending on whether the condition is met and have an arbitrary owner.

Variable Outputs are used via the [TRO](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/#tro-transfer-coins-to-output) opcode.

|   name   |   type   |              description             |
|:--------:|:--------:|:------------------------------------:|
| to       | byte[32] | Receiving address or predicate root. |
| amount   | uint64   | Amount of coins to send.             |
| asset_id | byte[32] | Asset ID of coins.                   |

The transaction invalidity rules for this output type are available [in our documentation](https://docs.fuel.network/docs/specs/tx-format/output/#outputvariable).

### OutputContractCreated

The `OutputContractCreated` output indicates that a new contract was created as part of the transaction. The parameters include the `contractID` and the initial state root for this contract.

|    name    |   type   |           description           |
|:----------:|:--------:|:-------------------------------:|
| contractID | byte[32] | Contract ID.                    |
| stateRoot  | byte[32] | Initial state root of contract. |

The transaction invalidity rules for this output type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/output/#outputcontractcreated).

## Witness

The witness is a parameter attached to transactions. The block builders fill in witnesses and are not part of the transaction ID. A Witness is usually used to provide digital signatures for verification purposes, for example, the signature to prove the spending of a Coin or anything else.

Witnesses are not part of the transaction ID, which allows someone to sign over a transaction and provide it as part of the transaction.

**NOTE:** The protocol doesn't limit witnesses to providing signatures only; they serve to fill in any data and enable various interesting use cases, like [State Rehydration](../fuels-future/state-rehydration.md).

Each witness contains a byte array data along with the field dataLength helping know the length of this data.

|    name    |   type   |            description            |
|:----------:|:--------:|:---------------------------------:|
| dataLength | uint64   | Length of witness data, in bytes. |
| data       | byte[]   | Witness data.                     |
| asset_id   | byte[32] | Asset ID of coins.                |

Multiple witnesses can be provided as part of the transaction, and the inputs can indicate which witness block builders, contracts, scripts or predicates can look at to verify the validity of being able to spend the input by providing the index at which their witness lives.

## TransactionScript

Script transactions are transactions that, as the name suggests, have Inputs, Outputs, and a Script that dictates what happens as part of the transaction.

Note: Scripts are optional in transactions of type `TransactionScript`. For example, a simple token transfer can work only on inputs and outputs, with no requirement for a script. Scripts are mainly leveraged when you want to do other things as part of your transaction beyond simply transferring or burning assets.

The transaction's script can compute arbitrary amounts and call other contracts. A famous example of script transactions is using an AMM or transferring a token.

|       name       |    type    |               description               |
|:----------------:|:----------:|:---------------------------------------:|
| scriptGasLimit   | uint64     | Gas limits the script execution.        |
| receiptsRoot     | byte[32]   | Merkle root of receipts.                |
| scriptLength     | uint64     | Script length, in instructions.         |
| scriptDataLength | uint64     | Length of script input data, in bytes.  |
| policyTypes      | uint32     | Bitfield of used policy types.          |
| inputsCount      | uint16     | Number of inputs.                       |
| outputsCount     | uint16     | Number of outputs.                      |
| witnessesCount   | uint16     | Number of witnesses.                    |
| script           | byte[]     | Script to execute.                      |
| scriptData       | byte[]     | Script input data (parameters).         |
| policies         | Policy []  | List of policies, sorted by PolicyType. |
| inputs           | Input []   | List of inputs.                         |
| outputs          | Output []  | List of outputs.                        |
| witnesses        | Witness [] | List of witnesses.                      |

**NOTE:** Script transactions lack the ability to create contracts, therefore they cannot produce a ContractCreated output type. For additional transaction invalidity rules, refer to [our documentation](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionscript).

## TransactionCreate

TransactionCreate is used to create new contracts; the parameters allow for contracts with initialized storage slots.

The contract ID of smart contracts on Fuel is calculated deterministically, and the calculation mechanism is referred to [here](https://docs.fuel.network/docs/specs/identifiers/contract-id/).

![2.2 Transaction Create](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-create-light.png)

|         name         |          type          |                    description                    |
|:--------------------:|:----------------------:|:-------------------------------------------------:|
| bytecodeWitnessIndex | uint16                 | Witness index of contract bytecode to create.     |
| salt                 | byte[32]               | Salt.                                             |
| storageSlotsCount    | uint64                 | Number of storage slots to initialize.            |
| policyTypes          | uint32                 | Bitfield of used policy types.                    |
| inputsCount          | uint16                 | Number of inputs.                                 |
| outputsCount         | uint16                 | Number of outputs.                                |
| witnessesCount       | uint16                 | Number of witnesses.                              |
| storageSlots         | (byte[32], byte[32])[] | List of storage slots to initialize (key, value). |
| policies             | Policy []              | List of policies.                                 |
| inputs               | Input []               | List of inputs.                                   |
| outputs              | Output []              | List of outputs.                                  |
| witnesses            | Witness []             | List of witnesses.                                |

The transaction invalidity rules for this transaction type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionscript).

## TransactionMint

The block producer uses this transaction to mint new assets. It doesn’t require a signature. The transaction is currently used to create the block producer's fees. The last transaction in the blocks is a Coinbase transaction, allowing the block producer to collect fees for building the block.

![2.2 Transaction Mint](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-mint-light.png)

|      name      |      type      |                                 description                                |
|:--------------:|:--------------:|:--------------------------------------------------------------------------:|
| txPointer      | TXPointer      | The location of the Mint transaction in the block.                         |
| inputContract  | InputContract  | The contract UTXO that assets are minted to.                               |
| outputContract | OutputContract | The contract UTXO that assets are being minted to.                         |
| mintAmount     | uint64         | The amount of funds minted.                                                |
| mintAssetId    | byte[32]       | The asset IDs corresponding to the minted amount.                          |
| gasPrice       | uint64         | The gas price to be used in calculating all fees for transactions on block |

The transaction invalidity rules for this transaction type can be seen here.

## TransactionUpgrade

The Fuel network employs [consensus parameters](https://docs.fuel.network/docs/specs/tx-format/consensus_parameters/), subject to occasional upgrades. The network's state transition function resides on-chain, allowing privileged addresses to upgrade it when necessary.

Therefore, at any given moment, a TransactionUpgrade might attempt to perform one of the following actions:

- Trying to upgrade the consensus parameters

- Trying to upgrade the state transition function

![2.2 Transaction Upgrade](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-upgrade-light.png)

|      name      |      type      |           description          |
|:--------------:|:--------------:|:------------------------------:|
| upgradePurpose | UpgradePurpose | The purpose of the upgrade.    |
| policyTypes    | uint32         | Bitfield of used policy types. |
| inputsCount    | uint16         | Number of inputs.              |
| outputsCount   | uint16         | Number of outputs.             |
| witnessesCount | uint16         | Number of witnesses.           |
| policies       | Policy []      | List of policies.              |
| inputs         | Input []       | List of inputs.                |
| outputs        | Output []      | List of outputs.               |
| witnesses      | Witness []     | List of witnesses.             |

The transaction invalidity rules for this transaction type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionmint).

## TransactionUpload

Before performing an upgrade, operators must upload the Fuel state transition bytecode to the chain. This requires uploading the bytecode via multiple transactions. TransactionUpload allows us to split the bytecode into multiple subsections and upload each subsection sequentially over multiple transactions.

On successful upload of all subsections, the transaction reaches completion, and the system adopts the new bytecode.

![2.2 Transaction Upload](https://raw.githubusercontent.com/FuelLabs/fuel-book/refs/heads/main/assets/2.2-transaction-upload-light.png)

<!-- markdownlint-disable MD052 -->
|        name       |    type    |                                      description                                      |
|:-----------------:|:----------:|:-------------------------------------------------------------------------------------:|
| root              | byte[32]   | The root of the Merkle tree is created over the bytecode.                             |
| witnessIndex      | uint16     | The witness index of the subsection of the bytecode.                                  |
| subsectionIndex   | uint16     | The index of the subsection of the bytecode.                                          |
| subsectionsNumber | uint16     | The total number of subsections on which bytecode was divided.                        |
| proofSetCount     | uint16     | Number of Merkle nodes in the proof.                                                  |
| policyTypes       | uint32     | Bitfield of used policy types.                                                        |
| inputsCount       | uint16     | Number of inputs.                                                                     |
| outputsCount      | uint16     | Number of outputs.                                                                    |
| witnessesCount    | uint16     | Number of witnesses.                                                                  |
| proofSet          | byte[32][] | The proof set of Merkle nodes to verify the connection of the subsection to the root. |
| policies          | Policy []  | List of policies.                                                                     |
| inputs            | Input []   | List of inputs.                                                                       |
| outputs           | Output []  | List of outputs.                                                                      |
| witnesses         | Witness [] | List of witnesses.                                                                    |
<!-- markdownlint-enable MD052 -->

The transaction invalidity rules for this transaction type can be seen [here](https://docs.fuel.network/docs/specs/tx-format/transaction/#transactionupload).

## Appendix

### Native Assets

In Fuel, apart from Eth (which is called the base asset), the functionality of minting and burning assets is enshrined in the protocol. The FuelVM provides op-codes for creating, minting, and burning assets, [MINT](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/#mint-mint-new-coins) and [BURN](https://docs.fuel.network/docs/specs/fuel-vm/instruction-set/#burn-burn-existing-coins), respectively.

All native assets can be spent using the same rules as the base asset, allowing Fuel developers and users to fully utilize the UTXO model and the resulting parallelization.

To explore Native assets further, it is recommended that you look at [Sway Standards](https://docs.fuel.network/docs/sway-standards/), which provide various standards ( like SRC-3, SRC-20, and many more ) related to native assets.


---

### File: docs/nightly/fuel-book/docs/src/why-fuel/beginnings.md

# Beginnings

A multitude of fragmented solutions—Layer 1s, rollups, DA layers, sequencers—clutter the blockchain landscape today, each striving to scale, decentralize, and power the internet's future. However, execution inefficiencies, unsustainable growth, and security compromises hamper the current array of solutions.

In the race to market, numerous solutions opted to copy and paste existing architectures. Few dared to build from the ground up. Why? Most projects focused on sustaining innovations, making incremental improvements to older frameworks. We took the opposite approach and aimed for disruptive innovation, challenging the status quo with a completely new architectural vision to overcome the limitations others had accepted.

Picture a group of early Ethereum developers, driven by a vision to enhance the performance, sustainability, interoperability, and developer experience of Ethereum. Recognizing the need for a fresh architectural approach to achieve ambitious goals, these devs envisioned a system incorporating years of blockchain evolution while adhering to cypherpunk ideals of decentralization and accessibility.

The blockchain ecosystem has undergone a remarkable transformation since the inception of Bitcoin in 2009. Bitcoin and Ethereum, as pioneering Layer 1 blockchains, established the foundation for decentralized systems, but quickly encountered scalability challenges. In response, alternative L1s offered differing approaches to decentralization, security, and performance. As demand for scalability grew, Ethereum explored modular approaches and various solutions like state channels, plasma, and eventually rollups—Layer 2 solutions that aggregate transactions to improve throughput while leveraging the security of L1s.

Sequencers, integral to rollups, emerged to manage transaction ordering and boost efficiency, forming a critical piece in the evolving blockchain landscape. This wave of innovation also sparked developments in Proposer-Builder Separation (PBS) and other modular solutions that allowed for specialization at various layers of the blockchain stack—execution, settlement, data availability, and consensus—pushing the boundaries of what these networks could achieve.

Despite such advancements, the blockchain landscape still lacks a crucial piece of the puzzle: scalability without compromise. Most solutions sacrifice decentralization for performance, or security for speed, resulting in trade-offs that undermine the core principles of blockchain technology.

Many L1 and L2 solutions boost transaction capacity by increasing node requirements, thus enhancing throughput and cutting latency. This approach, however, shrinks the pool of participants capable of validating and securing the chain.

Similarly, some rollups and sidechains achieve higher speeds by implementing trust assumptions that deviate from the foundational principles of security and decentralization. These solutions may rely on multi-signature schemes or other trust-based models to validate transactions, which introduce vulnerabilities. Users must place their trust in small groups of signers, which can be susceptible to hacking or coordination attacks.

This critical need for a scalable, trustless, and performant system—one that doesn’t trade off on the core principles of blockchain—remains unmet.

We built Fuel to address this critical gap.

In December 2020, Fuel emerged as the first optimistic rollup on Ethereum, with the launch of Fuel V1. We sought to create a trust-minimized sidechain that would inherit the security of Ethereum while introducing a radically redesigned execution model based on UTXOs, or Unspent Transaction Outputs.

Fuel V1 garnered significant attention within the blockchain community from day one. Many regarded Fuel V1 as the one “pure” rollup, primarily due to its approach to security and execution. Unlike other architectures, Fuel V1 demonstrated security inheritance without relying on third-party multi-signatures or sacrificing the integrity of optimistic fraud proofs.

[Vitalik's appreciation for Fuel.](https://x.com/vitalikbuterin/status/1838862177824051712?s=46&t=fyJoiPJn7gE_VIRS05WBaQ)

Fuel V1’s design philosophy set the bar for Ethereum rollups and ultimately, our vision, leading to a more refined architecture in Fuel V2.

Over the past three and a half years, Fuel has evolved significantly, morphing into a new blockchain architecture that thoughtfully addresses the common challenges faced by modern blockchains. Our vision culminated in what we now call Fuel V2, an operating system for rollups—the "Rollup OS." This framework empowers developers to build and customize their own rollups while leveraging the security and robustness of underlying L1s like Ethereum for settlement and access to Ethereum’s vast liquidity and assets.

Imagine Fuel as a robust framework designed to foster the development of sustainable and high-performance rollups, along with novel, advanced applications never before seen in blockchain. By providing this architecture, we empower developers to build innovative, decentralized solutions that push the boundaries of what's possible in the ecosystem.

We envision every application eventually evolving into its own app-chain, with Fuel providing the optimal architecture, tools, and developer experience for that future. Our commitment extends to creating pathways for the community to support millions of innovative app-chains, establishing Fuel as the foundation for the next generation of decentralized applications.

Fuel's narrative interweaves with Bitcoin and Ethereum's histories. Bitcoin's concise yet revolutionary whitepaper sparked a philosophical movement centered on self-sovereignty and cryptographic trust. Ethereum then expanded the horizon, introducing a programmable platform that unleashed developers' creativity and innovation.

Fuel acknowledges these contributions while seeking to fill the gaps left by conventional architectures. As we delve deeper into the intricacies of blockchain technology, we invite you to explore the problems we aim to solve and the vision we aspire to realize. Welcome to the beginnings of Fuel—a journey toward a sustainable, performant, and decentralized future.


---

### File: docs/nightly/fuel-book/docs/src/why-fuel/building-on-fuel-an-overview.md

# Building on Fuel: An Overview

Building on Fuel empowers developers to create high-performance, scalable decentralized applications with cutting-edge tools and infrastructure. Fuel’s architecture prioritizes speed, security, and developer productivity. This section outlines the core components of the Fuel ecosystem. We will explore each component in further detail in [Part 2](../the-architecture/index.md).

## The FuelVM (Fuel Virtual Machine)

The FuelVM incorporates years of blockchain design to bring the Ethereum community a reliable machine architecture built for longevity. It drives the Fuel Network and delivers exceptional performance by processing transactions in parallel. Unlike most blockchain virtual machines like the Ethereum Virtual Machine (EVM), which execute transactions serially, FuelVM handles concurrent processing, dramatically increasing throughput.

The FuelVM draws on a variety of architectures, including RISC-V, ARM ISAs, Bitcoin scripts, and the Ethereum Virtual Machine, to create a low-level execution environment optimized for blockchain use cases. By offering state-minimized facilities like native assets, ephemeral scripting, and spending conditions, it reduces the load on full nodes, improving network sustainability. Developers can avoid the inefficiencies of traditional state-heavy designs and build applications that deliver high performance while keeping the network decentralized and accessible.

As of May 2024, the FuelVM can achieve asset transfer benchmarks of 21,000 transactions per second (TPS) per core on high-end CPUs, offering unparalleled speed for modern blockchain applications.

## The Fuel Transaction Architecture

Fuel’s transaction architecture brings together lessons from Bitcoin, Ethereum, Cosmos, and Solana to create a highly parallel and efficient transaction model. By using a UTXO (Unspent Transaction Output) model, Fuel enables parallel execution both within and across blocks, allowing developers to process transactions quickly without overloading the network.

Fuel transactions are flexible enough to handle everything from simple asset transfers to complex multi-party, multi-asset interactions and batch smart-contract calls. Developers can build sophisticated applications using advanced conditional logic with predicates, reducing the need for state-heavy smart contracts. By minimizing reliance on state, developers can ensure that applications perform efficiently without overburdening network resources.

Fuel’s transaction model also solves concurrency issues seen in other UTXO-based blockchains. This maintains a familiar developer experience for those coming from Ethereum while benefiting from the performance advantages of UTXO-based execution.

## Fuel Ignition (Rollup)

Fuel Ignition will be the first Fuel V2 rollup to go live on Ethereum Mainnet. It aims to surpass traditional EVM rollups by delivering a vastly improved execution design. Initially starting as a more trustful Layer-2, Ignition’s ultimate goal is to evolve into a fully Ethereum-secured rollup with fraud proving, decentralized sequencing, and secure upgrades via a delayed multi-signature process.

Ignition’s focus on leveraging Ethereum’s security ensures that developers can build high-performance applications while benefiting from the strong security guarantees Ethereum offers. As Ignition develops, it will incorporate decentralized sequencing and Ethereum-based data availability (DA), further enhancing its trustless, scalable design.

## The Fuel Network

Fuel operates as a network of interconnected rollups, designed to offer seamless interaction between different blockchains and rollups. Fuel rollups diverge from the copy-paste approach common in many rollup networks. Fuel's customizable VM configurations enable tailoring each network blockchain to developers' specific needs, enhancing adaptability across diverse use cases. Combined with its decentralized block production model, enabled by a shared sequencing and builder network, Fuel provides a fair and efficient system for managing transaction inclusion and interoperation between rollups.

## Developer Tooling

The Fuel project realized early on the importance of thoughtful and considerate developer tooling. We consider developer time one of our community's most important assets and aim to optimize it for building high-value code. To maximize developer productivity and enable the creation of future-proof applications, we created our own suite of tools. These tools streamline building, testing, and deploying decentralized applications, freeing developers to focus on innovation.

**Sway:** Sway is a domain specific language (DSL) for modern blockchain programming which has familiar syntax, grammar and design ideology to Rust while incorporating blockchain specific functionality such as smart contract interface concepts. Sway is inherently designed to save developers time by providing a single programming language for constructing all critical blockchain application components such as: predicates, scripts, smart contracts, libraries, testing, deployment scripting, indexing and more.

Why not Rust or Solidity? Rust, primarily designed as a systems language, heavily bonds to the Low Level Virtual Machine (LLVM) toolchain and lacks focus on the special considerations of blockchain development. Solidity, a powerful language for developing on the Ethereum Virtual Machine, has many known shortcomings. Sway aims to combine the best aspects of both languages, offering developers a familiar yet powerful tool for blockchain development.

Other tools include:

- **Forc (Fuel Orchestrator):** This command-line toolchain serves as the backbone of Fuel development. It supports everything from compiling Sway smart contracts to managing dependencies and deploying applications. Forc simplifies the entire development process, ensuring that developers can build robust dApps with ease.

- **Fuel Rust SDK:** The Rust SDK allows developers to interact with Fuel’s blockchain using the Rust programming language. It offers a seamless experience for creating system-level applications and managing interactions with the Fuel Network.

- **Fuel Wallet SDK:** The Fuel Wallet SDK provides developers with the tools to create secure, user-friendly wallets that natively interact with the Fuel ecosystem. It ensures developers can easily build wallets that integrate into decentralized applications.

- **Fuel Typescript SDK:** The Typescript SDK allows developers to integrate Fuel into web applications, simplifying interaction with the Fuel blockchain and enabling frontend developers to build decentralized applications that connect with Fuel’s infrastructure.


---

### File: docs/nightly/fuel-book/docs/src/why-fuel/index.md

# Chapter 1 - Why Fuel?

- [1.1 - Beginnings](./beginnings.md)
- [1.2 - The Problem](./the-problem.md)
- [1.3 - The Fuel Way](./the-fuel-way.md)
- [1.4 - So, What is Fuel?](./what-is-fuel.md)
- [1.5 - Building on Fuel: An Overview](./building-on-fuel-an-overview.md)


---

### File: docs/nightly/fuel-book/docs/src/why-fuel/the-fuel-way.md

# The Fuel Way

Blockchains have largely followed Ethereum's evolutionary path since its launch.

Subsequent chains tout increased speed, scalability, power, and usability. They implement novel consensus mechanisms, databases, and ZK proving systems.

Despite these innovations, the core system remains largely unchanged: developers craft smart contracts for applications and assets (typically in Solidity or Rust). Users rely on centralized servers to read on-chain data and interact by signing messages with a standard private key, then routing these signed messages back through the same centralized servers.

Fuel charts a new course for the blockchain industry, prioritizing decentralization at its core. We're not just iterating; we're rebuilding blockchain architecture from the ground up.

## Decentralized… Sustainably Decentralized

Blockchains fundamentally consist of a network of distributed nodes, all validating new blocks and transactions. The ability for independent, distributed and unqualified actors to participate in this process is what gives blockchains their valuable properties of liveness, censorship resistance and verifiability.

Bitcoin continues to take the most principled stance on maintaining these properties. The low node requirements and low bandwidth usage mean that Bitcoin full nodes can be run on devices as light as Raspberry Pis, and in locations as remote as outer space.

However, subsequent blockchains have all made ongoing compromises. Most newer blockchains today (including most layer-2s) can only be run on high-powered servers with data-center connections. And some high throughput projects remove the key cryptographic primitives of verifiability, such as the merkelization of state elements.

Fuel aims to pull the blockchain space back from this creeping centralization, back towards the values of Bitcoin. The Fuel architecture allows for high performance, while still running on consumer hardware. Fuel always maintains the property of cryptographic verifiability, allowing users to check the state of the chain without trusting third parties.

## Blockchains are not Computers

Advancing blockchain technology demands more than incremental upgrades. True innovation often requires revolutionary action– including breaking changes. Fuel envisions revolutionizing both blockchain architecture and application development to unlock the technology's full potential.Traditional smart-contract platforms mimic computer systems, with blockchains serving as hardware and smart contracts as software. These contracts execute read and write operations, storing data to the chain's state—effectively treating it as a global Postgres database.

Fuel believes that blockchains are not simply scaled-up abstract mainframes but a different kind of computer—"trust machines." These machines are still programmable, but they operate under vastly different constraints than traditional execution environments. The role of a blockchain node is not to act as a cloud server but to verify the current state of the chain and all future state transitions with trustless integrity.

Moving computation off blockchain full nodes and shifting data outside of the blockchain’s state keep full node requirements low, allowing blockchains to scale without centralizing. Fuel enables developers to build smart applications without smart contracts, simplifying development while maintaining the decentralized ethos of blockchain technology.

## ZK Pragmatism

Zero-knowledge technology has captured the imagination of researchers and developers from across the blockchain industry. The promise of succinct verification for arbitrary computation has opened up a whole new range of possibilities for scaling blockchains, making them verifiable, interoperable, and more. The thesis of building the future of ZK-powered blockchain tech has driven some of the most anticipated and well-funded projects in this space.

Fuel adopts a pragmatic approach to zero-knowledge (ZK) technology while recognizing its groundbreaking potential within and beyond blockchains. We share the industry's excitement about these new primitives and are actively integrating ZK technology into the Fuel stack  (such as in Fuel’s hybrid-proving model and with the service chain’s ZK-powered bridge).

Fuel asserts that blockchain security, high performance, and interoperability should not hinge on ZK technology alone. Fuel pioneered the first optimistic rollup on Ethereum, diverging from the prevalent focus on ZK rollups among Ethereum scaling solutions. Fuel maintains that full ZK-verification cannot sustainably meet the market's stringent cost and performance demands.Proof generation costs and time constraints render fully ZK-proven chains incompatible with both cost-effectiveness and high-speed operations. Sustainable proofs and 'real-time proving' typically rely on ZK-specific hardware, which faces numerous production-readiness hurdles.

Fuel crafts cutting-edge blockchain technology, selectively integrating off-the-shelf ZK solutions to enhance its stack. The rise of generalized ZK-VMs like RISC Zero and Succinct’s SP-1 point to a future where ZK technology is commodified and easily available without the need for directly handling the necessary cryptography.


---

### File: docs/nightly/fuel-book/docs/src/why-fuel/the-problem.md

# The Problem

The blockchain landscape has advanced rapidly, but key issues still limit decentralized technology’s potential. Fuel is designed to address these fundamental challenges head-on. To understand its significance, we must first examine the core problems that blockchains face today.

## The Performance Bottleneck

Performance can be measured in various ways, such as speed to finality, total execution load capacity, transactions per second and cost-efficiency. However, traditional networks like Ethereum struggle to scale efficiently across these aspects.

One of the critical issues is load. Ethereum's computation overhead limits its processing capacity, restricting the number of transactions per second (TPS), compute units per gas unit, and overall execution capacity. Proving cryptographic evidence of transactions consumes much of this computation. The EVM, for instance, bears a significant cryptographic burden as it verifies and updates the state tree after every transaction. Ethereum's execution layer compounds this inefficiency by poorly optimizing for the underlying hardware, creating unnecessary computational overhead.

Sequential execution of these computations further constraints throughput.If you remove the state tree and focus solely on EVM computation, Ethereum could potentially achieve up to 10,000 TPS. However, the real bottleneck comes from the execution side and the cryptographic evidence required for state verification. Fuel addresses this by removing the need for a state tree and enabling computations to run in parallel, dramatically increasing efficiency. Fuel not only makes execution more efficient but also allows it to scale horizontally, making the system far more accessible to users without driving up costs or limiting throughput.

Cost-efficiency remains a problem. Ethereum's transaction costs fluctuate often, spiking to inaccessible heights during congestion. This unpredictability harms both developers and users, constraining the types of applications they can scale.

## The Scalability Dilemma

Many blockchain projects attempt to achieve scalability by increasing the hardware requirements for their nodes. This approach often makes it more expensive for users to participate, sidelining smaller users and compromising decentralization. Scalability demands more than incremental improvements. It requires fundamental changes to transaction and block processing that enhance efficiency without escalating the network's computational burden.

Early blockchains like Ethereum process transactions sequentially, executing one after another. This linear model severely limits performance on modern multi-core processors designed for parallel processing.

Parallelism, or the ability to process multiple transactions simultaneously, is one of the most promising solutions for blockchain scalability. However, enabling parallel transaction execution requires careful management of state access. If two transactions try to access the same state (for instance, attempting to spend the same funds), they can’t be processed in parallel. This leads to complex mechanisms in many blockchains that either attempt to predict state conflicts or reprocess conflicting transactions.

Fuel addresses these issues by adopting the UTXO model instead of Ethereum’s account-based model. In this model, every transaction defines its own state in the form of unspent transaction outputs, eliminating the risk of conflicting state access. As a result, Fuel can safely parallelize transaction execution, dramatically increasing throughput without compromising security. For developers, this complexity is abstracted away, allowing them to build seamlessly without needing to manage UTXOs directly.

Fuel's architecture introduces stateless primitives called predicates, enhancing efficiency and simplifying state management.This statelessness allows predicates to be trivially processed in parallel, enabling a high degree of concurrency in transaction execution. Predicates facilitate the execution of multiple operations within a single transaction while ensuring that conflicts with other transactions are avoided. Predicates don’t maintain state information between executions, enabling efficient parallel processing and significantly boosting throughput. Fuel's unique architecture enables critical performance gains, powering scalable real-world decentralized applications.

## State Growth and Sustainability

Blockchain growth inflates state size. State encompasses a blockchain's stored data: account balances, smart contract bytecode, and dApp interactions. Unchecked state growth explodes exponentially, threatening system stability. Every new transaction adds more data, and this accumulation increases the burden on node operators. As the state becomes larger, nodes must store and manage increasingly extensive amounts of data, leading to higher hardware requirements and potentially threatening decentralization.

Ethereum is currently grappling with state bloat, which many core developers consider the network’s most pressing scaling issues. As the state grows, nodes must store increasingly large amounts of data, which increases hardware requirements. The ecosystem continually explores possible solutions, such as statelessness and state expiry, but has yet to fully implement any. Ethereum's backwards compatibility limits radical innovation, while Fuel's flexibility enables more flexibility and scalable solutions.

Fuel directly addresses state growth by minimizing unnecessary data accumulation. It discourages excessive state use with op code pricing, pushing developers to optimize their applications. By streamlining data storage and management, Fuel reduces the state nodes must maintain, easing the load on operators. Its architecture efficiently handles data, ensuring the state remains manageable as transactions are processed. Our approach preserves decentralization and accessibility, allowing the network to scale without encountering the challenges of unchecked state growth.

## Interoperability and Fragmentation

Another major problem in today’s multi-chain world is interoperability. Ethereum's unified state machine succeeds largely by enabling application composition, universal asset access, and seamless dApp interactions. However, Ethereum's congestion has driven users to migrate to other L1s and L2s, fragmenting the ecosystem. Each new chain comes with its own set of challenges, including the need for separate wallets, token bridges, and onboarding processes.

Fuel is designed to reunite the fragmented ecosystem with a focus on interoperability at its core. Despite concerns about short-term fragmentation, Fuel's new VM and toolset aim to reduce ecosystem division long-term. Unlike most rollup projects, Fuel is not constrained by the EVM. Its flexible architecture enables innovative design choices for seamless interactions across multiple chains while maintaining full Ethereum compatibility. Fuel’s transaction model and block design simplify cross-chain integrations, making the movement of assets and data between chains easier to manage.

Fuel's proposed shared sequencer design prioritizes speed and efficiency, rapidly processing cross-chain transactions. Our fast sequencing empowers developers to build versatile, low-latency cross-chain applications, mitigating typical multi-chain fragmentation.

Fuel’s unique transaction and block architecture further enhances interoperability by providing execution evidence in the form of receipt roots and smart contract state roots. Verifiable proofs facilitate inter-chain interactions with Fuel, enhancing user experience and cross-chain fluidity.

## The Future: A Modular, Decentralized World

Performance limitations, poor scalability, unsustainable state growth, and minimal interoperability plague the current blockchain landscape. These issues threaten blockchain decentralization and constrain thriving applications. Fuel's innovations—UTXO-based parallelism, modular architecture, and cross-chain capabilities—overcome these limitations, setting a new blockchain infrastructure standard.


---

### File: docs/nightly/fuel-book/docs/src/why-fuel/what-is-fuel.md

# So What is Fuel?

Fuel is a next-generation execution layer for Ethereum, designed to offer unparalleled speed, flexibility, and scalability for both developers and users. But what exactly sets Fuel apart from other solutions? And why should you, as a developer, invest your time and energy into learning this architecture?

Fuel embodies a core philosophy of modularity and performance. For developers, Fuel’s appeal lies in both its design philosophy and the tools it offers. Here are a few key reasons why developers should pay attention to Fuel:

1. **Unmatched Parallelization:** Fuel’s unmatched parallelization enables simultaneous transaction processing, allowing significantly higher throughput than many other blockchains. By eliminating serial processing bottlenecks, developers can build scalable, efficient dApps without sacrificing performance. What truly sets Fuel apart is the introduction of predicates, stateless smart accounts that allow transactions to execute in parallel without conflict—something other blockchains struggle to achieve. Combined with the UTXO (Unspent Transaction Output) model, this ensures seamless, concurrent transaction execution, driving scalability to new heights.

2. **Native Assets:** Fuel natively supports a wide variety of assets, but its unique architecture handles them more efficiently. Unlike blockchains that handle only one native asset (like Ethereum's focus on ETH), Fuel enshrines all assets at the protocol level. This means developers don't need to create custom smart contracts for simple asset operations like transfers or balance checks. These operations are built into the system, significantly reducing complexity, time, and the risk of introducing vulnerabilities. Native assets also benefit from performance optimizations, avoiding the overhead of virtual machine processing.

3. **Security and Safety:** Fuel’s architecture eliminates many of the common vulnerabilities seen in smart contract platforms, such as reentrancy attacks. By integrating asset logic into the protocol itself, developers no longer have to rely on third-party contracts or code that could introduce risks. When you transfer tokens or execute other asset-related functions on Fuel, you do so with the assurance that the execution won’t be hijacked by malicious code, significantly enhancing security.

4. **Developer-Friendly Tooling:** Fuel offers an integrated, developer-friendly environment that makes building on its platform easier. Whether you're a seasoned blockchain developer or new to the space, Fuel provides a robust set of tools to support your development process. The Sway programming language, specifically designed for FuelVM, ensures that you’re writing optimized and secure smart contracts. In addition, Fuel’s native development kits (like Forc, the Fuel SDK, and Wallet SDK) make it easy to deploy, test, and manage decentralized applications.

5. **Future-Proof Design:** The blockchain space evolves rapidly, but Fuel is built to grow alongside it. Its modular design allows for the easy adoption of future innovations, whether in virtual machine improvements, consensus upgrades, data availability solutions or ZK. This flexibility ensures that Fuel can adapt to whatever comes next without developers having to constantly rework their applications.


---

### File: docs/nightly/fuel-graphql-docs/docs/how-to-use-graphql.md


# How To Use GraphQL

This section covers the fundamentals for how to use a GraphQL API.

For further documentation and resources about GraphQL, check out the official GraphQL Documentation at [graphql.org](https://graphql.org/).


---

### File: docs/nightly/fuel-graphql-docs/docs/how-to-use-graphql/apis-explained.md


# Schema & Type System

Unlike traditional REST APIs, GraphQL comes with a strong type system to describe your API. A GraphQL schema describes the data you can query using the API endpoint by defining a set of types and fields that are mapped to those types.

Read along to learn about various GraphQL types.

## Object Types

Object types in GraphQL describe an object with underlying fields that can be queried from your API endpoint.

As an example, an object type can be defined as shown below:

```graphql
type actors {
  name: String!
  appearsIn: [movie!]!
}
```

Here,`actors` is an object type and `name` and `appearsIn` are fields mapped to type `actors`.

## Scalar Types

> From The GraphQL Documentation:

In the example for object types above, field `name` is of type `String`. String in GraphQL is by default a scalar type. This means that it resolves to a definite value and cannot have further sub-fields while querying. Scalar types represent the leaves of a query.

GraphQL comes with a set of default scalar types out-of-the-box such as below:

- `Int`: A signed 32‐bit integer.
- `Float`: A signed double-precision floating-point value.
- `String`: A UTF‐8 character sequence.
- `Boolean`: true or false.
- `ID`: The ID scalar type represents a unique identifier, often used to re-fetch an object or as the key for a cache. The ID type is serialized in the same way as a String; however, defining it as an ID signifies that it is not intended to be human‐readable.

Fields can also be of types that are not scalar by default, but resolve to scalar values upon querying. For instance, in the following query, the `name` and `appearsIn` fields resolve to scalar types.

```graphql
{
  hero {
    name
    appearsIn
  }
}
```

This is because in the schema, `name` and `appearIn` do not have further queryable sub-fields as described below:

```graphql
{
 "data": {
   "hero": {
     "name": "R2-D2",
     "appearsIn": [
       "NEWHOPE",
       "EMPIRE",
       "JEDI"
     ]
   }
 }
}
```

## Lists and Non-nulls

> From the GraphQL documentation:

Object types, scalars, and enums are the only kinds of types you can define in GraphQL. But when you use the types in other parts of the schema, or in your query variable declarations, you can apply additional type modifiers that affect validation of those values.

Let's look at an example:

```graphql
type Character {
  name: String!
  appearsIn: [Episode]!
}
```

Here, we're using a String type and marking it as Non-Null by adding an exclamation mark `!` after the type name. This means that our server always expects to return a non-null value for this field, and if it ends up getting a null value that will actually trigger a GraphQL execution error, letting the client know that something has gone wrong.

The Non-Null type modifier can also be used when defining arguments for a field, causing the GraphQL server to return a validation error if a null value is passed either in the GraphQL string or the variables.

```graphql
query DroidById($id: ID!) {
 droid(id: $id) {
   name
 }
}
{
 "id": null
}
```

```graphql
{
 "errors": [
   {
     "message": "Variable \"$id\" of non-null type \"ID!\" must not be null.",
     "locations": [
       {
         "line": 1,
         "column": 17
       }
     ]
   }
 ]
}
```

```graphql
myField: [String!]
```

This means that the list itself can be null, but it can't have any null members. For example, in JSON:

```json
myField: null // valid
myField: [] // valid
myField: ['a', 'b'] // valid
myField: ['a', null, 'b'] // error

```

## Union types

When a query returns a union type, you can use `... on` to specify the query fields for a certain return type. These are also called inline fragments. For example, the `hero` query below returns a union type of either `Droid` or `Human`.

```graphql
query HeroForEpisode($ep: Episode!) {
  hero(episode: $ep) {
    name
    ... on Droid {
      primaryFunction
    }
    ... on Human {
      height
    }
  }
}
```

## Connections

Connections are a type of response used whenever you are expecting multiple results that may require pagination. Each query return type that ends in "Connection" will include the following return fields:

```graphql
pageInfo: PageInfo!
edges: [SomethingEdge!]!
nodes: [Something!]!
```

### `PageInfo`

`pageInfo` returns an object that includes information about the returned page of results:

`hasPreviousPage: Boolean!`
Whether or not the result has a previous page.

`hasNextPage: Boolean!`
Whether or not the result has another page after it.

`startCursor: String`
The starting cursor that identifies the first page.

`endCursor: String`
The end cursor that identifies the last page.

### Edges

`edges` returns an array of edge objects, which includes the cursor and first node for that page. You can use this data to help with pagination.

### Nodes

`nodes` returns an array of whichever type you are expecting paginated results for.

### Arguments

Each of these queries also accepts the following arguments:
`first: Int`
`after: String`
`last: Int`
`before: String`

`first` and `last` both accept an integer, which sets the number of results returned for each page. `first` will paginate the results starting at the beginning, while `last` will start from the end. It is required to pass an argument for either `first` or `last`. If no argument is given, the query will not return any results.

`after` and `before` both accept a cursor, which you can use to request different pages. These are both optional arguments.

You can learn more about the connection model and pagination in the official GraphQL docs here: https://graphql.org/learn/pagination/


---

### File: docs/nightly/fuel-graphql-docs/docs/how-to-use-graphql/what-is-graphql.md


# What is GraphQL?

## HTTP and APIs Explained

HTTP is a protocol, or a definite set of rules, for accessing resources on the web. Resources could mean anything from HTML files to data from a database, photos, text, and so on.

These resources are made available to us via an Application Programming Interface (API) and we make requests to these APIs via the HTTP protocol. It is the mechanism that allows developers to request resources.

Read more about HTTP methods, client-server architecture, and why you need APIs [here](https://www.freecodecamp.org/news/http-request-methods-explained/).

## How does GraphQL work?

> Note: This section goes over how GraphQL works under the hood, but it is not necessary to know this as a developer building on Fuel. Schema definition, resolver logic, etc. are all written and maintained by the contributors at Fuel Labs.

GraphQL is a query language and specification that describes how you can communicate with your API. GraphQL is not constrained by programming languages, backend frameworks, and databases. GraphQL uses the HTTP protocol under the hood, so you can map GraphQL operations back to simple `GET`, `POST`, `PUT`, or `DELETE` operations. You can view the GraphQL documentation here: https://graphql.org/.

A GraphQL API works by defining types and the properties available on those types, also known as the schema, and defining functions that specify the logic for how to resolve those types. A resolver is a function that's responsible for populating the data for a single field in your schema. Whenever a client queries for a particular field, the resolver for that field fetches the requested data from the appropriate data source.

For example, as an API developer you could define a type, `Car` and define the properties that will be query-able on that type such as below:

```graphql
type Car {
  id: ID
  color: String
  year: Int
  isNew: Boolean
}
```

Fuel Labs created a GraphQL API endpoint for the Fuel Network, allowing developers to make complex queries for data on the blockchain. You can leverage these queries to populate a frontend application with details that your users might be interested in like the history of their transactions, their balance of a specific token, etc.

### GraphQL Queries

Queries in GraphQL allow you to read data. GraphQL lets you ask for specific data and returns exactly what you asked for. It also lets you request multiple resources in a single query instead of writing a separate 'GET' request for each resource as with REST APIs.

GraphQL also facilitates more complex queries and operations such as pagination, sort, filter, full-text search, and more.

Sample query:

```graphql
query Actor {
  actor {
    name {
      appearIn
    }
  }
}
```

The above query gives you a response with the name of the actor along with the name of the movie(s) they appear in.

### GraphQL Mutations

Mutations in GraphQL are write operations that update the chain's state. In addition to being able to traverse objects and their fields, GraphQL gives developers the ability to pass arguments to fields in order to filter out responses. Every field and nested object can have its own set of arguments.

Sample mutation:

```graphql
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}
```


---

### File: docs/nightly/fuel-graphql-docs/docs/overview.md


# Overview

## Introduction to the Fuel GraphQL API

The Fuel GraphQL API allows you to query the Fuel blockchain for a wide range of on-chain data. It can be used to query transactions, balances, block information, and more. You can also use it to simulate and submit transactions on the Fuel network.

## GraphQL Playground

The playground is an interactive and graphical IDE that includes a reference for queries, mutations, and types. It also provides query validation and context for the underlying GraphQL schema.

You can test out the Fuel GraphQL API playground here:

**Testnet**: https://testnet.fuel.network/v1/playground

**Mainnet**: https://mainnet.fuel.network/v1/playground

## RPC Endpoints

Here is a list of public RPC endpoints you can use to interact with Fuel, whether it's retrieving on-chain data or sending transactions.

| **Provider**                                            | **Testnet**                                                | **Mainnet**                                                |
|---------------------------------------------------------|------------------------------------------------------------|------------------------------------------------------------|
| [Ankr](https://www.ankr.com/web3-api/chains-list/fuel/) | `https://rpc.ankr.com/http/fuel_sepolia`                   | `https://rpc.ankr.com/http/fuel`                           |
| Fuel                                                    | `https://testnet.fuel.network/v1/graphql`                  | `https://mainnet.fuel.network/v1/graphql`                  |
| [QuickNode](https://www.quicknode.com/chains/fuel)      | `https://fuel-public.fuel-sepolia.quiknode.pro/v1/graphql` | `https://fuel-public.fuel-mainnet.quiknode.pro/v1/graphql` |

> Note: The above endpoints are provided on a best effort basis. If you are running a commercial project, we highly recommend creating an account with one of the providers above to get enhanced support and rate limits.

## Chain Id

A chain ID is a unique identifier assigned to a blockchain network, whether a testnet or a mainnet (Fuel Ignition), to ensure correct transaction signing and prevent replay attacks across chains.

**Testnet**: [`0`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition-test/chain_config.json#L41)

**Mainnet**: [`9889`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition/chain_config.json#L41)


---

### File: docs/nightly/fuel-graphql-docs/docs/querying-from-a-dapp.md


# Querying From A Dapp

There are several ways to interact with the Fuel GraphQL API from a frontend application.
This section covers just a few options available to get you started.

## JavaScript

```javascript
export async function getHealth() {
  let response = await fetch(TESTNET_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
    },
    body: JSON.stringify({ query: '{ health }' }),
  });
  let data = await response.json();
  console.log('DATA:', data);
}
```

## Apollo Client

Read the official Apollo Client docs [here](https://www.apollographql.com/apollo-client/).

```bash
npm install @apollo/client graphql
```

```javascript
import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

const apolloClient = new ApolloClient({
  uri: TESTNET_ENDPOINT,
  cache: new InMemoryCache(),
});

const HEALTH_QUERY = `
  query {
    health
  }
`;

export const checkHealth = async () => {
  const response = await apolloClient.query({
    query: gql(HEALTH_QUERY),
  });
  console.log('RESPONSE:', response);
};
```

## urql

Read the official urql docs [here](https://formidable.com/open-source/urql/).

```bash
npm install urql graphql
```

```javascript
import { Client, cacheExchange, fetchExchange } from 'urql';

const urqlClient = new Client({
  url: TESTNET_ENDPOINT,
  exchanges: [cacheExchange, fetchExchange],
});

const HEALTH_QUERY = `
  query {
    health
  }
`;

export const checkHealth = async () => {
  const response = await urqlClient.query(HEALTH_QUERY).toPromise();
  console.log('RESPONSE:', response);
};
```

You can see more examples in the next section.


---

### File: docs/nightly/fuel-graphql-docs/docs/recipes.md


# Recipes

You can see and test the example queries and mutations below.
Click the "Run" button to run the query above it and see the response.
Click the "TypeScript", "Apollo Client", or "urql" buttons to see code examples.

- [Get an asset balance of an address](#get-an-asset-balance-of-an-address)
- [List all asset balances of an address](#list-all-asset-balances-of-an-address)
- [List all transactions from an address](#list-all-transactions-from-an-address)
- [List the latest transactions](#list-the-latest-transactions)
- [Get an asset balance of a contract](#get-an-asset-balance-of-a-contract)
- [List all asset balances of a contract](#list-all-asset-balances-of-a-contract)
- [List the latest blocks](#list-the-latest-blocks)
- [Get block information by height](#get-block-information-by-height)
- [List all messages owned by address](#list-all-messages-owned-by-address)
- [Dry run a transaction](#dry-run-a-transaction)
- [Submit a transaction](#submit-a-transaction)
- [More Examples](#more-examples)

## Get an asset balance of an address

<GQLExamples.Balance />

<CodeExamples
  file="../examples/tests/balance.test.ts"
  ts_testCase="get balance with ts"
  apollo_testCase="get balance with apollo"
  urql_testCase="get balance with urql"
/>

## List all asset balances of an address

<GQLExamples.Balances />

<CodeExamples
  file="../examples/tests/balances.test.ts"
  ts_testCase="get balances with ts"
  apollo_testCase="get balances with apollo"
  urql_testCase="get balances with urql"
/>

## List all transactions from an address

<GQLExamples.Transactions />

<CodeExamples
  file="../examples/tests/transactions-by-owner.test.ts"
  ts_testCase="get transactions with ts"
  apollo_testCase="get transactions with apollo"
  urql_testCase="get transactions with urql"
/>

## List the latest transactions

<GQLExamples.LatestTransactions />

<CodeExamples
  file="../examples/tests/latest-transactions.test.ts"
  ts_testCase="get latest transactions with ts"
  apollo_testCase="get latest transactions with apollo"
  urql_testCase="get latest transactions with urql"
/>

## Get an asset balance of a contract

<GQLExamples.ContractBalance />

<CodeExamples
  file="../examples/tests/contract-balance.test.ts"
  ts_testCase="get contract balance with ts"
  apollo_testCase="get contract balance with apollo"
  urql_testCase="get contract balance with urql"
/>

## List all asset balances of a contract

<GQLExamples.ContractBalances />

<CodeExamples
  file="../examples/tests/contract-balances.test.ts"
  ts_testCase="get contract balances with ts"
  apollo_testCase="get contract balances with apollo"
  urql_testCase="get contract balances with urql"
/>

## List the latest blocks

<GQLExamples.LatestBlocks />

<CodeExamples
  file="../examples/tests/latest-blocks.test.ts"
  ts_testCase="get latest blocks with ts"
  apollo_testCase="get latest blocks with apollo"
  urql_testCase="get latest blocks with urql"
/>

## Get block information by height

<GQLExamples.BlockByHeight />

<CodeExamples
  file="../examples/tests/block.test.ts"
  ts_testCase="get block info with ts"
  apollo_testCase="get block info with apollo"
  urql_testCase="get block info with urql"
/>

## List all messages owned by address

<GQLExamples.MessageInfo />

<CodeExamples
  file="../examples/tests/messages.test.ts"
  ts_testCase="get messages with ts"
  apollo_testCase="get messages with apollo"
  urql_testCase="get messages with urql"
/>

## Dry run a transaction

```graphql
mutation DryRun($encodedTransaction: HexString!, $utxoValidation: Boolean) {
  dryRun(tx: $encodedTransaction, utxoValidation: $utxoValidation) {
    receiptType
    data
  }
}
```

## Submit a transaction

```graphql
mutation submit($encodedTransaction: HexString!) {
  submit(tx: $encodedTransaction) {
    id
  }
}
```

## More Examples

You can find more examples of how we use this API in our GitHub:

[Fuels Typescript SDK](https://github.com/FuelLabs/fuels-ts/)

[Fuels Rust SDK](https://github.com/FuelLabs/fuels-rs/)


---

### File: docs/nightly/fuel-graphql-docs/docs/reference.md


# Reference

The reference provides more information about the types, queries, and mutations used in the Fuel GraphQL API.

- [Scalars](/docs/reference/scalars/)

- [Enums](/docs/reference/enums/)

- [Unions](/docs/reference/unions/)

- [Objects](/docs/reference/objects/)

- [Queries](/docs/reference/queries/)

- [Mutations](/docs/reference/mutations/)

- [Subscriptions](/docs/reference/subscriptions/)


---

### File: docs/nightly/fuel-graphql-docs/docs/reference/enums.md


# Enums

## `BlockVersion`

The version of the block.

`V1`:
Version 1.

## `ConsensusParametersVersion`

The version of the consensus parameters.

`V1`:
Version 1.

## `ContractParametersVersion`

The version of the contract-specific consensus parameters.

`V1`:
Version 1.

## `FeeParametersVersion`

The version of the fee-specific consensus parameters.

`V1`:
Version 1.

## `GasCostsVersion`

The version of the gas-specific consensus parameters.

`V1`:
Version 1.

## `HeaderVersion`

The version of the header.

`V1`:
Version 1.

## `MessageState`

The state of a message, either `UNSPENT`, `SPENT`, or `NOT_FOUND`.

`UNSPENT`:
The message is unspent.

`SPENT`:
The message is spent.

`NOT_FOUND`:
The message was not found.

## `ReceiptType`

The receipt type indicating what kind of transaction generated the receipt.

`CALL`:
The receipt was generated from a contract call.

`RETURN`:
The receipt was generated from a transaction that returned without data.

`RETURN_DATA`:
The receipt was generated from a transaction that returned data.

`PANIC`:
The receipt was generated from a failed contract call that panicked.

`REVERT`:
The receipt was generated from a failed contract call that reverted.

`LOG`:
The receipt was generated from a log in the contract. The Log receipt is generated for non-reference types, namely `bool`, `u8`, `u16`, `u32`, and `u64`.

`LOG_DATA`:
The receipt was generated from a log in the contract. `LogData` is generated for reference types which include all types except for the non_reference types mentioned above.

`TRANSFER`:
The receipt was generated from a transaction that transferred coins to a contract.

`TRANSFER_OUT`:
The receipt was generated from a transaction that transferred coins to an address (rather than a contract).

`SCRIPT_RESULT`:
The receipt was generated from a script.

`MESSAGE_OUT`:
The receipt was generated from a message.

`MINT`:
The receipt was generated from a mint.

`BURN`:
The receipt was generated from a burn.

## `PredicateParametersVersion`

The version of the predicate-specific consensus parameters.

`V1`:
Version 1.

## `ReturnType`

The type of return response for a transaction

`RETURN`:
Indicates the transaction returned without any data.

`RETURN_DATA`:
Indicates the transaction returned some data.

`REVERT`:
Indicates the transaction reverted.

## `RunState`

The state of a [`RunResult`](/docs/reference/objects/#runresult).

`COMPLETED`:
All breakpoints have been processed, and the program has terminated.

`BREAKPOINT`:
The program stopped on a breakpoint.

## `ScriptParametersVersion`

The version of the script-specific consensus parameters.

`V1`:
Version 1.

## `TxParametersVersion`

The version of the transaction-specific consensus parameters.

`V1`:
Version 1.


---

### File: docs/nightly/fuel-graphql-docs/docs/reference/mutations.md


# Mutations

## `startSession`

Initialize a new debugger session, returning its `ID`.
A new VM instance is spawned for each session.
The session is run in a separate database transaction,
on top of the most recent node state.

## `endSession`

End a debugger session.
Returns a `Boolean!` indicating whether the session was successfully ended.

**args:**

`id`: `ID!`

The session ID.

## `reset`

Reset the VM instance to the initial state.
Returns a `Boolean!` indicating whether the VM instance was successfully reset.

**args:**

`id`: `ID!`

The session ID.

## `execute`

Execute a single `fuel-asm` instruction.
Returns a `Boolean!` indicating whether the instruction was successfully executed.

**args:**

`id`: `ID!`

The session ID.

`op`: `String!`

The `fuel-asm` instruction to execute.

## `setSingleStepping`

Set single-stepping mode for the VM instance.
Returns a `Boolean!` indicating whether the mutation successfully executed.

**args:**

`id`: `ID!`

The session ID.

`enable`: `boolean`

Whether to enable single-stepping mode.

## `setBreakpoint`

Set a breakpoint for a VM instance.
Returns a `Boolean!` indicating whether the breakpoint was successfully set.

**args:**

`id`: `ID!`

The session ID.

`breakpoint`: [`Breakpoint!`](/docs/reference/objects/#breakpoint)

The breakpoint to set.

## `startTx`

Run a single transaction in given session until it hits a breakpoint or completes.
Returns a `RunResult!`.

**args:**

`id`: `ID!`

The session ID.

`txJson`: `String!`

The transaction JSON string.

## `continueTx`

Resume execution of the VM instance after a breakpoint.
Runs until the next breakpoint or until the transaction completes.
Returns a `RunResult!`.

**args:**

`id`: `ID!`

The session ID.

## `dryRun`

Spin up a new temporary node from the current state and emulate a given transaction or set of transactions.
Returns a [`[Receipt!]!`](/docs/reference/objects/#receipt) for the emulated transaction.
You can optionally use UTXO validation.

**args:**

`txs`: [`[HexString!]!`](/docs/reference/scalars/#hexstring)

An array of transaction hex strings.

`utxoValidation`: `Boolean`

Whether or not to use UTXO validation.

`gasPrice`: [`U64!`](/docs/reference/scalars/#u64)

The gas price for the multiple transactions ran during the dry run.

## `produceBlocks`

Produce blocks that can be used for testing that requires block advancement.
Returns a [`U32!`](/docs/reference/scalars/#u32).

**args:**

`startTimestamp`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The start time of the produced block.

`blocksToProduce`: [`U64!`](/docs/reference/scalars/#u64)

The number of blocks to produce.

## `submit`

Submit a transaction to the transaction pool.
Returns a [`Transaction!`](/docs/reference/objects/#transaction).

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.


---

### File: docs/nightly/fuel-graphql-docs/docs/reference/objects.md


# Objects

## `Balance`

The balance of a particular asset for a wallet address.

**fields:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

An EOA account represented by 32 bytes.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of the selected asset id as an unsigned 64 bit number.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

A 32 byte representation of the asset.

## `BalanceFilterInput`

The filter input type used to filter the `balances` query.

**fields:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address of the balances.

## `Blob`

Information about a blob transaction in the network.

**fields:**

`id`: [`BlobId!`](/docs/reference/scalars/#blobid)

The transaction identifier for the blob.

`bytecode`: [`HexString!`](/docs/reference/scalars/#hexstring)

The blob bytecode.

## `Block`

Information about a block in the network.

**fields:**

`version`: [`BlockVersion!`](/docs/reference/enums/#blockversion)

The version of the block.

`id`: [`BlockId!`](/docs/reference/scalars/#blockid)

A unique identifier for the block.

`height`: [`U32!`](/docs/reference/scalars/#u32)

The height of the block.

`header`: [`Header!`](#header)

Metadata about a block.

`consensus`: [`Consensus!`](/docs/reference/unions/#consensus)

The type of consensus used.

`transactionIds`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

An array of transaction ids included in the block only.

`transactions`: [`[Transaction!]!`](#transaction)

An array of transactions included in the block.

## `Breakpoint`

A breakpoint during debugging.
Defined as a tuple of a contract ID and relative `pc` offset inside it.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`pc`: [`U64!`](/docs/reference/scalars/#u64)

The value of the program counter register `$pc`, which is the memory address of the current instruction.

## `ChainInfo`

Information about the base chain. At a very high level `chainInfo` helps you understand what Fuel chain you're connected to and the different parameters of this chain.

**fields:**

`name`: `String!`

The human-readable string name of the chain. i.e. `Upgradable Testnet`.

`latestBlock`: [`Block!`](#block)

The most recently created block.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The height of the base chain via relayer (i.e. Ethereum or DA)

`consensusParameters`: [`ConsensusParameters!`](#consensusparameters)

The consensus parameters used to validate blocks.

`gasCosts`: [`GasCosts!`](#gascosts)

The gas cost of each opcode.

## `ChangeOutput`

A transaction output that changes the unspent coins in a UTXO.

**fields:**

`to`: [`Address!`](/docs/reference/scalars/#address)

The recipient address of the coins.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the coins.

## `Coin`

Information about a coin.

**fields:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for a UTXO.

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address of the coins.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id of the coin.

`blockCreated`: [`U32!`](/docs/reference/scalars/#u32)

The block when the coins were created.

`txCreatedIdx`: [`U64!`](/docs/reference/scalars/#u64)

The index of the transaction that created this coin.

## `CoinFilterInput`

The filter input type for the `coins` query.

**fields:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner of the coins.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id of the coins.

## `CoinOutput`

A type representing a coin output.

**fields:**

`to`: [`Address!`](/docs/reference/scalars/#address)

The receiver address of the output coins.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins in the output.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the output coins.

## `ConsensusParameters`

The consensus parameters used for validating blocks.

**fields:**

`version`: [`ConsensusParametersVersion!`](/docs/reference/unions/#consensusparametersversion)

The version of the consensus parameters.

`txParams`: [`TxParameters!`](#txparameters)

The allowed parameters of transactions.

`predicateParams`: [`PredicateParameters!`](#predicateparameters)

The allowed parameters of predicates.

`scriptParams`: [`ScriptParameters!`](#scriptparameters)

The allowed parameters of scripts.

`contractParams`: [`ContractParameters!`](#contractparameters)

The allowed parameters of contracts.

`feeParams`: [`FeeParameters!`](#feeparameters)

The allowed parameters of fees.

`baseAssetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id of the "base" asset used for gas fees.

`blockGasLimit`: [`U64!`](/docs/reference/scalars/#u64)

The maximum amount of gas spend allowed in a block.

`blockTransactionSizeLimit`: [`U64!`](/docs/reference/scalars/#u64)

The maximum transaction slots in a block.

`chainId`: [`U64!`](/docs/reference/scalars/#u64)

A unique identifier for the chain.

`gasCosts`: [`GasCosts!`](#gascosts)

The gas cost of each opcode.

`privilegedAddress`: [`Address!`](/docs/reference/scalars/#address)

The address used to authorize network upgrades via the `Upgrade` transaction.

## `ConsensusParametersPurpose`

Details about the consensus parameters that are being upgraded.

**fields:**

`witnessIndex`: [`U16!`](/docs/reference/scalars/#u16)

The index of the witness in the `witnesses` field that contains the serialized consensus parameters. For an upgrade to consensus parameters, the upgraded parameters are stored as a witness in the transaction.

`checksum`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The hash of the serialized consensus parameters.
Since the serialized consensus parameters live inside the transaction witnesses (which is malleable data), any party can override them. The `checksum` is used to verify that the data was not modified or tampered with.

## `Contract`

An object representing a deployed contract.

**fields:**

`id`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`bytecode`: [`HexString!`](/docs/reference/scalars/#hexstring)

The contract bytecode.

`salt`: [`Salt!`](/docs/reference/scalars/#salt)

A unique identifier for the contract.

## `ContractBalance`

An object representing the balance of a deployed contract for a certain asset.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The contract balance for the given asset.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the coins.

## `ContractBalanceFilterInput`

The filter input type for the `contractBalances` query.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract id that the query will return balances for.

## `ContractCreated`

The output type from deploying a contract.

**fields:**

`contract`: [`Contract!`](#contract)

The contract that was created.

`stateRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The initial state root of contract.

## `ContractOutput`

The output type from a transaction that changed the state of a contract.

**fields:**

`inputIndex`: `Int!`

The index of the input.

`balanceRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The root of amount of coins owned by contract after transaction execution.

`stateRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The state root of contract after transaction execution.

## `ContractParameters`

Contract-specific consensus parameters.

**fields:**

`version`: [`ContractParametersVersion!`](/docs/reference/unions/#contractparametersversion)

The version of the contract-specific consensus parameters.

`contractMaxSize`: [`U64!`](/docs/reference/scalars/#u64)

Maximum size of a contract in bytes.

`maxStorageSlots`: [`U64!`](/docs/reference/scalars/#u64)

Maximum number of storage slots.

## `DryRunTransactionExecutionStatus`

Details about the status of a transaction dry run.

**fields:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The transaction ID.

`status`: [`DryRunTransactionStatus!`](/docs/reference/unions/#dryruntransactionstatus)

The status of the transaction dry run.

`receipts`: [`[Receipt!]!`](#receipt)

The receipts for the transaction dry run.

## `DryRunFailureStatus`

The status details of a failed transaction dry run.

**fields:**

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`reason`: `String!`

The reason why the transaction dry run failed.

`receipts`: [`[Receipt!]!`](#receipt)

The transaction dry run receipts.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `DryRunSuccessStatus`

The status details of a successful transaction dry run.

**fields:**

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`receipts`: [`[Receipt!]!`](#receipt)

The transaction dry run receipts.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `EstimateGasPrice`

The estimated gas price for a transaction.

**fields:**

`gasPrice`: [`U64!`](/docs/reference/scalars/#u64)

## `ExcludeInput`

The input type for the `resourcesToSpend` query that defines what UTXOs and messages to exclude.

**fields:**

`utxos`: [`[UtxoId!]!`](/docs/reference/scalars/#utxoid)

An array of UTXO IDs to exclude.

`messages`: [`[Nonce!]!`](/docs/reference/scalars/#nonce)

An array of message IDs to exclude.

## `FailureStatus`

The status type of a transaction that has failed.

**fields:**

`transactionId`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

A unique transaction id.

`blockHeight`: [`U32`](/docs/reference/scalars/#u32)

The block height for the failed transaction.

`block`: [`Block!`](#block)

The block number for the failed transaction.

`transaction`: [`Transaction!`](#transaction)

The transaction itself.

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The time the transaction failed.

`reason`: `String!`

The reason why the transaction failed.

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`receipts`: [`[Receipt!]!`](#receipt)

The receipts for the transaction.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `FeeParameters`

The consensus parameters for fees.

**fields:**

`version`: [`FeeParametersVersion!`](/docs/reference/unions/#feeparametersversion)

The version of the consensus parameters.

`gasPriceFactor`: [`U64!`](/docs/reference/scalars/#u64)

The dynamic adjustment of gas costs.

`gasPerByte`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost per byte.

## `GasCosts`

The breakdown of the gas costs of each opcode.

**fields:**

`version`: [`GasCostsVersion!`](/docs/reference/unions/#gascostsversion)

The version of the gas-specific consensus parameters.

`add`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$add` ALU opcode.

`addi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$addi` ALU opcode.

`aloc`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$aloc` memory opcode.

`and`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$and` ALU opcode.

`andi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$andi` ALU opcode.

`bal`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$bal` contract opcode.

`bhei`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$bhei` contract opcode.

`bhsh`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$bhsh` contract opcode.

`burn`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$burn` contract opcode.

`cb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$cb` contract opcode.

`cfei`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$cfei` memory opcode.

`cfsi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$cfsi` memory opcode.

`div`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$div` ALU opcode.

`divi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$divi` ALU opcode.

`ecr1`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ecr1` cryptographic opcode.

`eck1`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$eck1` cryptographic opcode.

`ed19`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ed19` cryptographic opcode.

`eq`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$eq` ALU opcode.

`exp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$exp` ALU opcode.

`expi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$expi` ALU opcode.

`flag`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$flag` opcode.

`gm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$gm` opcode.

`gt`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$gt` opcode.

`gtf`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$gtf` ALU opcode.

`ji`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ji` control flow opcode.

`jmp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jmp` control flow opcode.

`jne`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jne` control flow opcode.

`jnei`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnei` control flow opcode.

`jnzi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnzi` control flow opcode.

`jmpf`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jmpf` control flow opcode.

`jmpb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jmpb` control flow opcode.

`jnzf`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnzf` control flow opcode.

`jnzb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnzb` control flow opcode.

`jnef`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jnef` control flow opcode.

`jneb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$jneb` control flow opcode.

`lb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$lb` memory opcode.

`log`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$log` contract opcode.

`lt`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$lt` ALU opcode.

`lw`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$lw` memory opcode.

`mint`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mint` contract opcode.

`mlog`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mlog` ALU opcode.

`modOp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$modOp` opcode.

`modi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$modi` ALU opcode.

`moveOp`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$moveOp` ALU opcode.

`movi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$movi` ALU opcode.

`mroo`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mroo` ALU opcode.

`mul`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mul` ALU opcode.

`muli`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$muli` ALU opcode.

`mldv`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$mldv` ALU opcode.

`noop`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$noop` ALU opcode.

`not`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$not` ALU opcode.

`or`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$or` ALU opcode.

`ori`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ori` ALU opcode.

`poph`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$poph` opcode.

`popl`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$popl` opcode.

`pshh`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$pshh` opcode.

`pshl`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$pshl` opcode.

`ret`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$ret` opcode.

`rvrt`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$rvrt` contract opcode.

`sb`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sb` memory opcode.

`sll`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sll` ALU opcode.

`slli`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$slli` ALU opcode.

`srl`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$srl` ALU opcode.

`srli`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$srli` ALU opcode.

`srw`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$srw` contract opcode.

`sub`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sub` ALU opcode.

`subi`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$subi` ALU opcode.

`sw`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sw` memory opcode.

`sww`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$sww` contract opcode.

`time`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$time` contract opcode.

`tr`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$tr` contract opcode.

`tro`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$tro` contract opcode.

`wdcm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdcm` ALU opcode.

`wqcm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqcm` ALU opcode.

`wdop`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdop` ALU opcode.

`wqop`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqop` ALU opcode.

`wdml`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdml` ALU opcode.

`wqml`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqml` ALU opcode.

`wddv`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wddv` ALU opcode.

`wqdv`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqdv` ALU opcode.

`wdmd`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdmd` ALU opcode.

`wqmd`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqmd` ALU opcode.

`wdam`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdam` ALU opcode.

`wqam`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqam` ALU opcode.

`wdmm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wdmm` ALU opcode.

`wqmm`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$wqmm` ALU opcode.

`xor`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$xor` ALU opcode.

`xori`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of using the `$xori` ALU opcode.

`alocDependentCost`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$aloc` contract opcode.

`bldd`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$bldd` contract opcode.

`bsiz`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$bsiz` contract opcode.

`cfe`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$cfe` contract opcode.

`cfeiDependentCost`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$cfei` contract opcode.

`call`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$call` contract opcode.

`ccp`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$ccp` contract opcode.

`croo`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$croo` contract opcode.

`csiz`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$csiz` contract opcode.

`ed19DependentCost`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$ed19` contract opcode.

`k256`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$k256` cryptographic opcode.

`ldc`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$ldc` contract opcode.

`logd`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$logd` contract opcode.

`mcl`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcl` memory opcode.

`mcli`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcli` memory opcode.

`mcp`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcp` memory opcode.

`mcpi`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcpi` memory opcode.

`meq`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$meq` memory opcode.

`retd`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$retd` contract opcode.

`s256`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$mcpi` cryptographic opcode.

`scwq`: [`DependentCost`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$scwq` cryptographic opcode.

`smo`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$smo` contract opcode.

`srwq`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$srwq` contract opcode.

`swwq`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of using the `$swwq` contract opcode.

`contractRoot`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost calculating the `contractRoot`.

`stateRoot`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost calculating the `stateRoot`.

`vmInitialization`: [`DependentCost!`](/docs/reference/unions/#dependentcost)

The `dependent` gas cost of the `vmInitialization`.

`newStoragePerByte`: [`U64!`](/docs/reference/scalars/#u64)

The gas cost of storage per byte.

## `Genesis`

The genesis consensus type.

**fields:**

`chainConfigHash`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The chain configuration hash. The chain configuration defines what consensus type to use, what settlement layer to use, and the rules of block validity.

`coinsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary Merkle tree root of all genesis coins.

`contractsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary Merkle tree root of state, balances, and the contracts code hash of each contract.

`messagesRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary merkle tree root of all genesis messages.

`transactionsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The binary Merkle tree root of all previous transactions.

## `HeavyOperation`

The operation dependent on the size of its inputs, and the time required per unit of input exceeding that of a single no-op operation

**fields:**

`base`: [`U64!`](/docs/reference/scalars/#u64)

The minimum gas that this operation can cost

`gasPerUnit`: [`U64!`](/docs/reference/scalars/#u64)

The gas is required to process a single unit

## `Header`

The header contains metadata about a certain block.

**fields:**

`version`: [`HeaderVersion!`](/docs/reference/enums/#headerversion)

The version of the header.

`id`: [`BlockId!`](/docs/reference/scalars/#blockid)

The current block id.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The block height for the data availability layer up to which (inclusive) input messages are processed.

`consensusParametersVersion`: [`U32!`](/docs/reference/scalars/#u32)

The version of the consensus parameters.

`stateTransitionBytecodeVersion`: [`U32!`](/docs/reference/scalars/#u32)

The version of the state transition bytecode.

`transactionsCount`: [`U64!`](/docs/reference/scalars/#u64)

The number of transactions in the block.

`messageReceiptCount`: [`U64!`](/docs/reference/scalars/#u64)

The number of receipt messages in the block.

`transactionsRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The merkle root of the transactions in the block.

`messageOutboxRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The Merkle root of the outgoing messages back to the data availability (DA) layer from Fuel, where the inputs are the IDs (`MessageId`) of the messages. The IDs are produced by executing transactions and collecting IDs from the receipts of the `Message` outputs.

`eventInboxRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The Merkle root of the incoming events from the data availability (DA) layer to Fuel, where the tree inputs are the hashes of these events.

`height`: [`U32!`](/docs/reference/scalars/#u32)

The block height.

`prevRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The merkle root of all previous consensus header hashes (not including this block).

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The timestamp for the block.

`applicationHash`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The hash of the serialized application header for this block.

## `InputCoin`

Information about a coin input.

**fields:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for the UTXO.

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owning address or predicate root.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset ID of the coins.

`txPointer`: [`TxPointer!`](/docs/reference/scalars/#txpointer)

A pointer to the transaction whose output is being spent.

`witnessIndex`: `Int!`

The index of the witness that authorizes spending the coin.

`predicateGasUsed`: [`U64!`](/docs/reference/scalars/#u64)

The amount of gas used in the predicate transaction.

`predicate`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate bytecode.

`predicateData`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate input parameters.

## `InputContract`

Information about a contract input.

**fields:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for the UTXO.

`balanceRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The root of amount of coins owned by contract before transaction execution.

`stateRoot`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The state root of contract before transaction execution.

`txPointer`: [`TxPointer!`](/docs/reference/scalars/#txpointer)

A pointer to the TX whose output is being spent.

`contractId`: [`ContractId!`](/docs/reference/scalars/#contractid)

The input contract's ID.

## `InputMessage`

Information about a message input.

**fields:**

`sender`: [`Address!`](/docs/reference/scalars/#address)

The sender address of the message.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The recipient address of the message.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount sent in the message.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

A nonce value for the message input, which is determined by the sending system and is published at the time the message is sent.

`witnessIndex`: `Int!`

The index of witness that authorizes spending the coin.

`predicateGasUsed`: [`U64!`](/docs/reference/scalars/#u64)

The amount of gas used in the predicate transaction.

`data`: [`HexString!`](/docs/reference/scalars/#hexstring)

The message data.

`predicate`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate bytecode.

`predicateData`: [`HexString!`](/docs/reference/scalars/#hexstring)

The predicate input parameters.

## `LatestGasPrice`

Information about the latest price of gas.

**fields:**

`gasPrice`: [`U64!`](/docs/reference/scalars/#u64)

The gas price for the latest block produced.

`blockHeight`: [`U32!`](/docs/reference/scalars/#u32)

The block height for the latest block produced.

## `LightOperation`

The operation dependent on the size of its inputs, and the time required per unit of input less that of a single no-op operation

**fields:**

`base`: [`U64!`](/docs/reference/scalars/#u64)

The minimum gas that this operation can cost

`unitsPerGas`: [`U64!`](/docs/reference/scalars/#u64)

The units that can be processed with a single gas

## `MerkleProof`

Information about a merkle proof.

**fields:**

`proofSet`: [`[Bytes32!]!`](/docs/reference/scalars/#bytes32)

The proof set of the message proof.

`proofIndex`: [`U64!`](/docs/reference/scalars/#u64)

The index used to generate this proof.

## `Message`

Contains information about a message.

**fields:**

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of base asset coins sent with the message.

`sender`: [`Address!`](/docs/reference/scalars/#address)

The address of the message sender.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The recipient of the message.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The nonce value for the message.

`data`: `[Int!]!`

The vector with the message data.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The block height of the data availability layer up to which (inclusive) input messages are processed.

## `MessageCoin`

Information about message coin

**fields:**

`sender`: [`Address!`](/docs/reference/scalars/#address)

The address of the message sender.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The recipient of the message.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The nonce value for the message.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of base asset coins sent with the message.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id of the coins transferred.

`daHeight`: [`U64!`](/docs/reference/scalars/#u64)

The block height of the data availability layer up to which (inclusive) input messages are processed.

## `MessageProof`

Information about the message proof.

**fields:**

`messageProof`: [`MerkleProof!`](#merkleproof)

The merkle proof of the message.

`blockProof`: [`MerkleProof!`](#merkleproof)

The merkle proof of the block.

`messageBlockHeader`: [`Header!`](#header)

The merkle proof of the message.

`commitBlockHeader`: [`Header!`](#header)

The merkle proof of the block.

`sender`: [`Address!`](/docs/reference/scalars/#address)

The message sender.

`recipient`: [`Address!`](/docs/reference/scalars/#address)

The message recipient.

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The message nonce.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount sent in the message.

`data`: [`HexString!`](/docs/reference/scalars/#hexstring)

The data from the message.

## `MessageStatus`

The status type of a message.

**fields:**

`state`: [`MessageState`](/docs/reference/enums/#messagestate)

The state of the message.

## `NodeInfo`

Information about a node.

**fields:**

`utxoValidation`: `Boolean!`

Whether or not the node is using UTXO validation.

`vmBacktrace`: `Boolean!`

Whether or not logging of backtraces from VM errors is enabled.

`maxTx`: [`U64!`](/docs/reference/scalars/#u64)

The maximum number of transactions.

`maxDepth`: [`U64!`](/docs/reference/scalars/#u64)

The maximum number of connected UTXOs allowed, excluding contracts.

`nodeVersion`: `String!`

The node version.

`peers`: [`PeerInfo!`](#peerinfo)!`

The information about the node's peers.

## `OutputBreakpoint`

A breakpoint during debugging.

**fields:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract address.

`pc`: [`U64!`](/docs/reference/scalars/#u64)

The value of the program counter register `$pc`, which is the memory address of the current instruction.

## `PeerInfo`

Information about a peer node.

**fields:**

`id`: `String!`

The `libp2p` ID of the peer node.

`addresses`: `[String!]!`

The advertised addresses that can be used to connect to this peer node.

`clientVersion`: `String`

The self-reported version of the client the peer node is using.

`blockHeight`: [`U32`](/docs/reference/scalars/#u32)

The last reported height of the peer node.

`lastHeartbeatMs`: [`U64!`](/docs/reference/scalars/#u64)

The time of the last heartbeat from this peer node in Unix epoch time milliseconds.

`appScore`: `Float!`

The internal Fuel peer-to-peer reputation of this peer node.

## `PoAConsensus`

The proof-of-authority (PoA) consensus type.

**fields:**

`signature`: [`Signature!`](/docs/reference/scalars/#signature)

The signature of the block produced by PoA consensus.

## `ProgramState`

An object representing the state of execution of a transaction.

**fields:**

`returnType`: [`ReturnType!`](/docs/reference/enums/#returntype)

The type of return response for the transaction.

`data`: [`HexString!`](/docs/reference/scalars/#hexstring)

The data returned from the transaction.

## `Policies`

Information about the policies of a transaction.

**fields:**

`tip`: [`U64`](/docs/reference/scalars/#u64)

The user-defined `tip` is a new transaction policy that replaced the `GasPrice` transaction policy. `Tip` allows the user to specify how much they want to pay to the block producer to incentivize them to include the user's transaction in the block.

`witnessLimit`: [`U64`](/docs/reference/scalars/#u64)

The limit of witnesses that can be included in the transaction.

`maturity`: [`U32`](/docs/reference/scalars/#u32)

The minimum block height that the transaction can be included at.

`maxFee`: [`U64`](/docs/reference/scalars/#u64)

The maximum fee allowed for the transaction to consume.

## `PredicateParameters`

The consensus parameters for predicates.

**fields:**

`version`: [`PredicateParametersVersion!`](/docs/reference/unions/#predicateparametersversion)

The version of the consensus parameters.

`maxPredicateLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of a predicate.

`maxPredicateDataLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of predicate data.

`maxGasPerPredicate`: [`U64!`](/docs/reference/scalars/#u64)

The maximum amount of gas allowed for a predicate.

`maxMessageDataLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of message data for a predicate.

## `Receipt`

An object representing all possible types of receipts.

**fields:**

`id`: [`ContractId!`](/docs/reference/scalars/#contractid)

The ID of the contract that produced the receipt.

`pc`: [`U64`](/docs/reference/scalars/#u64)

The value of the program counter register `$pc`, which is the memory address of the current instruction.

`is`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$is`, which is the pointer to the start of the currently-executing code.

`to`: [`Contract`](#contract)

The recipient contract.

`toAddress`: [`Address`](/docs/reference/scalars/#address)

The recipient address.

`amount`: [`U64`](/docs/reference/scalars/#u64)

The amount of coins transferred.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id of the coins transferred.

`gas`: [`U64`](/docs/reference/scalars/#u64)

The gas used for the transaction.

`param1`: [`U64`](/docs/reference/scalars/#u64)

The first parameter for a `CALL` receipt type, holds the function selector.

`param2`: [`U64`](/docs/reference/scalars/#u64)

The second parameter for a `CALL` receipt type, typically used for the user-specified input to the ABI function being selected.

`val`: [`U64`](/docs/reference/scalars/#u64)

The value of registers at the end of execution, used for debugging.

`ptr`: [`U64`](/docs/reference/scalars/#u64)

The value of the pointer register, used for debugging.

`digest`: [`Bytes32`](/docs/reference/scalars/#bytes32)

A 32-byte hash of `MEM[$rC, $rD]`. The syntax `MEM[x, y]` means the memory range starting at byte `x`, of length `y` bytes.

`reason`: [`U64`](/docs/reference/scalars/#u64)

The decimal string representation of an 8-bit unsigned integer for the panic reason. Only returned if the receipt type is `PANIC`.

`ra`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rA`.

`rb`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rB`.

`rc`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rC`.

`rd`: [`U64`](/docs/reference/scalars/#u64)

The value of register `$rD`.

`len`: [`U64`](/docs/reference/scalars/#u64)

The length of the receipt.

`receiptType`: [`ReceiptType!`](/docs/reference/enums/#receipttype)

The type of receipt.

`result`: [`U64`](/docs/reference/scalars/#u64)

`0` if script exited successfully, `any` otherwise.

`gasUsed`: [`U64`](/docs/reference/scalars/#u64)

The amount of gas consumed by the script.

`data`: [`HexString`](/docs/reference/scalars/#hexstring)

The receipt data.

`sender`: [`Address`](/docs/reference/scalars/#address)

The address of the message sender.

`recipient`: [`Address`](/docs/reference/scalars/#address)

The address of the message recipient.

`nonce`: [`Nonce`](/docs/reference/scalars/#nonce)

The nonce value for a message.

`contractId`: [`ContractId`](/docs/reference/scalars/#contractid)

The contract id.

`subId`: [`Bytes32`](/docs/reference/scalars/#bytes32)

The sub id.

## `RelayedTransactionFailed`

Details about why a relayed transaction from an L1 failed.

**fields:**

`blockHeight`: `U32!`

The block height at the time the relayed transaction failed.

`failure`: `String!`

The reason why the transaction failed.

## `RunResult`

The result of a transaction execution.

**fields:**

`state`: `RunState!`

The state of the transaction execution.

`breakpoint`: `OutputBreakpoint`

A breakpoint during debugging.

`jsonReceipts`: `[String!]!`

The receipts of the transaction in JSON format.

## `ScriptParameters`

The consensus parameters for a script.

**fields:**

`version`: [`ScriptParametersVersion!`](/docs/reference/unions/#scriptparametersversion)

The version of the consensus parameters.

`maxScriptLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of a script.

`maxScriptDataLength`: [`U64!`](/docs/reference/scalars/#u64)

The maximum length of script data.

## `SpendQueryElementInput`

A type used in the `queryPerAsset` argument for the `resourcesToSpend` query.

**fields:**

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the asset.

`amount`: [`U64!`](/docs/reference/scalars/#u64)

The amount of coins to send.

`max`: [`U64`](/docs/reference/scalars/#u64)

The max number of resources in the selection.

## `SqueezedOutStatus`

The status for a transaction that was squeezed out of the transaction pool.

**fields:**

`reason`: `String!`

The reason why the transaction was squeezed out.

## `StateTransitionBytecode`

The bytecode of a state transition upgrade.

**fields:**

`root`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

The merkle root of the state transition bytecode.

`bytecode`: [`[UploadedBytecode!]`](#uploadedbytecode)

The bytecode of the state transition.

## `StateTransitionPurpose`

Details about a state transition upgrade.

**fields:**

`root`: [`Bytes32!`](/docs/reference/scalars/#bytes32)

The merkle root of the new state.

## `SuccessStatus`

The status of a successful transaction.

**fields:**

`transactionId`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The ID of the transaction.

`blockHeight`: [`U32`](/docs/reference/scalars/#u32)

The block height for the successful transaction.

`block`: [`Block!`](#block)

The block for the successful transaction.

`transaction`: [`Transaction!`](#transaction)

The transaction itself.

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The time of the transaction.

`programState`: [`ProgramState`](#programstate)

The state of the program execution.

`receipts`: [`[Receipt!]!`](#receipt)

The transaction receipts.

`totalGas`: [`U64!`](/docs/reference/scalars/#u64)

The total amount of gas used.

`totalFee`: [`U64!`](/docs/reference/scalars/#u64)

The total fee for the transaction.

## `SubmittedStatus`

The status for a submitted transaction.

**fields:**

`time`: [`Tai64Timestamp!`](/docs/reference/scalars/#tai64timestamp)

The time a transaction was submitted

## `Transaction`

An object containing information about a transaction.

**fields:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

A unique transaction id.

`inputAssetIds`: [`[AssetId!]`](/docs/reference/scalars/#assetid)

An array of asset ids used for the transaction inputs.

`inputContracts`: [`[Contract!]`](#contract)

An array of contracts used for the transaction inputs.

`inputContract`: [`InputContract`](#inputcontract)

A contract used for the transaction input.

`policies`: [`Policies`](#policies)

The policies for the transaction.

`scriptGasLimit`: [`U64`](/docs/reference/scalars/#u64)

The gas limit for the transaction.

`maturity`: [`U32`](/docs/reference/scalars/#u32)

The minimum block height that the transaction can be included at.

`mintAmount`: [`U64`](/docs/reference/scalars/#u64)

The amount minted in the transaction.

`mintAssetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset ID for coins minted in the transaction.

`mintGasPrice`: [`U64!`](/docs/reference/scalars/#u64)

The gas price at the time of minting the block.

`txPointer`: [`TxPointer`](/docs/reference/scalars/#txpointer)

The location of the transaction in the block.

`isScript`: `Boolean!`

Whether or not the transaction is a script.

`isCreate`: `Boolean!`

Whether or not the transaction is creating a new contract.

`isMint`: `Boolean!`

Whether or not the transaction is minting new coins.

`isUpgrade`: `Boolean!`

Whether or not the transaction is upgrading the network.

`isUpload`: `Boolean!`

Whether or not the transaction is uploading state transition data to prepare for upgrading the network.

`isBlob`: `Boolean!`

Whether or not the transaction is a blob.

`inputs`: [`[Input!]`](/docs/reference/unions/#input)

An array of inputs for the transaction.

`outputs`: [`[Output!]!`](/docs/reference/unions/#output)

An array of outputs for the transaction.

`outputContract`: [`ContractOutput`](#contractoutput)

The contract output for the transaction.

`witnesses`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

An array of witnesses.

`receiptsRoot`: [`Bytes32`](/docs/reference/scalars/#bytes32)

The root of the receipts.

`status`: [`TransactionStatus`](/docs/reference/unions/#transactionstatus)

The status of the transaction.

`script`: [`HexString`](/docs/reference/scalars/#hexstring)

The script to execute.

`scriptData`: [`HexString`](/docs/reference/scalars/#hexstring)

The script input parameters.

`bytecodeWitnessIndex`: `Int`

The witness index of contract bytecode.

`blobId`: [`BlobId`](/docs/reference/scalars/#blobid)

A unique hash identifier for a blob transaction.

`salt`: [`Salt`](/docs/reference/scalars/#salt)

The salt value for the transaction.

`storageSlots`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

An array of storage slot.

`bytecodeRoot`: [`Bytes32`](/docs/reference/scalars/#bytes32)

The Merkle tree root of the bytecode that is being uploaded.

`subsectionIndex`: [`U16`](/docs/reference/scalars/#u16)

The index of the subsection of the bytecode.

`subsectionsNumber`: [`U16`](/docs/reference/scalars/#u16)

The total number of subsections that the bytecode was divided into.

`proofSet`: [`[Bytes32!]`](/docs/reference/scalars/#bytes32)

The proof set helps to verify the connection of the subsection to the `root`.

`upgradePurpose`: [`UpgradePurpose`](/docs/reference/unions/#upgradepurpose)

The purpose of a network upgrade.

`rawPayload`: [`HexString!`](/docs/reference/scalars/#hexstring)

A hex string of the raw transaction payload.

## `TxParameters`

The consensus parameters for a transaction.

**fields:**

`version`: [`TxParametersVersion!`](/docs/reference/unions/#txparametersversion)

The version of the consensus parameters.

`maxInputs`: [`U8!`](/docs/reference/scalars/#u8)

The maximum number of inputs allowed for a transaction.

`maxOutputs`: [`U8!`](/docs/reference/scalars/#u8)

The maximum number of outputs allowed for a transaction.

`maxWitnesses`: [`U32!`](/docs/reference/scalars/#u32)

The maximum number of witnesses allowed for a transaction.

`maxGasPerTx`: [`U64!`](/docs/reference/scalars/#u64)

The maximum amount of gas allowed for a transaction.

`maxSize`: [`U64!`](/docs/reference/scalars/#u64)

The maximum size allowed for a transaction.

`maxBytecodeSubsections`: [`U16!`](/docs/reference/scalars/#u16)

The maximum number of subsections the new executor bytecode can be broken into.

## `UploadedBytecode`

**fields:**

`bytecode`: [`[HexString!]!`](/docs/reference/scalars/#hexstring)

The bytecode that is uploaded.

`uploadedSubsectionsNumber`: `Int`

The number of uploaded subsections.

`completed`: `Boolean!`

Whether or not the bytecode upload has completed.

## `VariableOutput`

The output type for a transaction that outputs an amount that may vary based on transaction execution.

**fields:**

`to`: [`Address`](/docs/reference/scalars/#address)

The address the coins were sent to.

`amount`: [`U64`](/docs/reference/scalars/#u64)

The amount of coins in the output.

`assetId`: [`AssetId`](/docs/reference/scalars/#assetid)

The asset id for the coins sent.


---

### File: docs/nightly/fuel-graphql-docs/docs/reference/queries.md


# Queries

## `balance`

Returns the [`Balance!`](/docs/reference/objects/#balance) of a specific address for a given asset id.

**args:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address.

`assetId`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id.

## `balances`

Returns a [`BalanceConnection!`](/docs/reference/objects/#balance) for an array of balances for each asset owned by a given address.

**args:**

`filter`: [`BalanceFilterInput!`](/docs/reference/objects/#balancefilterinput)

A filter to specify the wallet owner address.

## `blob`

Returns information about a certain [`Blob`](/docs/reference/objects/#blob).

**args:**

`id`: [`BlobId`](/docs/reference/scalars/#blobid)

The transaction identifier for the blob.

## `block`

Returns information about a certain [`Block`](/docs/reference/objects/#block). Accepts either the block id or block height as an argument.

**args:**

`id`: [`BlockId`](/docs/reference/scalars/#blockid)

The block id.

`height`: [`U64`](/docs/reference/scalars/#u64)

The block height.

## `blocks`

Returns a [`BlockConnection!`](/docs/reference/objects/#block) for an array of all blocks produced.

## `chain`

Returns [`ChainInfo!`](/docs/reference/objects/#chaininfo) about the target Fuel network used for the API.

## `coin`

Returns details about a specific [`Coin`](/docs/reference/objects/#coin).

**args:**

`utxoId`: [`UtxoId!`](/docs/reference/scalars/#utxoid)

A unique 32 byte identifier for the UTXO.

## `coins`

Returns a [`CoinConnection!`](/docs/reference/objects/#coin) for an array of coins based on a given owner and/or asset id

**args:**

`filter`: [`CoinFilterInput!`](/docs/reference/objects/#coinfilterinput)

A filter with the owner address and optionally the asset id.

## `coinsToSpend`

Returns an array of spendable [`[[CoinType!]!]!`](/docs/reference/unions/#cointype) per asset.

**args:**

`owner`: [`Address`](/docs/reference/scalars/#address)

The owner address of the coins.

`queryPerAsset`: [`[SpendQueryElementInput!]!`](/docs/reference/objects/#spendqueryelementinput)

The list of requested asset resources. Several entries with the same asset id are not allowed.

`excludedIds`: [`ExcludeInput`](/docs/reference/objects/#excludeinput)

The resources to exclude.

## `consensusParameters`

Returns the [`ConsensusParameters`](/docs/reference/objects/#consensusparameters) for a given version.

**args:**

`version`: `Int!`

The version of the consensus parameters.

## `contract`

Returns the [`Contract`](/docs/reference/objects/#contract) information for a given contract id.

**args:**

`id`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract id of the requested contract.

## `contractBalance`

Returns the [`ContractBalance!`](/docs/reference/objects/#contractbalance) for a given contract and asset id.

**args:**

`contract`: [`ContractId!`](/docs/reference/scalars/#contractid)

The contract that owns the balance.

`asset`: [`AssetId!`](/docs/reference/scalars/#assetid)

The asset id for the balance.

## `contractBalances`

Returns a [`ContractBalanceConnection!`](/docs/reference/objects/#contractbalance) for an array of balances for all assets owned by a given contract

**args:**

`filter`: [`ContractBalanceFilterInput!`](/docs/reference/objects/#contractbalancefilterinput)

A filter for the contract balances.

## `estimateGasPrice`

Estimates the most expensive the gas price over a given block horizon, and returns [`EstimateGasPrice!`](/docs/reference/objects/#estimategasprice).

**args:**

`blockHorizon`: [`U32!`](/docs/reference/scalars/#u32)

The block horizon defines how many blocks in the future you are doing an estimate for.

## `estimatePredicates`

Estimate the predicate gas and returns a [`Transaction!`](/docs/reference/objects/#transaction).

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.

## `health`

Returns `true` if the API is running or `false` if the API is down.

## `latestGasPrice`

Returns the [`LatestGasPrice!`](/docs/reference/objects/#latestgasprice) of the latest block.

## `message`

Returns the [`Message`](/docs/reference/objects/#message) for a given message nonce.

**args:**

`nonce`: [`Nonce!`](/docs/reference/scalars/#nonce)

The message nonce.

## `messageProof`

Returns the [`MessageProof`](/docs/reference/objects/#messageproof) for a given message id or transaction.

**args:**

`transactionId`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The transaction id for the message.

`nonce`: [`Nonce`](/docs/reference/scalars/#nonce)

The message nonce.

`commitBlockId`: [`BlockId`](/docs/reference/scalars/#blockid)

The block id.

`commitBlockHeight`: [`U32`](/docs/reference/scalars/#u32)

The block height.

## `messages`

Returns a [`MessageConnection!`](/docs/reference/objects/#message) for an array of messages for a given owner.

**args:**

`owner`: [`Address`](/docs/reference/scalars/#address)

The owner address of the messages.

## `messageStatus`

Returns the [`MessageStatus`](/docs/reference/objects/#messagestatus) for a given message [`Nonce`](/docs/reference/scalars/#nonce).

**args:**

`nonce`: [`Nonce`](/docs/reference/scalars/#nonce)

The nonce of the message.

## `nodeInfo`

Returns [`NodeInfo!`](/docs/reference/objects/#nodeinfo) about the current node.

## `relayedTransactionStatus`

Returns [`RelayedTransactionStatus`](/docs/reference/unions/#relayedtransactionstatus) details for a given relayed transaction id.

**args:**

`id`: [`RelayedTransactionId!`](/docs/reference/scalars/#relayedtransactionid)

The ID for the relayed transaction.

## `stateTransitionBytecodeByVersion`

Returns [`StateTransitionBytecode`](/docs/reference/objects/#statetransitionbytecode) details for a given version.

**args:**

`version`: `Int!`

The version of the state transition function..

## `stateTransitionBytecodeByRoot`

Returns [`StateTransitionBytecode`](/docs/reference/objects/#statetransitionbytecode) details for a given root.

**args:**

`root`: [`[HexString!]`](/docs/reference/scalars/#hexstring)

The merkle root of the state transition bytecode.

## `transaction`

Returns [`Transaction`](/docs/reference/objects/#transaction) details for a given transaction id.

**args:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The ID for the transaction.

## `transactions`

Returns a [`TransactionConnection!`](/docs/reference/objects/#transaction) for an array of all transactions.

## `transactionsByOwner`

Returns a [`TransactionConnection!`](/docs/reference/objects/#transaction) for an array of all transactions from a given address.

**args:**

`owner`: [`Address!`](/docs/reference/scalars/#address)

The owner address of the transactions.


---

### File: docs/nightly/fuel-graphql-docs/docs/reference/scalars.md


# Scalars

## `Address`

An address of an externally owned account identified by a 32 byte string prefixed by `0x`.

## `AssetId`

A 32 byte unique ID used to identify a coin. On the testnet, the `assetId` is `0x0000000000000000000000000000000000000000000000000000000000000000`.

## `BlobId`

A unique hash identifier for a blob transaction.

## `BlockId`

A unique hash identifier for a block.

## `Bytes32`

32 bytes to hold arbitrary data, usually as a hex string. `Bytes32` is the base type for cryptographic primitives like `Address` or `Message`.

## `ContractId`

A wrapped 32byte hash that is used to uniquely identify a contract.

## `HexString`

A way to pass in bytes as hex data. This is used for variable byte length types. Predicates and predicate data are always a hex string.

## `Nonce`

A random or pseudo-random number generated for a single use to ensure data freshness and prevent replay attacks.

## `RelayedTransactionId`

The ID for a relayed transaction.

## `Salt`

Sometimes referred to as a nonce. A unique, random value used to distinguish two things that are otherwise identical. This is used in contract deployments so you can deploy contracts that are otherwise exactly the same.

## `Signature`

A cryptographic signature used to authorize messages and transactions.

## `Tai64Timestamp`

A TAI 64 timestamp.

## `TransactionId`

A unique 32 byte hash identifier for a transaction.

## `TxPointer`

The location of the transaction in the block. It can be used by UTXOs as a reference to the transaction or by the transaction itself to make it unique.

## `U16`

Unsigned 16 bit integer.

## `U32`

Unsigned 32 bit integer.

## `U64`

Unsigned 64 bit integer. The default GraphQL `int` scalar does not cover the range of values needed because the FuelVM word size is 64bit.

## `UtxoId`

A unique 32 byte identifier for a UTXO.


---

### File: docs/nightly/fuel-graphql-docs/docs/reference/subscriptions.md


# Subscriptions

## `statusChange`

Returns a stream of [`TransactionStatus!`](/docs/reference/unions/#transactionstatus) updates for the given transaction id if the current status is `[TransactionStatus::Submitted]`.

This stream will wait forever so it's advised to use within a timeout. It is possible for the stream to miss an update if it is polled slower then the updates arrive. In such a case the stream will close without a status. If this occurs the stream can simply be restarted to return the latest status.

**args:**

`id`: [`TransactionId!`](/docs/reference/scalars/#transactionid)

The id of the transaction to stream status updates for.

## `submitAndAwait`

Submits a transaction to the `TxPool` and await returns the [`TransactionStatus!`](/docs/reference/unions/#transactionstatus).

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.

## `submitAndAwaitStatus`

Submits the transaction to the `TxPool` and returns a stream of events. Compared to the [`submitAndAwait`](/docs/reference/subscriptions/#submitandawait), the stream also contains [`SubmittedStatus`](/docs/reference/objects/#submittedstatus) as an intermediate state.

**args:**

`tx`: [`HexString!`](/docs/reference/scalars/#hexstring)

The transaction hex string.


---

### File: docs/nightly/fuel-graphql-docs/docs/reference/unions.md


# Union Types

## `CoinType`

The type of coin being used.

**Types:**

[`Coin`](/docs/reference/objects/#coin): A standard coin.

[`MessageCoin`](/docs/reference/objects/#messagecoin): A message coin.

## `Consensus`

The type of consensus mechanism used to validate a block.

**Types:**

[`Genesis`](/docs/reference/objects/#genesis): Genesis consensus

[`PoAConsensus`](/docs/reference/objects/#poaconsensus): PoA
consensus

## `DependentCost`

Contains the dependent cost of opcodes.

**Types:**

[`LightOperation`](/docs/reference/objects/#lightoperation): Operations that can process many units with 1 gas

[`HeavyOperation`](/docs/reference/objects/#heavyoperation): Operations that require more than 1 gas to process a single unit

## `DryRunTransactionStatus`

The status of a transaction dry run.

**Types:**

[`DryRunSuccessStatus`](/docs/reference/objects/#dryrunsuccessstatus): The transaction dry run was successful.

[`DryRunFailureStatus`](/docs/reference/objects/#dryrunfailurestatus): The transaction dry run failed.

## `Input`

An input type for a transaction.

**Types:**

[`InputCoin`](/docs/reference/objects/#inputcoin): An input type for
a coin.

[`InputContract`](/docs/reference/objects/#inputcontract): An input
type for a contract.

[`InputMessage`](/docs/reference/objects/#inputmessage): An input
type for a message.

## `Output`

An output type for a transaction.

**Types:**

[`CoinOutput`](/docs/reference/objects/#coinoutput): Indicates coins
were forwarded from one address to another.
Can be used during transaction creation when the recipient, asset, and amount is known.

[`ContractOutput`](/docs/reference/objects/#contractoutput):
Indicates the transaction updated the state of a contract.

[`ChangeOutput`](/docs/reference/objects/#changeoutput): Indicates
that the output's amount may vary based on transaction execution, but is
otherwise identical to a Coin output. Output changes are always guaranteed to
have an amount of zero since they're only set after execution terminates.

[`VariableOutput`](/docs/reference/objects/#variableoutput): Similar
to `ChangeOutput`, this output type indicates that the output's amount may vary
based on transaction execution, but is otherwise identical to a Coin output. On
initialization, the amount on variable outputs is zero, but during execution
they could be set to a non-zero value.

[`ContractCreated`](/docs/reference/objects/#contractcreated):
Indicates a contract was deployed.

## `RelayedTransactionStatus`

The status of a relayed transaction from a L1. If the transaction is valid, it will be included in part of a block. If the transaction is invalid, it will be skipped.

**Types:**

[`RelayedTransactionFailed`](/docs/reference/objects/#relayedtransactionfailed): Details about why the relayed transaction failed.

## `TransactionStatus`

The status type of a transaction.

**Types:**

[`SubmittedStatus`](/docs/reference/objects/#submittedstatus): The transaction has been submitted.

[`SuccessStatus`](/docs/reference/objects/#successstatus): The transaction has succeeded.

[`SqueezedOutStatus`](/docs/reference/objects/#squeezedoutstatus): The transaction was kicked out of the mempool.

[`FailureStatus`](/docs/reference/objects/#failurestatus): The transaction has failed.

## `UpgradePurpose`

The purpose of a network upgrade.

**Types:**

[`ConsensusParametersPurpose`](/docs/reference/objects/#consensusparameterspurpose): The consensus parameters are being upgraded.

[`StateTransitionPurpose`](/docs/reference/objects/#statetransitionpurpose): The state transition is being upgraded.


---

### File: docs/nightly/fuel-specs/src/abi/argument-encoding.md

# Argument Encoding

## Version 0

> :warning: This version is being deprecated for Version 1 (see below).

When crafting transaction script data, you must encode the arguments you wish to pass to the script.

### Types

These are the available types that can be encoded in the ABI:

- Unsigned integers:
  - `u8`, 8 bits.
  - `u16`, 16 bits.
  - `u32`, 32 bits.
  - `u64`, 64 bits.
  - `u128`, 128 bits.
  - `u256`, 256 bits.
- Boolean: `bool`, either `0` or `1` encoded identically to `u8`.
- B256: `b256`, arbitrary 256-bits value.
- Address : `address`, a 256-bit (32-byte) address.
- Fixed size string
- Array
- Enums (sum types)
- Structs
- Vectors
- Tuples

These types are encoded in-place. Here's how to encode them. We define `enc(X)` the encoding of the type `X`.

### Unsigned Integers

`u<M>` where `M` is either 8, 16, 32, 64, 128 or 256 bits.

`enc(X)` is the big-endian (i.e. right-aligned) representation of `X` left-padded with zero-bytes.

- In the case of `M` being 8, 16, 32 or 64, total length must be 8 bytes.
- If `M` is 128, total length must be 16 bytes.
- If `M` is 256, total length must be 32 bytes.

> **Note:** since all integer values are unsigned, there is no need to preserve the sign when extending/padding; padding with only zeroes is sufficient._

**Example:**

Encoding `42` yields: `0x000000000000002a`, which is the hexadecimal representation of the decimal number `42`, right-aligned to 8 bytes.
Encoding `u128::MAX - 1` yields: `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE`, it's right-aligned to 16 bytes

### `Boolean`

`enc(X)` is `0` if `X` is false or `1` if `X` is true, left-padded with zero-bytes. Total length must be 8 bytes. Similar to the `u8` encoding.

**Example:**

Encoding `true` yields:

```text
0x0000000000000001
```

### `B256`

`b256` is a fixed size bit array of length 256. Used for 256-bit hash digests and other 256-bit types. It is encoded as-is.

**Example:**

Encoding `0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745` yields:

```text
0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745
```

### `Address`

A 256-bit (32-byte) address, encoded in the same way as a `b256` argument: encoded as-is.

**Example:**

Encoding `0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745` yields:

```text
0xc7fd1d987ada439fc085cfa3c49416cf2b504ac50151e3c2335d60595cb90745
```

### Array

An array of a certain type `T`, `[T; n]`, where `n` is the length of the array.

Arrays in Sway have a fixed-length which is known at compile time. This means the ABI encoding for arrays also happens in-place, with no need to account for dynamic sizing.

The encoding for the array contains, in order, the encoding of each element in `[T; n]`, recursively following the encoding for the type `T`.

For instance, consider the function signature `my_func(bool, [u64; 2])` with the values `(true, [1, 2])`.

The encoding will be:

1. `0x0000000000000001`, the `true` bool encoded in-place.
2. `0x0000000000000001`, First element of the parameter `[u64; 2]`, `1`, encoded as a `u64`.
3. `0x0000000000000002`, Second element of the parameter `[u64; 2]`, `2`, encoded as a `u64`.

The resulting encoded ABI will be:

```text
0x000000000000000100000000000000010000000000000002
```

### Fixed-length Strings

Strings have fixed length and are encoded in-place. `str[n]`, where `n` is the fixed-size of the string. Rather than padding the string, the encoding of the elements of the string is tightly packed. And unlike the other type encodings, the string encoding is left-aligned.

Note that all strings are encoded in UTF-8.

**Example:**

Encoding `"Hello, World"` as a `str[12]` **yields**:

```text
0x48656c6c6f2c20576f726c6400000000
```

Note that we're padding with zeroes in order to keep it right-aligned to 8 bytes (FuelVM's word size).

### Structs

Encoding ABIs that contain custom types, such as structs, is similar to encoding a set of primitive types. The encoding will proceed in the order that the inner types of a custom type are declared and _recursively_ just like encoding any other type. This way you can encode structs with primitive types or structs with more complex types in them such as other structs, arrays, strings, and enums.

Here's an example:

```rust
struct InputStruct {
    field_1: bool,
    field_2: u8,
}


abi MyContract {
    fn foo(a: u64);
    fn bar(a: InputStruct);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `InputStruct { field_1: true, field_2: 5 }` yields:

```plaintext
0x
0000000000000001 // `true` encoded as a bool
0000000000000005 // `5` encoded as u8
```

A more complex scenario:

```rust
struct InputStruct {
    field_1: bool,
    field_2: [u8; 2], // An array of u8, with length 2.
}


abi MyContract {
    fn foo(a: u64);
    fn bar(a: InputStruct);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `InputStruct { field_1: true, field_2: [1, 2] }` yields:

```plaintext
0x
0000000000000001 // `true` encoded as a bool
0000000000000001 // `1` encoded as u8
0000000000000002 // `2` encoded as u8
```

### Enums (sum types)

ABI calls containing enums (sum types) are encoded similarly to structs: encode the discriminant first, then recursively encode the type of the enum variant being passed to the function being called.

```rust
enum MySumType
{
    X: u32,
    Y: bool,
}

abi MyContract {
    fn foo(a: u64);
    fn bar(a: MySumType);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `MySumType::X(42)` yields:

```plaintext
0x
0000000000000000 // The discriminant of the chosen enum, in this case `0`.
000000000000002a // `42` encoded as u64
```

If the sum type has variants of different sizes, then left padding is required.

```rust
enum MySumType
{
    X: b256,
    Y: u32,
}

abi MyContract {
    fn foo(a: u64);
    fn bar(a: MySumType);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `MySumType::Y(42)` yields:

```plaintext
0x
0000000000000001 // The discriminant of the chosen enum, in this case `1`.
0000000000000000 // Left padding
0000000000000000 // Left padding
0000000000000000 // Left padding
000000000000002a // `42` encoded as u64
```

Note that three words of padding are required because the largest variant of `MySumType` is 4 words wide.

If all the variants of a sum type are of type `()`, or unit, then only the discriminant needs to be encoded.

```rust
enum MySumType
{
    X: (),
    Y: (),
    Z: (),
}

abi MyContract {
    fn foo(a: u64);
    fn bar(a: MySumType);
} {
    fn baz(a: ()) { }
}
```

Calling `bar` with `MySumType::Z` yields:

```plaintext
0x
0000000000000002 // The discriminant of the chosen enum, in this case `2`.
```

### Vectors

ABI calls containing vectors are encoded in the following way:

- First, figure out the the length `l` of the vector. Its length will also be its capacity.
- Encode the content of the vector according to the spec of its type, e.g. for a `Vec<bool>`,
  encode each `bool` element according to the `bool` specs. This gives out data that is stored
  on the heap, and we encode only the pointer to this data

```rust
abi MyContract {
  fn foo(a: Vec<u32>);
} {
  fn foo(a: Vec<u32>) {};
}
```

Calling `foo` with `vec![1u32, 2u32, 3u32, 4u32]`:

- `length` is 4, `capacity` is 4
- `data`: [0x0000000000000001, 0x0000000000000002, 0x0000000000000003, 0x0000000000000004], stored at pointer address `0x000000000000beef`

> Note: to understand how the `u32` are encoded, see the section about encoding integers.

```plaintext
0x
000000000000beef // pointer address
0000000000000004 // length = 4
0000000000000004 // capacity = 4
```

At the pointer address, then the vector's content are encoded as such:

```plaintext
0x
0000000000000001 // 1u32
0000000000000002 // 2u32
0000000000000003 // 3u32
0000000000000004 // 4u32
```

### Tuples

ABI calls containing tuples are encoded as such:
If `X` is a tuple with the type signature `(T_1, T_2, ..., T_n)`, with `T_1,...,T_n` being any type except for vector, then `enc(X)` is encoded as the concatenation of `enc(T_1)`, `enc(T_2)`,`enc (T_3)`, ..., `enc(T_n)`.

```rust
abi MyContract {
  fn foo(a: (u64, str[3], bool));
} {
  fn foo(a: (u64, str[4], bool)) {};
}
```

Calling `foo` with `(1u64, "fuel", true)` :

```plaintext
0x
0000000000000001 // 1u64
6675656c00000000 // "fuel" encoded as per the specs
0000000000000001 // true
```

## Version 1

This version was created to replace the older version 0 described above, and follows three philosophical tenets:

- being self-sufficient: it must be possible to completely decode the original data only using the encoded bytes and the original type (there are no references to data outside the encoded bytes);
- no overhead: only the bare minimum bytes are necessary to do the encoding. No metadata, headers, etc...;
- no relation with runtime memory layout: no padding, no alignment, etc...

### Primitive Types

Primitive types will be encoded using the exact number of bits they need:

- `u8`: 1 byte;
- `u16`: 2 bytes;
- `u32`: 4 bytes;
- `u64`: 8 bytes;
- `u256`: 32 bytes;
- `b256`: 32 bytes;

### Arrays

Arrays are encoded without any padding or alignment, with one item after the other.

- [T; 1] is encoded [encode(T)];
- [T; 2] is encoded [encode(T), encode(T)]

### Strings

String arrays are encoded just like arrays, without any overhead.

- `str[1]` = 1 byte
- `str[2]` = 2 bytes
- `str[n]` = `n` bytes

String slices do contain their length as u64, and the string itself is encoded packed without alignment or padding.

- `"abc"` = `[0, 0, 0, 0, 0, 0, 0, 3, "a", "b", "c"]`

### Slices

`raw_slice`, also being dynamic, contains their length as u64 and is treated as a "slice of bytes". Each byte is encoded as `u8` (1 byte) and is packed without alignment and padding.

For example, a slice of three bytes like `[0u8, 1u8, 2u8]` will be encoded as bytes `[0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2]`

### Tuple

Tuples are encoded just like arrays, without any overhead like padding and alignment:

- `(A, B, C)` = `[encode(A), encode(B), encode(C)]`

### Structs (v1)

Structs can be encoded in two ways:

- first, with the automatic implementation;
- second, with the custom implementation.

Auto implementation follows the same rules as tuples. So we can imagine that

```sway
struct S {
    a: A,
    b: B,
    c: C
}
```

is encoded the same way as the tuple `(A, B, C)`.

Custom implementation allows the developer to choose how a struct is encoded.

A struct has auto-implemented encoding if no custom was found.

### Enums

`Enums` can also be encoded with the automatic or the custom implementation.

The auto implementation first encoded the variant with a `u64` number starting from zero as the first variant and increments this value for each variant, following declaration order.

```sway
enum E {
    VARIANT_A: A, // <- variant 0
    VARIANT_B: B, // <- variant 1
    VARIANT_C: C  // <- variant 2 
}
```

will be encoded as `[encode(variant), encode(value)]`.

The variant data will be encoded right after the variant tag, without any alignment or padding.

An enum has auto-implemented encoding if no custom was found.

### Data Structures

Some common data structures also have well-defined encoding:

- `Vec` will be encoded as `[encode(length), <encode each item>]`
- `Bytes` will be encoded as `[encode(length), <bytes>]`
- `String` will be encoded as `[encode (length), <data>]`

All of them first contain the length and then their data right after, without any padding or alignment.


---

### File: docs/nightly/fuel-specs/src/abi/fn-selector-encoding.md

# Function Selector Encoding

To select which function you want to call, first, this function must be in an ABI struct of a Sway program. For instance:

```rust
abi MyContract {
    fn foo(a: u64);
    fn bar(a: InputStruct );
} {
    fn baz(a: ()) { }
}
```

The function selector is the first 4 bytes of the SHA-256 hash function of the signature of the Sway function being called. Then, these 4 bytes are right-aligned to 8 bytes, left-padded with zeroes.

> **Note**: The word size for the FuelVM is 8 bytes.

## Function Signature

The signature is composed of the function name with the parenthesized list of comma-separated parameter types without spaces. All strings encoded with UTF-8. For custom types such as `enum` and `struct`, there is a prefix added to the parenthesized list (see below). Generic `struct` and `enum` types also accept a list of comma-separated type arguments in between angle brackets right after the prefix.

For instance, to compute the selector for the following function:

```rust
    fn entry_one(arg: u64);
```

we should pass `"entry_one(u64)"` to the `sha256()` hashing algorithm. The full digest would be:

```text
0x0c36cb9cb766ff60422db243c4fff06d342949da3c64a3c6ac564941f84b6f06
```

Then we would get only the first 4 bytes of this digest and left-pad it to 8 bytes:

```text
0x000000000c36cb9c
```

The table below summarizes how each function argument type is encoded

| Type       | Encoding                                                                                                                                                                    |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bool`     | `bool`                                                                                                                                                                      |
| `u8`       | `u8`                                                                                                                                                                        |
| `u16`      | `u16`                                                                                                                                                                       |
| `u32`      | `u32`                                                                                                                                                                       |
| `u64`      | `u64`                                                                                                                                                                       |
| `b256`     | `b256`                                                                                                                                                                      |
| `struct`   | `s<<arg1>,<arg2>,...>(<ty1>,<ty2>,...)` where `<ty1>`, `<ty2>`, ... are the encoded types of the struct fields and `<arg1>`, `<arg2>`, ... are the encoded type arguments   |
| `enum`     | `e<<arg1>>,<arg_2>,...>(<ty1>,<ty2>,...)` where `<ty1>`, `<ty2>`, ... are the encoded types of the enum variants and `<arg1>`, `<arg2>`, ... are the encoded type arguments |
| `str[<n>]` | `str[<n>]`                                                                                                                                                                  |
| `array`    | `a[<ty>;<n>]` where `<ty>` is the encoded element type of the array and `<n>` is its length                                                                                 |
| `tuple`    | `(<ty1>,<ty2>,...)` where `<ty1>`, `<ty2>`, ... are the encoded types of the tuple fields                                                                                   |

> **Note:** Non-generic structs and enums do not require angle brackets.

## A Complex Example

```rust
enum MyEnum<V> {
    Foo: u64,
    Bar: bool,
}
struct MyStruct<T, U> {
    bim: T,
    bam: MyEnum<u64>,
}

struct MyOtherStruct {
    bom: u64,
}

fn complex_function(
    arg1: MyStruct<[b256; 3], u8>,
    arg2: [MyStruct<u64, bool>; 4],
    arg3: (str[5], bool),
    arg4: MyOtherStruct,
);
```

is encoded as:

```text
abi MyContract {
    complex_function(s<a[b256;3],u8>(a[b256;3],e<u64>(u64,bool)),a[s<u64,bool>(u64,e<u64>(u64,bool));4],(str[5],bool),s(u64))
}
```

which is then hashed into:

```text
51fdfdadc37ff569e281a622281af7ec055f8098c40bc566118cbb48ca5fd28b
```

and then the encoded function selector is:

```text
0x0000000051fdfdad
```


---

### File: docs/nightly/fuel-specs/src/abi/hash-based-ids.md

# Hash based IDs

Hash based ids are deterministically generated from associated types and are used in the JSON ABI for `type` IDs and for `logId`.
This document specifies how the hash based IDS are generated for `type` IDs and for `logId`.

## Generation

Hash based ids for `type` IDs are generated from the `sha256` of a string that represents the type.

For `logIds` we use the first 8 bytes of the `sha256` of a string that represents the type, this is because the `LOG` and `LOGD` opcodes use a 64bit value as log id.

## String representation of types

For describing the string representation of type we will use the notation `{abi_str(T)}` that should be replaced by the respective ABI string representation of the respective type `T`.

### Intrinsics

 `u8`   => `"u8"`
 `u16`  => `"u16"`
 `u32`  => `"u32"`
 `u64`  => `"u64"`
 `u256` => `"u256"`
 `b256` => `"b256"`
 `bool` => `"bool"`

### String arrays

  String array of size `1` => `"str[1]"`
  String array of size `2` => `"str[2]"`
  etc.

### String slices

  String slice => `"str"`

### Arrays

 `[T; 1]` => `"[{abi_str(T)}; 1]"`
 `[T; 2]` => `"[{abi_str(T)}; 2]"`
etc.

### Tuples

 `()`      => `"()"`
 `(T1)`    => `"({abi_str(T1)})"`
 `(T1,T2)` => `"({abi_str(T1)}, {abi_str(T2)})"`
etc.

### Enums

  `Option` enum with type parameter `T` => `"enum std::option::Option<{abi_str(T)}>"`
  Enum without type parameters named `MyEnum` => `"enum MyEnum"`
  Enum with type parameter `T1` named `MyEnum` => `"enum MyEnum<{abi_str(T1)}>"`
  Enum with type parameters `T1`, `T2` named `MyEnum` in `my_module` => `"enum my_module::MyEnum<{abi_str(T1)},{abi_str(T2)}>"`

### Structs

  `Vec` struct with type parameter `T` => `"struct std::vec::Vec<{abi_str(T)}>"`
  Struct without type parameters named `MyStruct` => `"struct MyStruct"`
  Struct with type parameter `T1` named `MyStruct` => `"struct MyStruct<{abi_str(T1)}>"`
  Struct with type parameters `T1`, `T2` named `MyStruct` in `my_module` => `"struct my_module::MyStruct<{abi_str(T1)},{abi_str(T2)}>"`

### Generic Type Parameter

 Generic type parameter `T` if root type => `"generic T"`
 Generic type parameter `T` if not root type => `"T"` as in `"struct MyStruct<T>"`

### Complex examples composition

 Tuple of array and `u64` => `"([u64,1]; u64)"`
 Array of `Option<u64>`=> `"[enum std::option::Option<u64>; 3]"`
 Struct with tuple type parameter => `"struct my_module::MyStruct<(u64, u64)>"`


---

### File: docs/nightly/fuel-specs/src/abi/index.md

# Application Binary Interface (ABI)

This document describes and specifies the ABI (Application Binary Interface) of the FuelVM, the Sway programming language, and contracts written in Sway.

- [JSON ABI Format](./json-abi-format.md)
- [Receipts](./receipts.md)
- [Function Selector Encoding](./fn-selector-encoding.md)
- [Argument Encoding](./argument-encoding.md)
- [Hash Based Ids](./hash-based-ids.md)


---

### File: docs/nightly/fuel-specs/src/abi/json-abi-format.md

# JSON ABI Format

The JSON of an ABI is the human-readable representation of the interface of a Sway contract.

## Spec Version

Current `specVersion` is `1.0`

The version above should be updated each time this spec changes and the JSON ABI generator should be updated with the new changes along with an increment in the spec version.

## Notation

Before describing the format of the JSON ABI, we provide some definitions that will make the JSON ABI spec easier to read.

Given the example below:

```rust
struct Foo { x: bool }
struct Bar<T> { y: T }

fn baz(input1: Foo, input2: Bar<u64>); // an ABI function
```

we define the following expressions:

- _type concrete declaration_: the declaration or definition of a type which can be generic. `struct Foo { .. }` and `struct Bar<T> { .. }` in the example above are both type declarations. Note that generic types may have multiple _type concrete declaration_.
- _type metadata declaration_: the declaration or definition of a type which can be generic. `struct Foo { .. }` and `struct Bar<T> { .. }` in the example above are both type declarations. The metadata declaration contains component details about the type. And a single _type metadata declaration_ is generated per type, even for generic types.
- _type application_: the application or use of a type. `Foo` and `Bar<u64>` in `fn baz(input1: Foo, input2: Bar<u64>);` in the example above are both applications of the type declarations `struct Foo { .. }` and `struct Bar<T> { .. }` respectively.
- _type parameter_: a generic parameter used in a type declaration. `T` in `struct Bar<T>` in the example above is a type parameter.
- _type argument_: an application of a type parameter used in a type application. `u64` in `input2: Bar<u64>` in the example above is a type argument.

## JSON ABI Spec

The ABI of a contract is represented as a JSON object containing the following properties:

- `"specVersion"`: a string representing the version pointing to this document versioning. `specVersion` enables the reader of the JSON ABI to find the correct specification for that file, this can be done by comparing it to value in [spec version](#spec-version).
- `"encodingVersion"`: a string representing the version of the `ABIEncode` and `ABIDecode` used in this program.
- `"programType"`: a string that can be `"script"`, `"contract"`, `"predicate"`, `"library"`. This is used by the SDK to generate types without having to manually specify the program type.
- `"concreteTypes"`: an array describing all the _type concrete declarations_ used (or transitively used) in the ABI. Each _type concrete declaration_ is a JSON object that contains the following properties:
  - `"type"`: a string representing the type, the `sha256` of this string generates the `concreteTypeId`.
  - `"concreteTypeId"`: a unique string hash based ID. Generated as specified in [Hash Based Ids](./hash-based-ids.md).
  - `"metadataTypeId"`: the _type metadata declaration_ ID of this type, if the type metadata has components or is generic, otherwise nonexistent.
  - `"typeArguments"`: an array of _type concrete declarations_ hash based IDs of the type parameters of the type, if the type is generic, otherwise nonexistent.
- `"metadataTypes"`: an array describing all the _type metadata declarations_ used (or transitively used) in the ABI. Each _type metadata declaration_ is a JSON object that contains the following properties:
  - `"type"`: a string representation of the _type metadata declaration_. The section [JSON ABI Format for Each Possible Metadata Type Declaration](#json-abi-format-for-each-possible-metadata-type-declaration) specifies the format for each possible type.
  - `"metadataTypeId"`: a unique integer ID.
  - `"components"`: an array of the components of a given type, if any, otherwise nonexistent. Each component is a _type application_ represented as a JSON object that contains the following properties:
    - `"name"`: the name of the component.
    - `"typeId"`: the _type metadata declaration_ ID (number) or _type concrete declaration_ hash based ID (string) of the type of the component.
    - `"typeArguments"`: an array of the _type arguments_ used when applying the type of the component, if the type is generic, otherwise nonexistent. Each _type argument_ is a _type application_ represented as a JSON object that contains the following properties:
      - `"name"`: the name of the _type argument_.
      - `"typeId"`: the _type metadata declaration_ ID (number) or _type concrete declaration_ hash based ID (string) of the type of the component.
      - `"typeArguments"`: an array of the _type arguments_ used when applying the type of the _type argument_, if the type is generic, otherwise nonexistent. The format of the elements of this array recursively follows the rules described in this section.
  - `"typeParameters"`: an array of _type metadata declaration_ ID of the _type parameters_ of the type, if the type is generic, otherwise nonexistent. Each _type parameter_ is a type declaration and is represented as described in [Generic Type Parameter](#generic-type-parameter).
- `"functions`": an array describing all the functions in the ABI. Each function is a JSON object that contains the following properties:
  - `"name"`: the name of the function
  - `"inputs"`: an array of objects that represents the inputs to the function (i.e. its parameters). Each input is a _type application_ represented as a JSON object that contains the following properties:
    - `"name"`: the name of the input.
    - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the type of the input.
  - `"output"`: the _type concrete declaration_ hash based ID of the type being returned by the function.
  - `"attributes"`: an optional array of _attributes_. Each _attribute_ is explained in the [dedicated section](#attributes-semantics) and is represented as a JSON object that contains the following properties:
    - `"name"`: the name of the attribute.
    - `"arguments"`: an array of attribute arguments.
- `"loggedTypes"`: an array describing all instances of [`log`](../fuel-vm/instruction-set.md#log-log-event) or [`logd`](../fuel-vm/instruction-set.md#logd-log-data-event) in the contract's bytecode. Each instance is a JSON object that contains the following properties:
  - `"logId"`: a string containing the 64bit hash based decimal ID calculated from the first 8 bytes of the `sha256` of a string that represents the type logged as defined in [Hash Based Ids](./hash-based-ids.md). The [`log`](../fuel-vm/instruction-set.md#log-log-event) and [`logd`](../fuel-vm/instruction-set.md#logd-log-data-event) instructions must set their `$rB` register to that ID.
  - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the value being logged.
- `"messagesTypes"`: an array describing all instances of [`smo`](../fuel-vm/instruction-set.md#smo-send-message-to-output) in the contract's bytecode. Each instance is a JSON object that contains the following properties:
  - `"messageId"`: a unique string ID.
  - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the message data being sent.
- `"configurables"`: an array describing all `configurable` variables used in the contract. Each `configurable` variable is represented as a JSON object that contains the following properties:
  - `"name"`: the name of the `configurable` variable.
  - `"concreteTypeId"`: the _type concrete declaration_ hash based ID of the type of the `configurable` variable.
  - `"offset"`: the specific offset within the contract's bytecode, in bytes, to the data section entry for the `configurable` variable.

> **Note**: This JSON should be both human-readable and parsable by the tooling around the FuelVM and the Sway programming language. There is a detailed specification for the binary encoding backing this readable descriptor. The [Function Selector Encoding](./fn-selector-encoding.md) section specifies the encoding for the function being selected to be executed and each of the argument types.

### Attributes Semantics

| Attribute name | Attribute arguments               | Semantics                                                                                              |
|----------------|-----------------------------------|--------------------------------------------------------------------------------------------------------|
| `storage`      | `read` and/or `write`             | Specifies if a function reads or writes to/from storage                                                |
| `payable`      | None                              | Specifies if a function can accept coins: a function without `payable` attribute must not accept coins |
| `test`         | None                              | Specifies if a function is a unit test                                                                 |
| `inline`       | `never` or `always`, but not both | Specifies if a function should be inlined during code generation                                       |
| `doc-comment`  | String                            | Documentation comment                                                                                  |
| `doc`          | Not defined yet                   | Not defined yet                                                                                        |

## A Simple Example

Below is a simple example showing how the JSON ABI for an example that does not use generic or complex types. We will later go over more complex examples.

```rust
abi MyContract {
    fn first_function(arg: u64) -> bool;
    fn second_function(arg: b256);
}
```

the JSON representation of this ABI looks like:

```json
{
  "concreteTypes": [
    {
      "type": "u64",
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    },
    {
      "type": "b256",
      "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
    },
    {
      "type": "bool",
      "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "metadataTypes": [],
  "functions": [
    {
      "inputs": [
        {
          "name": "arg",
          "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
        }
      ],
      "name": "first_function",
      "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
    },
    {
      "inputs": [
        {
          "name": "arg",
          "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
        }
      ],
      "name": "second_function",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "loggedTypes": []
}
```

## JSON ABI Format for Each Possible Metadata Type Declaration

Below is a list of the JSON ABI formats for each possible metadata type declaration:

### `struct`

```json
{
  "metadataTypeId": <id>,
  "type": "struct <struct_name>",
  "components": [
    {
      "name": "<field1_name>",
      "typeId": "<field1_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    {
      "name": "<field2_name>",
      "typeId": "<field2_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    ...
  ],
  "typeParameters": [
    <type_param1_type_id>,
    <type_param2_type_id>,
    ...
  ]
}
```

### `enum`

```json
{
  "metadataTypeId": <id>,
  "type": "enum <enum_name>",
  "components": [
    {
      "name": "<variant1_name>",
      "typeId": "<variant1_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    {
      "name": "<variant2_name>",
      "typeId": "<variant2_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    ...
  ],
  "typeParameters": [
    <type_param1_type_id>,
    <type_param2_type_id>,
    ...
  ]
}
```

### `array`

```json
{
  "metadataTypeId": <id>,
  "type": "[_; <n>]",
  "components": [
    {
      "name": "__array_element",
      "typeId": "<element_type>",
      "typeArguments": ...
    }
    {
      "name": "__array_element",
      "typeId": "<element_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
  ]
}
```

- `<n>` is the size of the array.

### `tuple`

```json
{
  "metadataTypeId": <id>,
  "type": "(_, _, ...)",
  "components": [
    {
      "name": "__tuple_element",
      "typeId": "<field1_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    {
      "name": "__tuple_element",
      "typeId": "<field2_type_id>",
      "typeArguments": [
        {
          "typeId": "<type_arg1_type_id>",
          "typeArguments": ...
        },
        {
          "typeId": "<type_arg2_type_id>",
          "typeArguments": ...
        },
        ...
      ]
    },
    ...
  ]
}
```

### Generic Type Parameter

```json
{
  "metadataTypeId": <id>,
  "type": "generic <name>"
}
```

`<name>` is the name of the generic parameter as specified in the struct or enum declaration that uses it.

## Some Complex Examples

### An Example with Non-Generic Custom Types

Given the following ABI declaration:

```rust
enum MyEnum {
    Foo: u64,
    Bar: bool,
}

struct MyStruct {
    bim: u64,
    bam: MyEnum,
}

abi MyContract {
    /// this is a doc comment
    #[payable, storage(read, write)]
    fn complex_function(
        arg1: ([str[5]; 3], bool, b256),
        arg2: MyStruct,
    );
}
```

its JSON representation would look like:

```json
{
  "concreteTypes": [
    {
      "type": "([str[5]; 3], bool, b256)",
      "concreteTypeId": "625531542be70834dd127e771101ac1014111718451bfae996d97abe700c66a5",
      "metadataTypeId": 1,
    },
    {
      "type": "str[5]",
      "concreteTypeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7",
    },
    {
      "type": "struct MyStruct",
      "concreteTypeId": "392d58c694d2d91f3025f2bccfadacf2a105936f5da881b0899185d49f264522",
      "metadataTypeId": 4,
    },
    {
      "type": "u64",
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    },
    {
      "type": "b256",
      "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
    },
    {
      "type": "bool",
      "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "metadataTypes": [
    {
      "metadataTypeId": 1,
      "type": "(_, _, _)",
      "components": [
        {
          "name": "__tuple_element",
          "typeId": 2,
        },
        {
          "name": "__tuple_element",
          "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
        },
        {
          "name": "__tuple_element",
          "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b",
        }
      ]
    },
    {
      "metadataTypeId": 2,
      "type": "[_; 3]",
      "components": [
        {
          "name": "__array_element",
          "typeId": "84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7",
        }
      ]
    },
    {
      "metadataTypeId": 3,
      "type": "enum MyEnum",
      "components": [
        {
          "name": "Foo",
          "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
        },
        {
          "name": "Bar",
          "typeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
        }
      ]
    },
    {
      "metadataTypeId": 4,
      "type": "struct MyStruct",
      "components": [
        {
          "name": "bim",
          "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
        },
        {
          "name": "bam",
          "typeId": 3,
        }
      ]
    },
  ],
  "functions": [
    {
      "inputs": [
        {
          "name": "arg1",
          "concreteTypeId": "625531542be70834dd127e771101ac1014111718451bfae996d97abe700c66a5",
        },
        {
          "name": "arg2",
          "concreteTypeId": "392d58c694d2d91f3025f2bccfadacf2a105936f5da881b0899185d49f264522"
        }
      ],
      "name": "complex_function",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d",
      "attributes": [
        {
          "name": "doc-comment",
          "arguments": [" this is a doc comment"]
        },
        {
          "name": "payable",
        },
        {
          "name": "storage",
          "arguments": ["read", "write"]
        }
      ]
    }
  ],
  "loggedTypes": []
}
```

### An Example with Generic Types

Given the following ABI declaration:

```rust
enum MyEnum<T, U> {
    Foo: T,
    Bar: U,
}
struct MyStruct<W> {
    bam: MyEnum<W, W>,
}

abi MyContract {
    fn complex_function(
        arg1: MyStruct<b256>,
    );
}
```

its JSON representation would look like:

```json
{
  "concreteTypes": [
    {
      "type": "struct MyStruct<b256>",
      "concreteTypeId": "3ddd5c1768dd7869663dc2f868ea8a8ce68bd6064244dbc4286e2c921c8ce962",
      "metadataTypeId": 5,
      "typeArguments": [
        "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b"
      ]
    },
    {
      "type": "b256",
      "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b",
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d",
    }
  ],
  "metadataTypes": [
    {
      "metadataTypeId": 1,
      "type": "enum MyEnum",
      "components": [
        {
          "name": "Foo",
          "typeId": 2,
        },
        {
          "name": "Bar",
          "typeId": 3,
        }
      ],
      "typeParameters": [2, 3]
    },
    {
      "metadataTypeId": 2,
      "type": "generic T",
    },
    {
      "metadataTypeId": 3,
      "type": "generic U",
    },
    {
      "metadataTypeId": 4,
      "type": "generic W",
    },
    {
      "metadataTypeId": 5,
      "type": "struct MyStruct",
      "components": [
        {
          "name": "bam",
          "typeId": 1,
          "typeArguments": [
            {
              "typeId": 4,
            },
            {
              "typeId": 4,
            }
          ]
        }
      ],
      "typeParameters": [4]
    }
  ],
  "functions": [
    {
      "inputs": [
        {
          "name": "arg1",
          "concreteTypeId": "3ddd5c1768dd7869663dc2f868ea8a8ce68bd6064244dbc4286e2c921c8ce962"
        }
      ],
      "name": "complex_function",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "loggedTypes": []
}
```

### An Example with Logs

Given the following contract:

```rust
struct MyStruct<W> {
    x: W,
}

abi MyContract {
    fn logging();
}

...

fn logging() {
    log(MyStruct { x: 42 });
    log(MyStruct { x: true });
}
```

its JSON representation would look like:

```json
{
  "concreteTypes": [
    {      
      "type": "struct MyStruct<bool>",
      "concreteTypeId": "eca2a040ce95fc19b7cd5f75bac530d052484d0b1a49267a2eb07a7a1b00c389",
      "metadataTypeId": 1,
      "typeArguments": [
        "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903"
      ]
    },
    {      
      "type": "struct MyStruct<u64>",
      "concreteTypeId": "b2fa346d9ca66ceca61951a27dba2977b2a82b8aa8600670604f286a1393dffe",
      "metadataTypeId": 1,
      "typeArguments": [
        "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
      ]
    },
    {      
      "type": "bool",
      "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903",
    },
    {      
      "type": "u64",
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
    },
    {
      "type": "()",
      "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d",
    }
  ],
  "metadataTypes": [
    {
      "metadataTypeId": 1,
      "type": "struct MyStruct",
      "components": [
        {
          "name": "x",
          "typeId": 2,
          "typeArguments": null
        }
      ],
      "typeParameters": [2]
    },
    {
      "metadataTypeId": 2,
      "type": "generic W",
    },
  ],
  "functions": [
    {
      "inputs": [],
      "name": "logging",
      "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d"
    }
  ],
  "loggedTypes": [
    {
      "logId": "12896678128313068780",
      "concreteTypeId": "b2fa346d9ca66ceca61951a27dba2977b2a82b8aa8600670604f286a1393dffe"
    },
    {
      "logId": "16383228984366451899",
      "concreteTypeId": "eca2a040ce95fc19b7cd5f75bac530d052484d0b1a49267a2eb07a7a1b00c389"
    }
  ]
}
```

The `logIds` are calculated from:

- First 8 bytes of `sha256("struct MyStruct<u64>")` => "12896678128313068780"
- First 8 bytes of `sha256("struct MyStruct<bool>")` => "16383228984366451899"


---

### File: docs/nightly/fuel-specs/src/abi/receipts.md

# Receipts

Upon execution of ABI calls, i.e scripts being executed, a JSON object representing a list of receipts will be returned to the caller. Below is the JSON specification of the possible receipt types. The root will be `receipts_root` which will include an array of `receipts`.

```json
{
  "receipts_list":[
    {
      "type":"<receipt_type>",
      ...
    },
    ...
  ]
}
```

All receipts will have a `type` property:

- `type`: String; the type of the receipt. Can be one of:
  - [`Call`](#call-receipt)
  - [`Return`](#return-receipt)
  - [`ReturnData`](#returndata-receipt)
  - [`Panic`](#panic-receipt)
  - [`Revert`](#revert-receipt)
  - [`Log`](#log-receipt)
  - [`Mint`](#mint-receipt)
  - [`Burn`](#burn-receipt)
  - [`LogData`](#logdata-receipt)
  - [`Transfer`](#transfer-receipt)
  - [`TransferOut`](#transferout-receipt)
  - [`ScriptResult`](#scriptresult-receipt)
  - [`MessageOut`](#messageout-receipt)

Then, each receipt type will have its own properties. Some of these properties are related to the FuelVM's registers, as specified in more detail [here](../fuel-vm/instruction-set.md).

_Important note:_ For the JSON representation of receipts, we represent 64-bit unsigned integers as a JSON `String` due to limitations around the type `Number` in the JSON specification, which only supports numbers up to `2^{53-1}`, while the FuelVM's registers hold values up to `2^64`.

## Panic Receipt

- `type`: `Panic`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `reason`: Optional decimal string representation of an 8-bit unsigned integer; panic reason.
  Not included in canonical receipt form.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.
- `contractId`: Optional hexadecimal string representation of the 256-bit (32-byte) contract ID if applicable. `null` otherwise.
  Not included in canonical receipt form. Primary use is for access-list estimation by SDK.

```json
{
  "type": "Panic",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "reason": "1",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe",
  "contractId": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
```

## `Return` Receipt

- `type`: `Return`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context; `null` otherwise.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Return",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "18446744073709551613",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Call` Receipt

- `type`: `Call`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context; `null` otherwise.
- `to`: Hexadecimal representation of the 256-bit (32-byte) contract ID of the callee.
- `amount`: Decimal string representation of a 64-bit unsigned integer; amount of coins to forward.
- `asset_id`: Hexadecimal string representation of the 256-bit (32-byte) asset ID of coins to forward.
- `gas`: Decimal string representation of a 64-bit unsigned integer; amount gas to forward; value in register `$rD`.
- `param1`: Hexadecimal string representation of a 64-bit unsigned integer; first parameter, holds the function selector.
- `param2`: Hexadecimal string representation of a 64-bit unsigned integer; second parameter, typically used for the user-specified input to the ABI function being selected.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Call",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "to": "0x1c98ff5d121a6d5afc8135821acb3983e460ef0590919266d620bfc7b9b6f24d",
  "amount": "10000",
  "asset_id": "0xa5149ac6064222922eaa226526b0d853e7871e28c368f6afbcfd60a6ef8d6e61",
  "gas": "500",
  "param1": "0x28f5c28f5c28f5c",
  "param2": "0x68db8bac710cb",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Log` Receipt

- `type`: `Log`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `ra`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `rb`: Decimal string representation of a 64-bit unsigned integer; value of register `$rB`.
- `rc`: Decimal string representation of a 64-bit unsigned integer; value of register `$rC`.
- `rd`: Decimal string representation of a 64-bit unsigned integer; value of register `$rD`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Log",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "ra": "1844674407370",
  "rb": "1844674407371",
  "rc": "1844674407372",
  "rd": "1844674407373",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Mint` Receipt

- `type`: `Mint`.
- `sub_id`: Hexadecimal string representation of the 256-bit (32-byte) asset sub identifier ID; derived from register `$rB`.
- `contract_id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Mint",
  "sub_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "contract_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "18446744073709551613",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Burn` Receipt

- `type`: `Burn`.
- `sub_id`: Hexadecimal string representation of the 256-bit (32-byte) asset sub identifier ID; derived from register `$rB`.
- `contract_id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Burn",
  "sub_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "contract_id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "18446744073709551613",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `LogData` Receipt

- `type`: `LogData`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `ra`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`
- `rb`: Decimal string representation of a 64-bit unsigned integer; value of register `$rB`
- `ptr`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$rC`.
- `len`: Decimal string representation of a 64-bit unsigned integer; value of register `$rD`.
- `digest`: Hexadecimal string representation of the 256-bit (32-byte) hash of `MEM[$rC, $rD]`.
- `data`: Hexadecimal string representation of the value of the memory range `MEM[$rC, $rD]`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "LogData",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "ra": "1844674407370",
  "rb": "1844674407371",
  "ptr": "0x1ad7f29abcc",
  "len": "66544",
  "digest": "0xd28b78894e493c98a196aa51b432b674e4813253257ed9331054ee8d6813b3aa",
  "pc": "0xffffffffffffffff",
  "data": "0xa7c5ac471b47",
  "is": "0xfffffffffffffffe"
}
```

## `ReturnData` Receipt

- `type`: `ReturnData`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `ptr`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `len`: Decimal string representation of a 64-bit unsigned integer; value of register `$rB`.
- `digest`: Hexadecimal string representation of 256-bit (32-byte), hash of `MEM[$rA, $rB]`.
- `data`: Hexadecimal string representation of the value of the memory range `MEM[$rA, $rB]`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "ReturnData",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "ptr": "0x1ad7f29abcc",
  "len": "1844",
  "digest": "0xd28b78894e493c98a196aa51b432b674e4813253257ed9331054ee8d6813b3aa",
  "pc": "0xffffffffffffffff",
  "data": "0xa7c5ac471b47",
  "is": "0xfffffffffffffffe"
}
```

## `Revert` Receipt

- `type`: `Revert`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `val`: Decimal string representation of a 64-bit unsigned integer; value of register `$rA`.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Revert",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "val": "1844674407372",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `Transfer` Receipt

- `type`: `Transfer`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `to`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the recipient contract.
- `amount`: Decimal string representation of a 64-bit unsigned integer; amount of coins to forward.
- `asset_id`: Hexadecimal string representation of the 256-bit (32-byte) asset ID of coins to forward.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "Transfer",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "to": "0x1c98ff5d121a6d5afc8135821acb3983e460ef0590919266d620bfc7b9b6f24d",
  "amount": "10000",
  "asset_id": "0xa5149ac6064222922eaa226526b0d853e7871e28c368f6afbcfd60a6ef8d6e61",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `TransferOut` Receipt

- `type`: `TransferOut`.
- `id`: Hexadecimal string representation of the 256-bit (32-byte) contract ID of the current context if in an internal context. `null` otherwise.
- `to`: Hexadecimal string representation of the 256-bit (32-byte) _address_ to transfer coins to.
- `amount`: Decimal string representation of a 64-bit unsigned integer; amount of coins to forward.
- `asset_id`: Hexadecimal string representation of the 256-bit (32-byte) asset ID of coins to forward.
- `pc`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$pc`.
- `is`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$is`.

```json
{
  "type": "TransferOut",
  "id": "0x39150017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "to": "0x1c98ff5d121a6d5afc8135821acb3983e460ef0590919266d620bfc7b9b6f24d",
  "amount": "10000",
  "asset_id": "0xa5149ac6064222922eaa226526b0d853e7871e28c368f6afbcfd60a6ef8d6e61",
  "pc": "0xffffffffffffffff",
  "is": "0xfffffffffffffffe"
}
```

## `ScriptResult` Receipt

- `type`: `ScriptResult`.
- `result`: Hexadecimal string representation of a 64-bit unsigned integer; `0` if script exited successfully, `any` otherwise.
- `gas_used`: Decimal string representation of a 64-bit unsigned integer; amount of gas consumed by the script.

```json
{
  "type": "ScriptResult",
  "result": "0x00",
  "gas_used": "400"
}
```

## `MessageOut` Receipt

- `type`: `MessageOut`.
- `sender`: Hexadecimal string representation of the 256-bit (32-byte) address of the message sender: `MEM[$fp, 32]`.
- `recipient`: Hexadecimal string representation of the 256-bit (32-byte) address of the message recipient: `MEM[$rA, 32]`.
- `amount`: Hexadecimal string representation of a 64-bit unsigned integer; value of register `$rD`.
- `nonce`: Hexadecimal string representation of the 256-bit (32-byte) message nonce as described [here](../identifiers/utxo-id.md#message-nonce).
- `len`: Decimal string representation of a 16-bit unsigned integer; value of register `$rC`.
- `digest`: Hexadecimal string representation of 256-bit (32-byte), hash of `MEM[$rB, $rC]`.
- `data`: Hexadecimal string representation of the value of the memory range `MEM[$rB, $rC]`.

```json
{
  "type": "MessageOut",
  "sender": "0x38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff05139150017c9e",
  "recipient": "0x4710162c2e3a95a6faff05139150017c9e38e5e280432d546fae345d6ce6d8fe",
  "amount": "0xe6d8fe4710162c2e",
  "nonce": "0x47101017c9e38e5e280432d546fae345d6ce6d8fe4710162c2e3a95a6faff051",
  "len": "65535",
  "digest": "0xd28b78894e493c98a196aa51b432b674e4813253257ed9331054ee8d6813b3aa",
  "data": "0xa7c5ac471b47"
}
```


---

### File: docs/nightly/fuel-specs/src/fuel-vm/index.md

# Fuel VM Specification

- [Introduction](#introduction)
- [Parameters](#parameters)
- [Semantics](#semantics)
- [Flags](#flags)
- [Instruction Set](#instruction-set)
- [VM Initialization](#vm-initialization)
- [Contexts](#contexts)
  - [Predicate Estimation and Verification](#predicate-estimation-and-verification)
  - [Script Execution](#script-execution)
  - [Call](#call)
- [Call Frames](#call-frames)
- [Ownership](#ownership)

## Introduction

This document provides the specification for the Fuel Virtual Machine (FuelVM). The specification covers the types, instruction set, and execution semantics.

## Parameters

| name                    | type     | value   | note                                    |
|-------------------------|----------|---------|-----------------------------------------|
| `CONTRACT_MAX_SIZE`     | `uint64` |         | Maximum contract size, in bytes.        |
| `VM_MAX_RAM`            | `uint64` | `2**26` | 64 MiB.                                 |
| `MESSAGE_MAX_DATA_SIZE` | `uint64` |         | Maximum size of message data, in bytes. |

## Semantics

FuelVM instructions are exactly 32 bits (4 bytes) wide and comprise of a combination of:

- Opcode: 8 bits
- Register/special register (see below) identifier: 6 bits
- Immediate value: 12, 18, or 24 bits, depending on operation

Of the 64 registers (6-bit register address space), the first `16` are reserved:

| value  | register | name                | description                                                                      |
|--------|----------|---------------------|----------------------------------------------------------------------------------|
| `0x00` | `$zero`  | zero                | Contains zero (`0`), for convenience.                                            |
| `0x01` | `$one`   | one                 | Contains one (`1`), for convenience.                                             |
| `0x02` | `$of`    | overflow            | Contains overflow/underflow of addition, subtraction, and multiplication.        |
| `0x03` | `$pc`    | program counter     | The program counter. Memory address of the current instruction.                  |
| `0x04` | `$ssp`   | stack start pointer | Memory address of bottom of current writable stack area.                         |
| `0x05` | `$sp`    | stack pointer       | Memory address on top of current writable stack area (points to free memory).    |
| `0x06` | `$fp`    | frame pointer       | Memory address of beginning of current call frame.                               |
| `0x07` | `$hp`    | heap pointer        | Memory address below the current bottom of the heap (points to used/OOB memory). |
| `0x08` | `$err`   | error               | Error codes for particular operations.                                           |
| `0x09` | `$ggas`  | global gas          | Remaining gas globally.                                                          |
| `0x0A` | `$cgas`  | context gas         | Remaining gas in the context.                                                    |
| `0x0B` | `$bal`   | balance             | Received balance for this context.                                               |
| `0x0C` | `$is`    | instructions start        | Pointer to the start of the currently-executing code.                            |
| `0x0D` | `$ret`   | return value        | Return value or pointer.                                                         |
| `0x0E` | `$retl`  | return length       | Return value length in bytes.                                                    |
| `0x0F` | `$flag`  | flags               | Flags register.                                                                  |

Integers are represented in [big-endian](https://en.wikipedia.org/wiki/Endianness) format, and all operations are unsigned. Boolean `false` is `0` and Boolean `true` is `1`.

Registers are 64 bits (8 bytes) wide. Words are the same width as registers.

Persistent state (i.e. storage) is a key-value store with 32-byte keys and 32-byte values. Each contract has its own persistent state that is independent of other contracts. This is committed to in a Sparse Binary Merkle Tree.

## Flags

| value  | name           | description                                                               |
|--------|----------------|---------------------------------------------------------------------------|
| `0x01` | `F_UNSAFEMATH` | If set, undefined arithmetic zeroes target and sets `$err` without panic. |
| `0x02` | `F_WRAPPING`   | If set, overflowing arithmetic wraps around and sets `$of` without panic. |

All other flags are reserved, any must be set to zero.

## Instruction Set

A complete instruction set of the Fuel VM is documented in [the following page](./instruction-set.md).

## VM Initialization

Every time the VM runs, a single monolithic memory of size `VM_MAX_RAM` bytes is allocated, indexed by individual byte. A stack and heap memory model is used, allowing for dynamic memory allocation in higher-level languages. The stack begins at `0` and grows upward. The heap begins at `VM_MAX_RAM` and grows downward.

To initialize the VM, the following is pushed on the stack sequentially:

1. Transaction hash (`byte[32]`, word-aligned), computed as defined [here](../identifiers/transaction-id.md).
1. Base asset ID (`byte[32]`, word-aligned)
1. [`MAX_INPUTS`](../tx-format/consensus_parameters.md) pairs of `(asset_id: byte[32], balance: uint64)`, of:
    1. For [predicate estimation and verification](#predicate-estimation-and-verification), zeroes.
    1. For [script execution](#script-execution), the free balance for each asset ID seen in the transaction's inputs, ordered in ascending order. If there are fewer than `MAX_INPUTS` asset IDs, the pair has a value of zero.
1. Transaction length, in bytes (`uint64`, word-aligned).
1. The [transaction, serialized](../tx-format/index.md).

Then the following registers are initialized (without explicit initialization, all registers are initialized to zero):

1. `$ssp = 32 + 32 + MAX_INPUTS*(32+8) + size(tx))`: the writable stack area starts immediately after the serialized transaction in memory (see above).
1. `$sp = $ssp`: writable stack area is empty to start.
1. `$hp = VM_MAX_RAM`: the heap area begins at the top and is empty to start.

## Contexts

There are 4 _contexts_ in the FuelVM: [predicate estimation and verification](#predicate-estimation-and-verification), [scripts](#script-execution), and [calls](#call). A context is an isolated execution environment with defined [memory ownership](#ownership) and can be _external_ or _internal_:

- External: predicate and script. `$fp` will be zero.
- Internal: call. `$fp` will be non-zero.

[Returning](./instruction-set.md#return-return-from-call) from a context behaves differently depending on whether the context is external or internal.

### Predicate Estimation and Verification

There are two ways to run predicates on the VM:

1. Estimation: runs the predicate and updates the amount of gas used
1. Verification: runs the predicate and verifies the amount of gas used matches the input

For any input of type [`InputType.Coin`](../tx-format/input.md#inputcoin) or [`InputType.Message`](../tx-format/input.md#inputmessage), a non-zero `predicateLength` field means the UTXO being spent is a [`P2SH`](https://en.bitcoin.it/P2SH) rather than a [`P2PKH`](https://en.bitcoin.it/P2PKH) output.

For each such input in the transaction, the VM is [initialized](#vm-initialization), then:

1. `$pc` and `$is` are set to the start of the input's `predicate` field.
1. `$ggas` and `$cgas` are set to `MAX_GAS_PER_PREDICATE` for estimation, and `predicateGasUsed` for verification.

Predicate execution will fail if gas is exhausted during execution.

During predicate mode, hitting any [contract instruction](./instruction-set.md#contract-instructions) (except `ldc` with non-contract target) causes predicate verification to halt, returning Boolean `false`.

A predicate that halts without returning Boolean `true` would not pass verification, making the entire transaction invalid. Note that predicate return value is monotonic with respect to time (i.e. if a predicate evaluates to `true` then it will always evaluate to `true` in the future).

After successful execution, the run mode is determines the final step:

1. Estimation: `predicateGasUsed` is set to `MAX_GAS_PER_PREDICATE - $ggas`.
1. Verification: if `$ggas` is non-zero, predicate verification fails.

### Script Execution

If script bytecode is present, transaction validation requires execution.

The VM is [initialized](#vm-initialization), then:

1. `$pc` and `$is` are set to the start of the transaction's script bytecode.
1. `$ggas` and `$cgas` are set to `tx.scriptGasLimit`.

Following initialization, execution begins.

For each instruction, its gas cost `gc` is first computed. If `gc > $cgas`, deduct `$cgas` from `$ggas` and `$cgas` (i.e. spend all of `$cgas` and no more), then [revert](./instruction-set.md#rvrt-revert) immediately without actually executing the instruction. Otherwise, deduct `gc` from `$ggas` and `$cgas`.

After the script has been executed, `tx.receiptsRoot` is updated to contain the Merkle root of the receipts, [as described in the `TransactionScript` spec](../tx-format/transaction.md#`TransactionScript`).

### Call

Call context is entered via [`CALL` instruction](./instruction-set.md#call-call-contract). It's also called _internal context_, or _contract context_. Call context is used to access state of a contract.

## Call Frames

Cross-contract calls push a _call frame_ onto the stack, similar to a stack frame used in regular languages for function calls (which may be used by a high-level language that targets the FuelVM). The distinction is as follows:

1. Stack frames: store metadata across trusted internal (i.e. intra-contract) function calls. Not supported natively by the FuelVM, but may be used as an abstraction at a higher layer.
1. Call frames: store metadata across untrusted external (i.e. inter-contract) calls. Supported natively by the FuelVM.

Call frames are needed to ensure that the called contract cannot mutate the running state of the current executing contract. They segment access rights for memory: the currently-executing contracts may only write to their own call frame and their own heap.

A call frame consists of the following, word-aligned:

| bytes | type          | value      | description                                                                   |
|-------|---------------|------------|-------------------------------------------------------------------------------|
|       |               |            | **Unwritable area begins.**                                                   |
| 32    | `byte[32]`    | `to`       | Contract ID for this call.                                                    |
| 32    | `byte[32]`    | `asset_id` | asset ID of forwarded coins.                                                  |
| 8*64  | `byte[8][64]` | `regs`     | Saved registers from previous context.                                        |
| 8     | `uint64`      | `codesize` | Code size in bytes, padded to the next word boundary.                         |
| 8     | `byte[8]`     | `param1`   | First parameter.                                                              |
| 8     | `byte[8]`     | `param2`   | Second parameter.                                                             |
| 1*    | `byte[]`      | `code`     | Zero-padded to 8-byte alignment, but individual instructions are not aligned. |
|       |               |            | **Unwritable area ends.**                                                     |
| *     |               |            | Call frame's stack.                                                           |

## Access rights

Only memory that has been allocated is accessible.
In other words, memory between highest-ever `$sp` value and current `$hp`
is inaccessible. Attempting to read or write
memory that has not been allocated will result in VM panic.
Similarly reads or writes that cross from the stack to the heap
will panic. Note that stack remains readable even after stack
frame has been shrunk. However, if the heap is afterwards expanded
to cover that area, the crossing read prohibition still remains,
while all memory is accessible.

### Ownership

Whenever memory is written to (i.e. with [`SB`](./instruction-set.md#sb-store-byte) or [`SW`](./instruction-set.md#sw-store-word)), or write access is granted (i.e. with [`CALL`](./instruction-set.md#call-call-contract)), ownership must be checked.

If the context is external, the owned memory range is:

1. `[$ssp, $sp)`: the writable stack area.
1. `[$hp, VM_MAX_RAM)`: the heap area allocated by this script or predicate.

If the context is internal, the owned memory range for a call frame is:

1. `[$ssp, $sp)`: the writable stack area of the call frame.
1. `[$hp, $fp->$hp)`: the heap area allocated by this call frame.

### Executability

Memory is only executable in range `[$is, $ssp)`. Attempting to execute instructions outside these boundaries will cause a panic. This area never overlaps with writable memory, essentially providing [W^X](https://en.wikipedia.org/wiki/W%5EX) protection.


---

### File: docs/nightly/fuel-specs/src/fuel-vm/instruction-set.md

# FuelVM Instruction Set

- [Reading Guide](#reading-guide)
- [Arithmetic/Logic (ALU) Instructions](#arithmeticlogic-alu-instructions)
  - [`ADD`: Add](#add-add)
  - [`ADDI`: Add immediate](#addi-add-immediate)
  - [`AND`: AND](#and-and)
  - [`ANDI`: AND immediate](#andi-and-immediate)
  - [`DIV`: Divide](#div-divide)
  - [`DIVI`: Divide immediate](#divi-divide-immediate)
  - [`EQ`: Equals](#eq-equals)
  - [`EXP`: Exponentiate](#exp-exponentiate)
  - [`EXPI`: Exponentiate immediate](#expi-exponentiate-immediate)
  - [`GT`: Greater than](#gt-greater-than)
  - [`LT`: Less than](#lt-less-than)
  - [`MLOG`: Math logarithm](#mlog-math-logarithm)
  - [`MOD`: Modulus](#mod-modulus)
  - [`MODI`: Modulus immediate](#modi-modulus-immediate)
  - [`MOVE`: Move](#move-move)
  - [`MOVI`: Move immediate](#movi-move-immediate)
  - [`MROO`: Math root](#mroo-math-root)
  - [`MUL`: Multiply](#mul-multiply)
  - [`MULI`: Multiply immediate](#muli-multiply-immediate)
  - [`MLDV`: Fused multiply-divide](#mldv-fused-multiply-divide)
  - [`NIOP`: Narrow integer operation](#niop-narrow-integer-operation)
  - [`NOOP`: No operation](#noop-no-operation)
  - [`NOT`: Invert](#not-invert)
  - [`OR`: OR](#or-or)
  - [`ORI`: OR immediate](#ori-or-immediate)
  - [`SLL`: Shift left logical](#sll-shift-left-logical)
  - [`SLLI`: Shift left logical immediate](#slli-shift-left-logical-immediate)
  - [`SRL`: Shift right logical](#srl-shift-right-logical)
  - [`SRLI`: Shift right logical immediate](#srli-shift-right-logical-immediate)
  - [`SUB`: Subtract](#sub-subtract)
  - [`SUBI`: Subtract immediate](#subi-subtract-immediate)
  - [`WDCM`: 128-bit integer comparison](#wdcm-128-bit-integer-comparison)
  - [`WQCM`: 256-bit integer comparison](#wqcm-256-bit-integer-comparison)
  - [`WDOP`: Misc 128-bit integer operations](#wdop-misc-128-bit-integer-operations)
  - [`WQOP`: Misc 256-bit integer operations](#wqop-misc-256-bit-integer-operations)
  - [`WDML`: Multiply 128-bit integers](#wdml-multiply-128-bit-integers)
  - [`WQML`: Multiply 256-bit integers](#wqml-multiply-256-bit-integers)
  - [`WDDV`: 128-bit integer division](#wddv-128-bit-integer-division)
  - [`WQDV`: 256-bit integer division](#wqdv-256-bit-integer-division)
  - [`WDMD`: 128-bit integer fused multiply-divide](#wdmd-128-bit-integer-fused-multiply-divide)
  - [`WQMD`: 256-bit integer fused multiply-divide](#wqmd-256-bit-integer-fused-multiply-divide)
  - [`WDAM`: Modular 128-bit integer addition](#wdam-modular-128-bit-integer-addition)
  - [`WQAM`: Modular 256-bit integer addition](#wqam-modular-256-bit-integer-addition)
  - [`WDMM`: Modular 128-bit integer multiplication](#wdmm-modular-128-bit-integer-multiplication)
  - [`WQMM`: Modular 256-bit integer multiplication](#wqmm-modular-256-bit-integer-multiplication)
  - [`XOR`: XOR](#xor-xor)
  - [`XORI`: XOR immediate](#xori-xor-immediate)
- [Control Flow Instructions](#control-flow-instructions)
  - [`JMP`: Jump](#jmp-jump)
  - [`JI`: Jump immediate](#ji-jump-immediate)
  - [`JNE`: Jump if not equal](#jne-jump-if-not-equal)
  - [`JNEI`: Jump if not equal immediate](#jnei-jump-if-not-equal-immediate)
  - [`JNZI`: Jump if not zero immediate](#jnzi-jump-if-not-zero-immediate)
  - [`JMPB`: Jump relative backwards](#jmpb-jump-relative-backwards)
  - [`JMPF`: Jump relative forwards](#jmpf-jump-relative-forwards)
  - [`JNZB`: Jump if not zero relative backwards](#jnzb-jump-if-not-zero-relative-backwards)
  - [`JNZF`: Jump if not zero relative forwards](#jnzf-jump-if-not-zero-relative-forwards)
  - [`JNEB`: Jump if not equal relative backwards](#jneb-jump-if-not-equal-relative-backwards)
  - [`JNEF`: Jump if not equal relative forwards](#jnef-jump-if-not-equal-relative-forwards)
  - [`JAL`: Jump and link](#jal-jump-and-link)
  - [`RET`: Return from context](#ret-return-from-context)
- [Memory Instructions](#memory-instructions)
  - [`ALOC`: Allocate memory](#aloc-allocate-memory)
  - [`CFE`: Extend call frame](#cfe-extend-call-frame)
  - [`CFEI`: Extend call frame immediate](#cfei-extend-call-frame-immediate)
  - [`CFS`: Shrink call frame](#cfs-shrink-call-frame)
  - [`CFSI`: Shrink call frame immediate](#cfsi-shrink-call-frame-immediate)
  - [`LB`: Load byte](#lb-load-byte)
  - [`LQW`: Load quarter word](#lqw-load-quarter-word)
  - [`LHW`: Load half word](#lhw-load-half-word)
  - [`LW`: Load word](#lw-load-word)
  - [`MCL`: Memory clear](#mcl-memory-clear)
  - [`MCLI`: Memory clear immediate](#mcli-memory-clear-immediate)
  - [`MCP`: Memory copy](#mcp-memory-copy)
  - [`MCPI`: Memory copy immediate](#mcpi-memory-copy-immediate)
  - [`MEQ`: Memory equality](#meq-memory-equality)
  - [`POPH`: Pop a set of high registers from stack](#poph-pop-a-set-of-high-registers-from-stack)
  - [`POPL`: Pop a set of low registers from stack](#popl-pop-a-set-of-low-registers-from-stack)
  - [`PSHH`: Push a set of high registers to stack](#pshh-push-a-set-of-high-registers-to-stack)
  - [`PSHL`: Push a set of low registers to stack](#pshl-push-a-set-of-low-registers-to-stack)
  - [`SB`: Store byte](#sb-store-byte)
  - [`SQW`: Store quarter word](#sqw-store-quarter-word)
  - [`SHW`: Store half word](#shw-store-half-word)
  - [`SW`: Store word](#sw-store-word)
- [Contract Instructions](#contract-instructions)
  - [`BAL`: Balance of contract ID](#bal-balance-of-contract-id)
  - [`BHEI`: Block height](#bhei-block-height)
  - [`BHSH`: Block hash](#bhsh-block-hash)
  - [`BURN`: Burn existing coins](#burn-burn-existing-coins)
  - [`CALL`: Call contract](#call-call-contract)
  - [`CB`: Coinbase contract id](#cb-coinbase-contract-id)
  - [`CCP`: Code copy](#ccp-code-copy)
  - [`CROO`: Code Merkle root](#croo-code-merkle-root)
  - [`CSIZ`: Code size](#csiz-code-size)
  - [`LDC`: Load code from an external contract, blob or memory](#ldc-load-code-from-an-external-contract-blob-or-memory)
  - [`LOG`: Log event](#log-log-event)
  - [`LOGD`: Log data event](#logd-log-data-event)
  - [`MINT`: Mint new coins](#mint-mint-new-coins)
  - [`RETD`: Return from context with data](#retd-return-from-context-with-data)
  - [`RVRT`: Revert](#rvrt-revert)
  - [`SMO`: Send message to output](#smo-send-message-out)
  - [`SCWQ`: State clear sequential 32 byte slots](#scwq-state-clear-sequential-32-byte-slots)
  - [`SRW`: State read word](#srw-state-read-word)
  - [`SRWQ`: State read sequential 32 byte slots](#srwq-state-read-sequential-32-byte-slots)
  - [`SWW`: State write word](#sww-state-write-word)
  - [`SWWQ`: State write sequential 32 byte slots](#swwq-state-write-sequential-32-byte-slots)
  - [`TIME`: Timestamp at height](#time-timestamp-at-height)
  - [`TR`: Transfer coins to contract](#tr-transfer-coins-to-contract)
  - [`TRO`: Transfer coins to output](#tro-transfer-coins-to-output)
- [Blob Instructions](#blob-instructions)
  - [`BSIZ`: Blob size](#bsiz-blob-size)
  - [`BLDD`: Load data from a blob](#bldd-load-data-from-a-blob)
- [Cryptographic Instructions](#cryptographic-instructions)
  - [`ECK1`: Secp251k1 signature recovery](#eck1-secp256k1-signature-recovery)
  - [`ECR1`: Secp256r1 signature recovery](#ecr1-secp256r1-signature-recovery)
  - [`ED19`: EdDSA curve25519 verification](#ed19-eddsa-curve25519-verification)
  - [`K256`: keccak-256](#k256-keccak-256)
  - [`S256`: SHA-2-256](#s256-sha-2-256)
  - [`ECOP`: Elliptic curve operation](#ecop-elliptic-curve-point-operation)
  - [`EPAR`: Elliptic curve point pairing check](#epar-elliptic-curve-point-pairing-check)
- [Other Instructions](#other-instructions)
  - [`ECAL`: Call external function](#ecal-call-external-function)
  - [`FLAG`: Set flags](#flag-set-flags)
  - [`GM`: Get metadata](#gm-get-metadata)
  - [`GTF`: Get transaction fields](#gtf-get-transaction-fields)

## Reading Guide

This page provides a description of all instructions for the FuelVM. Encoding is read as a sequence of one 8-bit value (the opcode identifier) followed by four 6-bit values (the register identifiers or immediate value). A single `i` indicates a 6-bit immediate value, `i i` indicates a 12-bit immediate value, `i i i` indicates an 18-bit immediate value, and `i i i i` indicates a 24-bit immediate value. All immediate values are interpreted as big-endian unsigned integers. If the instruction would be shorter than the full 32 bits, the remaining part is reserved and must be zero.

- The syntax `MEM[x, y]` used in this page means the memory range starting at byte `x`, of length `y` bytes.
- The syntax `STATE[x, y]` used in this page means the sequence of storage slots starting at key `x` and spanning `y` bytes.

### Panics

Some instructions may _panic_, i.e. enter an unrecoverable state. Additionally, attempting to execute an instruction not in this list causes a panic and consumes no gas. Instructions with reserved part having a non-zero value will likewise panic.  How a panic is handled depends on [context](./index.md#contexts):

- In a predicate context, cease VM execution and return `false`.
- In other contexts, revert (described below).

On a non-predicate panic, append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Panic`                                                       |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

then append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `1`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

### Receipts

The number of receipts is limited to 2<sup>16</sup>, with the last two reserved to panic and script result receipts. Trying to add any other receipts after 2<sup>16</sup>-2 will panic.

### Effects

A few instructions are annotated with the _effects_ they produce, the table below explains each effect:

| effect name        | description                                        |
|--------------------|----------------------------------------------------|
| Storage read       | Instruction reads from storage slots               |
| Storage write      | Instruction writes to storage slots                |
| External call      | External contract call instruction                 |
| Balance tree read  | Instruction reads from the balance tree            |
| Balance tree write | Instruction writes to the balance tree             |
| Output message     | Instruction sends a message to a recipient address |

If an instruction is not annotated with an effect, it means it does not produce any of the aforementioned affects.

## Arithmetic/Logic (ALU) Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

Normally, if the result of an ALU operation is mathematically undefined (e.g. dividing by zero),
the VM panics. However, if the [`F_UNSAFEMATH`](./index.md#flags) flag is set, `$err` is set to `true`
and execution continues.

If an operation would overflow, so that the result doesn't fit into the target field, the VM will panic.
Results below zero are also considered overflows. If the [`F_WRAPPING`](./index.md#flags) flag is set,
instead `$of` is set to `true` or the overflowing part of the result, depending on the operation.

### `ADD`: Add

|             |                        |
|-------------|------------------------|
| Description | Adds two registers.    |
| Operation   | ```$rA = $rB + $rC;``` |
| Syntax      | `add $rA, $rB, $rC`    |
| Encoding    | `0x00 rA rB rC -`      |
| Notes       |                        |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `ADDI`: Add immediate

|             |                                         |
|-------------|-----------------------------------------|
| Description | Adds a register and an immediate value. |
| Operation   | ```$rA = $rB + imm;```                  |
| Syntax      | `addi $rA, $rB, immediate`              |
| Encoding    | `0x00 rA rB i i`                        |
| Notes       |                                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `AND`: AND

|             |                             |
|-------------|-----------------------------|
| Description | Bitwise ANDs two registers. |
| Operation   | ```$rA = $rB & $rC;```      |
| Syntax      | `and $rA, $rB, $rC`         |
| Encoding    | `0x00 rA rB rC -`           |
| Notes       |                             |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `ANDI`: AND immediate

|             |                                                 |
|-------------|-------------------------------------------------|
| Description | Bitwise ANDs a register and an immediate value. |
| Operation   | ```$rA = $rB & imm;```                          |
| Syntax      | `andi $rA, $rB, imm`                            |
| Encoding    | `0x00 rA rB i i`                                |
| Notes       |                                                 |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`imm` is extended to 64 bits, with the high 52 bits set to `0`.

`$of` and `$err` are cleared.

### `DIV`: Divide

|             |                         |
|-------------|-------------------------|
| Description | Divides two registers.  |
| Operation   | ```$rA = $rB // $rC;``` |
| Syntax      | `div $rA, $rB, $rC`     |
| Encoding    | `0x00 rA rB rC -`       |
| Notes       |                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rC == 0`, `$rA` is cleared and `$err` is set to `true`.

Otherwise, `$err` is cleared.

`$of` is cleared.

### `DIVI`: Divide immediate

|             |                                            |
|-------------|--------------------------------------------|
| Description | Divides a register and an immediate value. |
| Operation   | ```$rA = $rB // imm;```                    |
| Syntax      | `divi $rA, $rB, imm`                       |
| Encoding    | `0x00 rA rB i i`                           |
| Notes       |                                            |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `imm == 0`, `$rA` is cleared and `$err` is set to `true`.

Otherwise, `$err` is cleared.

`$of` is cleared.

### `EQ`: Equals

|             |                                      |
|-------------|--------------------------------------|
| Description | Compares two registers for equality. |
| Operation   | ```$rA = $rB == $rC;```              |
| Syntax      | `eq $rA, $rB, $rC`                   |
| Encoding    | `0x00 rA rB rC -`                    |
| Notes       |                                      |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `EXP`: Exponentiate

|             |                                              |
|-------------|----------------------------------------------|
| Description | Raises one register to the power of another. |
| Operation   | ```$rA = $rB ** $rC;```                      |
| Syntax      | `exp $rA, $rB, $rC`                          |
| Encoding    | `0x00 rA rB rC -`                            |
| Notes       |                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If the result cannot fit in 8 bytes, `$of` is set to `1` and `$rA` is instead set to `0`, otherwise `$of` is cleared.

`$err` is cleared.

### `EXPI`: Exponentiate immediate

|             |                                                         |
|-------------|---------------------------------------------------------|
| Description | Raises one register to the power of an immediate value. |
| Operation   | ```$rA = $rB ** imm;```                                 |
| Syntax      | `expi $rA, $rB, imm`                                    |
| Encoding    | `0x00 rA rB i i`                                        |
| Notes       |                                                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If the result cannot fit in 8 bytes, `$of` is set to `1` and `$rA` is instead set to `0`, otherwise `$of` is cleared.

`$err` is cleared.

### `GT`: Greater than

|             |                                          |
|-------------|------------------------------------------|
| Description | Compares two registers for greater-than. |
| Operation   | ```$rA = $rB > $rC;```                   |
| Syntax      | `gt $rA, $rB, $rC`                       |
| Encoding    | `0x00 rA rB rC -`                        |
| Notes       |                                          |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `LT`: Less than

|             |                                       |
|-------------|---------------------------------------|
| Description | Compares two registers for less-than. |
| Operation   | ```$rA = $rB < $rC;```                |
| Syntax      | `lt $rA, $rB, $rC`                    |
| Encoding    | `0x00 rA rB rC -`                     |
| Notes       |                                       |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `MLOG`: Math logarithm

|             |                                              |
|-------------|----------------------------------------------|
| Description | The (integer) logarithm base `$rC` of `$rB`. |
| Operation   | ```$rA = math.floor(math.log($rB, $rC));```  |
| Syntax      | `mlog $rA, $rB, $rC`                         |
| Encoding    | `0x00 rA rB rC -`                            |
| Notes       |                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rB == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

If `$rC <= 1`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MOD`: Modulus

|             |                                    |
|-------------|------------------------------------|
| Description | Modulo remainder of two registers. |
| Operation   | ```$rA = $rB % $rC;```             |
| Syntax      | `mod $rA, $rB, $rC`                |
| Encoding    | `0x00 rA rB rC -`                  |
| Notes       |                                    |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rC == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MODI`: Modulus immediate

|             |                                                        |
|-------------|--------------------------------------------------------|
| Description | Modulo remainder of a register and an immediate value. |
| Operation   | ```$rA = $rB % imm;```                                 |
| Syntax      | `modi $rA, $rB, imm`                                   |
| Encoding    | `0x00 rA rB i i`                                       |
| Notes       |                                                        |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `imm == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MOVE`: Move

|             |                                    |
|-------------|------------------------------------|
| Description | Copy from one register to another. |
| Operation   | ```$rA = $rB;```                   |
| Syntax      | `move $rA, $rB`                    |
| Encoding    | `0x00 rA rB - -`                   |
| Notes       |                                    |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `MOVI`: Move immediate

|             |                                          |
|-------------|------------------------------------------|
| Description | Copy an immediate value into a register. |
| Operation   | ```$rA = imm;```                         |
| Syntax      | `movi $rA, imm`                          |
| Encoding    | `0x00 rA i i i`                          |
| Notes       |                                          |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `MROO`: Math root

|             |                                              |
|-------------|----------------------------------------------|
| Description | The (integer) `$rCth` root of `$rB`.         |
| Operation   | ```$rA = math.floor(math.root($rB, $rC));``` |
| Syntax      | `mroo $rA, $rB, $rC`                         |
| Encoding    | `0x00 rA rB rC -`                            |
| Notes       |                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

If `$rC == 0`, both `$rA` and `$of` are cleared and `$err` is set to `true`.

Otherwise, `$of` and `$err` are cleared.

### `MUL`: Multiply

|             |                           |
|-------------|---------------------------|
| Description | Multiplies two registers. |
| Operation   | ```$rA = $rB * $rC;```    |
| Syntax      | `mul $rA, $rB, $rC`       |
| Encoding    | `0x00 rA rB rC -`         |
| Notes       |                           |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `MULI`: Multiply immediate

|             |                                               |
|-------------|-----------------------------------------------|
| Description | Multiplies a register and an immediate value. |
| Operation   | ```$rA = $rB * imm;```                        |
| Syntax      | `mul $rA, $rB, imm`                           |
| Encoding    | `0x00 rA rB i i`                              |
| Notes       |                                               |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the overflow of the operation.

`$err` is cleared.

### `MLDV`: Fused multiply-divide

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Multiplies two registers with arbitrary precision, then divides by a third register. |
| Operation   | `a = (b * c) / d;`                                                                   |
| Syntax      | `mldv $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       | Division by zero is treated as division by `1 << 64` instead.                        |

If the divisor (`$rD`) is zero, then instead the value is divided by `1 << 64`. This returns the higher half of the 128-bit multiplication result. This operation never overflows.

If the result of after the division doesn't fit into a register, `$of` is assigned the overflow of the operation. Otherwise, `$of` is cleared.

`$err` is cleared.

### `NIOP`: Narrow integer operation

|             |                                                                                     |
|-------------|-------------------------------------------------------------------------------------|
| Description | Perform an ALU operation with overflow handing for 8, 16 or 32 bit integers         |
| Operation   | `$rA = op($rB,$rC);`                                                                |
| Syntax      | `niop $rA, $rB, $rC, imm`                                                           |
| Encoding    | `0x00 rA rB rC i`                                                                   |
| Notes       | Operations that would be identical with their 64-bit counterparts are not available |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`..XXXX` | `op`       | Operation selection, see below
`XX....` | `width`    | Operation width, see below

Then the actual operation that's performed:

`op` | Name | Description
-----|-------|---------------------------
0    | `add` | Add (`a = b + c`)
1    | `sub` | Subtract (`a = b - c`)
2    | `mul` | Multiply (`a = b * c`)
3    | `exp` | Exponentiate (`a = b ** c`)
4    | `sll` | Bit shift left (logical) (`a = b << c`)
5    | `xnor`| Bitwise xnor (`a = b ^ (!c)`).
other| -     | Reserved and must not be used

And operation width:

`width`| Bits
-------|------
0      | 8
1      | 16
2      | 32
3      | Reserved and must not be used

All operations first truncate their operands to the given bit width,
then perform the operation with overflow checking on that size. The
result always fits within the bit width of the operation.

Operations set `$of` and `$err` similarly to their 64-bit counterparts.
For subtraction specifically, this means that an overflowing operation sets `$of` to all ones (`2**64-1`).
`XNOR` has no counterpart, and it always clears both `$of` and `$err`.

Panic if:

- Reserved bits of the immediate are set
- `$rA` is a [reserved register](./index.md#semantics)

### `NOOP`: No operation

|             |                        |
|-------------|------------------------|
| Description | Performs no operation. |
| Operation   |                        |
| Syntax      | `noop`                 |
| Encoding    | `0x00 - - - -`         |
| Notes       |                        |

`$of` and `$err` are cleared.

### `NOT`: Invert

|             |                         |
|-------------|-------------------------|
| Description | Bitwise NOT a register. |
| Operation   | ```$rA = ~$rB;```       |
| Syntax      | `not $rA, $rB`          |
| Encoding    | `0x00 rA rB - -`        |
| Notes       |                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `OR`: OR

|             |                            |
|-------------|----------------------------|
| Description | Bitwise ORs two registers. |
| Operation   | ```$rA = $rB \| $rC;```    |
| Syntax      | `or $rA, $rB, $rC`         |
| Encoding    | `0x00 rA rB rC -`          |
| Notes       |                            |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `ORI`: OR immediate

|             |                                                |
|-------------|------------------------------------------------|
| Description | Bitwise ORs a register and an immediate value. |
| Operation   | ```$rA = $rB \| imm;```                        |
| Syntax      | `ori $rA, $rB, imm`                            |
| Encoding    | `0x00 rA rB i i`                               |
| Notes       |                                                |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`imm` is extended to 64 bits, with the high 52 bits set to `0`.

`$of` and `$err` are cleared.

### `SLL`: Shift left logical

|             |                                       |
|-------------|---------------------------------------|
| Description | Left shifts a register by a register. |
| Operation   | ```$rA = $rB << $rC;```               |
| Syntax      | `sll $rA, $rB, $rC`                   |
| Encoding    | `0x00 rA rB rC -`                     |
| Notes       | Zeroes are shifted in.                |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SLLI`: Shift left logical immediate

|             |                                               |
|-------------|-----------------------------------------------|
| Description | Left shifts a register by an immediate value. |
| Operation   | ```$rA = $rB << imm;```                       |
| Syntax      | `slli $rA, $rB, imm`                          |
| Encoding    | `0x00 rA rB i i`                              |
| Notes       | Zeroes are shifted in.                        |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SRL`: Shift right logical

|             |                                        |
|-------------|----------------------------------------|
| Description | Right shifts a register by a register. |
| Operation   | ```$rA = $rB >> $rC;```                |
| Syntax      | `srl $rA, $rB, $rC`                    |
| Encoding    | `0x00 rA rB rC -`                      |
| Notes       | Zeroes are shifted in.                 |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SRLI`: Shift right logical immediate

|             |                                                |
|-------------|------------------------------------------------|
| Description | Right shifts a register by an immediate value. |
| Operation   | ```$rA = $rB >> imm;```                        |
| Syntax      | `srli $rA, $rB, imm`                           |
| Encoding    | `0x00 rA rB i i`                               |
| Notes       | Zeroes are shifted in.                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `SUB`: Subtract

|             |                                                  |
|-------------|--------------------------------------------------|
| Description | Subtracts two registers.                         |
| Operation   | ```$rA = $rB - $rC;```                           |
| Syntax      | `sub $rA, $rB, $rC`                              |
| Encoding    | `0x00 rA rB rC -`                                |
| Notes       |                                                  |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the underflow of the operation, as though `$of` is the high byte of a 128-bit register.

`$err` is cleared.

### `SUBI`: Subtract immediate

|             |                                                  |
|-------------|--------------------------------------------------|
| Description | Subtracts a register and an immediate value.     |
| Operation   | ```$rA = $rB - imm;```                           |
| Syntax      | `subi $rA, $rB, imm`                             |
| Encoding    | `0x00 rA rB i i`                                 |
| Notes       |                                                  |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` is assigned the underflow of the operation, as though `$of` is the high byte of a 128-bit register.

`$err` is cleared.

### `WDCM`: 128-bit integer comparison

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Compare or examine two 128-bit integers using selected mode                   |
| Operation   | `b = mem[$rB,16];`<br>`c = indirect?mem[$rC,16]:$rC;`<br>`$rA = cmp_op(b,c);` |
| Syntax      | `wdcm $rA, $rB, $rC, imm`                                                     |
| Encoding    | `0x00 rA rB rC i`                                                             |
| Notes       |                                                                               |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`...XXX` | `mode`     | Compare mode selection
`.XX...` | `reserved` | Reserved and must be zero
`X.....` | `indirect` | Is rhs operand (`$rC`) indirect or not

Then the actual operation that's performed:

`mode` | Name | Description
-------|------|-------------------------------------------------------------
0      | `eq`   | Equality (`==`)
1      | `ne`   | Inequality (`!=`)
2      | `lt`   | Less than (`<`)
3      | `gt`   | Greater than (`>`)
4      | `lte`  | Less than or equals (`<=`)
5      | `gte`  | Greater than or equals (`>=`)
6      | `lzc`  | Leading zero count the lhs argument (`lzcnt`). Discards rhs.
7      | -    | Reserved and must not be used

The leading zero count can be used to compute rounded-down log2 of a number using the following formula `TOTAL_BITS - 1 - lzc(n)`. Note that `log2(0)` is undefined, and will lead to integer overflow with this method.

Clears `$of` and `$err`.

Panic if:

- A reserved compare mode is given
- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQCM`: 256-bit integer comparison

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Compare or examine two 256-bit integers using selected mode                   |
| Operation   | `b = mem[$rB,32];`<br>`c = indirect?mem[$rC,32]:$rC;`<br>`$rA = cmp_op(b,c);` |
| Syntax      | `wqcm $rA, $rB, $rC, imm`                                                     |
| Encoding    | `0x00 rA rB rC i`                                                             |
| Notes       |                                                                               |

The immediate value is interpreted identically to `WDCM`.

Clears `$of` and `$err`.

Panic if:

- A reserved compare mode is given
- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDOP`: Misc 128-bit integer operations

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Perform an ALU operation on two 128-bit integers                                  |
| Operation   | `b = mem[$rB,16];`<br>`c = indirect?mem[$rC,16]:$rC;`<br>`mem[$rA,16] = op(b,c);` |
| Syntax      | `wdop $rA, $rB, $rC, imm`                                                         |
| Encoding    | `0x00 rA rB rC i`                                                                 |
| Notes       |                                                                                   |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`...XXX` | `op`       | Operation selection, see below
`.XX...` | `reserved` | Reserved and must be zero
`X.....` | `indirect` | Is rhs operand (`$rC`) indirect or not

Then the actual operation that's performed:

`op` | Name | Description
-----|------|---------------------------
0    | `add`  | Add
1    | `sub`  | Subtract
2    | `not`  | Invert bits (discards rhs)
3    | `or`   | Bitwise or
4    | `xor`  | Bitwise exclusive or
5    | `and`  | Bitwise and
6    | `shl`  | Shift left (logical)
7    | `shr`  | Shift right (logical)

Operations behave `$of` and `$err` similarly to their 64-bit counterparts, except that `$of` is set to `1` instead of the overflowing part.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQOP`: Misc 256-bit integer operations

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Perform an ALU operation on two 256-bit integers                                  |
| Operation   | `b = mem[$rB,32];`<br>`c = indirect?mem[$rC,32]:$rC;`<br>`mem[$rA,32] = op(b,c);` |
| Syntax      | `wqop $rA, $rB, $rC, imm`                                                         |
| Encoding    | `0x00 rA rB rC i`                                                                 |
| Notes       |                                                                                   |

The immediate value is interpreted identically to `WDOP`.

Operations behave `$of` and `$err` similarly to their 64-bit counterparts.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDML`: Multiply 128-bit integers

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Perform integer multiplication operation on two 128-bit integers.                      |
| Operation   | `b=indirect0?mem[$rB,16]:$rB;`<br>`c=indirect1?mem[$rC,16]:$rC;`<br>`mem[$rA,16]=b*c;` |
| Syntax      | `wdml $rA, $rB, $rC, imm`                                                              |
| Encoding    | `0x00 rA rB rC i`                                                                      |
| Notes       |                                                                                        |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name  | Description
---------|-------------|-------------------------------------
`..XXXX` | `reserved`  | Reserved and must be zero
`.X....` | `indirect0` | Is lhs operand (`$rB`) indirect or not
`X.....` | `indirect1` | Is rhs operand (`$rC`) indirect or not

`$of` is set to `1` in case of overflow, and cleared otherwise.

`$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `indirect0 == 1` and `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect1 == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQML`: Multiply 256-bit integers

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Perform integer multiplication operation on two 256-bit integers.                      |
| Operation   | `b=indirect0?mem[$rB,32]:$rB;`<br>`c=indirect1?mem[$rC,32]:$rC;`<br>`mem[$rA,32]=b*c;` |
| Syntax      | `wqml $rA, $rB, $rC, imm`                                                              |
| Encoding    | `0x00 rA rB rC i`                                                                      |
| Notes       |                                                                                        |

The immediate value is interpreted identically to `WDML`.

`$of` is set to `1` in case of overflow, and cleared otherwise.

`$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `indirect0 == 1` and `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect1 == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDDV`: 128-bit integer division

|             |                                                                                 |
|-------------|---------------------------------------------------------------------------------|
| Description | Divide a 128-bit integer by another.                                            |
| Operation   | `b = mem[$rB,16];`<br>`c = indirect?mem[$rC,16]:$rC;`<br>`mem[$rA,16] = b / c;` |
| Syntax      | `wddv $rA, $rB, $rC, imm`                                                       |
| Encoding    | `0x00 rA rB rC i`                                                               |
| Notes       |                                                                                 |

The six-bit immediate value is used to select operating mode, as follows:

Bits     | Short name | Description
---------|------------|-------------------------------------
`.XXXXX` | `reserved` | Reserved and must be zero
`X.....` | `indirect` | Is rhs operand (`$rC`) indirect or not

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 16]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 16` overflows or `> VM_MAX_RAM`

### `WQDV`: 256-bit integer division

|             |                                                                                 |
|-------------|---------------------------------------------------------------------------------|
| Description | Divide a 256-bit integer by another.                                            |
| Operation   | `b = mem[$rB,32];`<br>`c = indirect?mem[$rC,32]:$rC;`<br>`mem[$rA,32] = b / c;` |
| Syntax      | `wqdv $rA, $rB, $rC, imm`                                                       |
| Encoding    | `0x00 rA rB rC i`                                                               |
| Notes       |                                                                                 |

The immediate value is interpreted identically to `WDDV`.

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 32]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- Reserved bits of the immediate are set
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `indirect == 1` and `$rC + 32` overflows or `> VM_MAX_RAM`

### `WDMD`: 128-bit integer fused multiply-divide

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Combined multiply-divide of 128-bit integers with arbitrary precision.                 |
| Operation   | `b=mem[$rB,16];`<br>`c=mem[$rC,16];`<br>`d=mem[$rD,16];`<br>`mem[$rA,16]=(b * c) / d;` |
| Syntax      | `wdmd $rA, $rB, $rC, $rD`                                                              |
| Encoding    | `0x00 rA rB rC rD`                                                                     |
| Notes       | Division by zero is treated as division by `1 << 128` instead.                         |

If the divisor `MEM[$rA, 16]` is zero, then instead the value is divided by `1 << 128`. This returns the higher half of the 256-bit multiplication result.

If the result of after the division is larger than operand size, `$of` is set to one. Otherwise, `$of` is cleared.

`$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `$rC + 16` overflows or `> VM_MAX_RAM`
- `$rD + 16` overflows or `> VM_MAX_RAM`

### `WQMD`: 256-bit integer fused multiply-divide

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Combined multiply-divide of 256-bit integers with arbitrary precision.                 |
| Operation   | `b=mem[$rB,32];`<br>`c=mem[$rC,32];`<br>`d=mem[$rD,32];`<br>`mem[$rA,32]=(b * c) / d;` |
| Syntax      | `wqmd $rA, $rB, $rC, $rD`                                                              |
| Encoding    | `0x00 rA rB rC rD`                                                                     |
| Notes       | Division by zero is treated as division by `1 << 256` instead.                         |

If the divisor `MEM[$rA, 32]` is zero, then instead the value is divided by `1 << 256`. This returns the higher half of the 512-bit multiplication result.

If the result of after the division is larger than operand size, `$of` is set to one. Otherwise, `$of` is cleared.

`$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`

### `WDAM`: Modular 128-bit integer addition

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Add two 128-bit integers and compute modulo remainder with arbitrary precision.      |
| Operation   | `b=mem[$rB,16];`<br>`c=mem[$rC,16];`<br>`d=mem[$rD,16];`<br>`mem[$rA,16] = (b+c)%d;` |
| Syntax      | `wdam $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 16]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `$rC + 16` overflows or `> VM_MAX_RAM`
- `$rD + 16` overflows or `> VM_MAX_RAM`

### `WQAM`: Modular 256-bit integer addition

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Add two 256-bit integers and compute modulo remainder with arbitrary precision.      |
| Operation   | `b=mem[$rB,32];`<br>`c=mem[$rC,32];`<br>`d=mem[$rD,32];`<br>`mem[$rA,32] = (b+c)%d;` |
| Syntax      | `wqam $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 32]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`

### `WDMM`: Modular 128-bit integer multiplication

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Multiply two 128-bit integers and compute modulo remainder with arbitrary precision. |
| Operation   | `b=mem[$rB,16];`<br>`c=mem[$rC,16];`<br>`d=mem[$rD,16];`<br>`mem[$rA,16] = (b*c)%d;` |
| Syntax      | `wdmm $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 16]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 16]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 16` overflows or `> VM_MAX_RAM`
- `$rC + 16` overflows or `> VM_MAX_RAM`
- `$rD + 16` overflows or `> VM_MAX_RAM`

### `WQMM`: Modular 256-bit integer multiplication

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Multiply two 256-bit integers and compute modulo remainder with arbitrary precision. |
| Operation   | `b=mem[$rB,32];`<br>`c=mem[$rC,32];`<br>`d=mem[$rD,32];`<br>`mem[$rA,32] = (b*c)%d;` |
| Syntax      | `wqmm $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                   |
| Notes       |                                                                                      |

`$of` is cleared.

If the rhs operand is zero, `MEM[$rA, 32]` is cleared and `$err` is set to `true`. Otherwise, `$err` is cleared.

Panic if:

- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`

### `XOR`: XOR

|             |                             |
|-------------|-----------------------------|
| Description | Bitwise XORs two registers. |
| Operation   | ```$rA = $rB ^ $rC;```      |
| Syntax      | `xor $rA, $rB, $rC`         |
| Encoding    | `0x00 rA rB rC -`           |
| Notes       |                             |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

### `XORI`: XOR immediate

|             |                                                 |
|-------------|-------------------------------------------------|
| Description | Bitwise XORs a register and an immediate value. |
| Operation   | ```$rA = $rB ^ imm;```                          |
| Syntax      | `xori $rA, $rB, imm`                            |
| Encoding    | `0x00 rA rB i i`                                |
| Notes       |                                                 |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

`$of` and `$err` are cleared.

## Control Flow Instructions

### `JMP`: Jump

|             |                                                     |
|-------------|-----------------------------------------------------|
| Description | Jumps to the code instruction offset by a register. |
| Operation   | ```$pc = $is + $rA * 4;```                          |
| Syntax      | `jmp $rA`                                           |
| Encoding    | `0x00 rA - - -`                                     |
| Notes       |                                                     |

Panic if:

- `$is + $rA * 4 > VM_MAX_RAM - 1`

### `JI`: Jump immediate

|             |                                                |
|-------------|------------------------------------------------|
| Description | Jumps to the code instruction offset by `imm`. |
| Operation   | ```$pc = $is + imm * 4;```                     |
| Syntax      | `ji imm`                                       |
| Encoding    | `0x00 i i i i`                                 |
| Notes       |                                                |

Panic if:

- `$is + imm * 4 > VM_MAX_RAM - 1`

### `JNE`: Jump if not equal

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Jump to the code instruction offset by a register if `$rA` is not equal to `$rB`.    |
| Operation   | ```if $rA != $rB:```<br>```$pc = $is + $rC * 4;```<br>```else:```<br>```$pc += 4;``` |
| Syntax      | `jne $rA $rB $rC`                                                                    |
| Encoding    | `0x00 rA rB rC -`                                                                    |
| Notes       |                                                                                      |

Panic if:

- `$is + $rC * 4 > VM_MAX_RAM - 1` and the jump would be performed (i.e. `$rA != $rB`)

### `JNEI`: Jump if not equal immediate

|             |                                                                                      |
|-------------|--------------------------------------------------------------------------------------|
| Description | Jump to the code instruction offset by `imm` if `$rA` is not equal to `$rB`.         |
| Operation   | ```if $rA != $rB:```<br>```$pc = $is + imm * 4;```<br>```else:```<br>```$pc += 4;``` |
| Syntax      | `jnei $rA $rB imm`                                                                   |
| Encoding    | `0x00 rA rB i i`                                                                     |
| Notes       |                                                                                      |

Panic if:

- `$is + imm * 4 > VM_MAX_RAM - 1` and the jump would be performed (i.e. `$rA != $rB`)

### `JNZI`: Jump if not zero immediate

|             |                                                                                        |
|-------------|----------------------------------------------------------------------------------------|
| Description | Jump to the code instruction offset by `imm` if `$rA` is not equal to `$zero`.         |
| Operation   | ```if $rA != $zero:```<br>```$pc = $is + imm * 4;```<br>```else:```<br>```$pc += 4;``` |
| Syntax      | `jnzi $rA imm`                                                                         |
| Encoding    | `0x00 rA i i i`                                                                        |
| Notes       |                                                                                        |

Panic if:

- `$is + imm * 4 > VM_MAX_RAM - 1`and the jump would be performed (i.e. `$rA != $zero`)

### `JMPB`: Jump relative backwards

|             |                                          |
|-------------|------------------------------------------|
| Description | Jump `$rA + imm` instructions backwards. |
| Operation   | ```$pc -= ($rA + imm + 1) * 4;```        |
| Syntax      | `jmpb $rA imm`                           |
| Encoding    | `0x00 rA i i i`                          |
| Notes       |                                          |

Panic if:

- `$pc - ($rA + imm + 1) * 4 < 0`

### `JMPF`: Jump relative forwards

|             |                                        |
|-------------|----------------------------------------|
| Description | Jump `$rA + imm` instructions forwards |
| Operation   | ```$pc += ($rA + imm + 1) * 4;```      |
| Syntax      | `jmpf $rA imm`                         |
| Encoding    | `0x00 rA i i i`                        |
| Notes       |                                        |

Panic if:

- `$pc + ($rA + imm + 1) * 4 > VM_MAX_RAM - 1`

### `JNZB`: Jump if not zero relative backwards

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Jump `$rB + imm` instructions backwards if `$rA != $zero`.                    |
| Operation   | `if $rA != $zero:`<br>`$pc -= ($rB + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jnzb $rA $rB imm`                                                            |
| Encoding    | `0x00 rA rB i i`                                                              |
| Notes       |                                                                               |

Panic if:

- `$pc - ($rB + imm + 1) * 4 < 0`

### `JNZF`: Jump if not zero relative forwards

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | Jump `$rB + imm` instructions forwards if `$rA != $zero`.                     |
| Operation   | `if $rA != $zero:`<br>`$pc += ($rB + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jnzf $rA $rB imm`                                                            |
| Encoding    | `0x00 rA rB i i`                                                              |
| Notes       |                                                                               |

Panic if:

- `$pc + ($rB + imm + 1) * 4 > VM_MAX_RAM - 1`

### `JNEB`: Jump if not equal relative backwards

|             |                                                                             |
|-------------|-----------------------------------------------------------------------------|
| Description | Jump `$rC + imm` instructions backwards if `$rA != $rB`.                    |
| Operation   | `if $rA != $rB:`<br>`$pc -= ($rC + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jneb $rA $rB $rC imm`                                                      |
| Encoding    | `0x00 rA rB rC i`                                                           |
| Notes       |                                                                             |

Panic if:

- `$pc - ($rC + imm + 1) * 4 < 0`

### `JNEF`: Jump if not equal relative forwards

|             |                                                                             |
|-------------|-----------------------------------------------------------------------------|
| Description | Jump `$rC + imm` instructions forwards if `$rA != $rB`.                     |
| Operation   | `if $rA != $rB:`<br>`$pc += ($rC + imm + 1) * 4;`<br>`else:`<br>`$pc += 4;` |
| Syntax      | `jnef $rA $rB $rC imm`                                                      |
| Encoding    | `0x00 rA rB rC i`                                                           |
| Notes       |                                                                             |

Panic if:

- `$pc + ($rC + imm + 1) * 4 > VM_MAX_RAM - 1`

### `JAL`: Jump and link

|             |                                                                                               |
|-------------|-----------------------------------------------------------------------------------------------|
| Description | Set `$rA` to address of the next instruction. Jump to instruction at address `$rB + imm * 4`. |
| Operation   | `if $rA is not $zero { $rA = $pc + 4 }` <br> `$pc = $rB + imm * 4`                            |
| Syntax      | `jal $rA $rB imm`                                                                             |
| Encoding    | `0x00 rA rB i i`                                                                              |
| Notes       | If `$rA` is `$zero`, the return address discarded.                                            |

Panic if:

- `$rA` is a reserved register other than `$zero`
- `$rB + imm * 4 >= VM_MAX_RAM`

### `RET`: Return from context

|             |                                                               |
|-------------|---------------------------------------------------------------|
| Description | Returns from [context](./index.md#contexts) with value `$rA`. |
| Operation   | ```return($rA);```                                            |
| Syntax      | `ret $rA`                                                     |
| Encoding    | `0x00 rA - - -`                                               |
| Notes       | `$ret` is set to the return value from `$rA`.                 |

Append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Return`                                                      |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val`  | `uint64`      | Value of register `$rA`.                                                  |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

If current context is external, append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `0`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

If current context is external, cease VM execution and return `$rA`.

Returns from contract call, popping the call frame. Before popping perform the following operations.

Return the unused forwarded gas to the caller:

1. `$cgas = $cgas + $fp->$cgas` (add remaining context gas from previous context to current remaining context gas)

Set the return value:

1. `$ret = $rA`
1. `$retl = 0`

Then pop the call frame and restore all registers _except_ `$ggas`, `$cgas`, `$ret`, `$retl` and `$hp`. Afterwards, set the following registers:

1. `$pc = $pc + 4` (advance program counter from where we called)

## Memory Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `ALOC`: Allocate memory

|             |                                           |
|-------------|-------------------------------------------|
| Description | Allocate a number of bytes from the heap. |
| Operation   | ```$hp = $hp - $rA;```                    |
| Syntax      | `aloc $rA`                                |
| Encoding    | `0x00 rA - - -`                           |
| Notes       | Newly allocated memory is zeroed.         |

Panic if:

- `$hp - $rA` underflows
- `$hp - $rA < $sp`

### `CFE`: Extend call frame

|             |                                        |
|-------------|----------------------------------------|
| Description | Extend the current call frame's stack. |
| Operation   | ```$sp = $sp + $rA```                  |
| Syntax      | `cfe $rA`                             |
| Encoding    | `0x00 rA - - -`                        |
| Notes       | Does not initialize memory.            |

Panic if:

- `$sp + $rA` overflows
- `$sp + $rA > $hp`

### `CFEI`: Extend call frame immediate

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | Extend the current call frame's stack by an immediate value. |
| Operation   | ```$sp = $sp + imm```                                        |
| Syntax      | `cfei imm`                                                   |
| Encoding    | `0x00 i i i i`                                               |
| Notes       | Does not initialize memory.                                  |

Panic if:

- `$sp + imm` overflows
- `$sp + imm > $hp`

### `CFS`: Shrink call frame

|             |                                        |
|-------------|----------------------------------------|
| Description | Shrink the current call frame's stack. |
| Operation   | ```$sp = $sp - $rA```                  |
| Syntax      | `cfs $rA`                              |
| Encoding    | `0x00 $rA - - -`                       |
| Notes       | Does not clear memory.                 |

Panic if:

- `$sp - $rA` underflows
- `$sp - $rA < $ssp`

### `CFSI`: Shrink call frame immediate

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | Shrink the current call frame's stack by an immediate value. |
| Operation   | ```$sp = $sp - imm```                                        |
| Syntax      | `cfsi imm`                                                   |
| Encoding    | `0x00 i i i i`                                               |
| Notes       | Does not clear memory.                                       |

Panic if:

- `$sp - imm` underflows
- `$sp - imm < $ssp`

### `LB`: Load byte

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | A byte is loaded from the specified address offset by `imm`. |
| Operation   | ```$rA = MEM[$rB + imm, 1];```                               |
| Syntax      | `lb $rA, $rB, imm`                                           |
| Encoding    | `0x00 rA rB i i`                                             |
| Notes       |                                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + imm + 1` overflows or `> VM_MAX_RAM`

### `LQW`: Load quarter word

|             |                                                                      |
|-------------|----------------------------------------------------------------------|
| Description | A quarter word is loaded from the specified address offset by `imm`. |
| Operation   | ```$rA = MEM[$rB + (imm * 2), 2];```                                 |
| Syntax      | `lqw $rA, $rB, imm`                                                  |
| Encoding    | `0x00 rA rB i i`                                                     |
| Notes       |                                                                      |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + (imm * 2) + 2` overflows or `> VM_MAX_RAM`

### `LHW`: Load half word

|             |                                                                      |
|-------------|----------------------------------------------------------------------|
| Description | A half word is loaded from the specified address offset by `imm`.    |
| Operation   | ```$rA = MEM[$rB + (imm * 4), 4];```                                 |
| Syntax      | `lhw $rA, $rB, imm`                                                  |
| Encoding    | `0x00 rA rB i i`                                                     |
| Notes       |                                                                      |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + (imm * 4) + 4` overflows or `> VM_MAX_RAM`

### `LW`: Load word

|             |                                                              |
|-------------|--------------------------------------------------------------|
| Description | A word is loaded from the specified address offset by `imm`. |
| Operation   | ```$rA = MEM[$rB + (imm * 8), 8];```                         |
| Syntax      | `lw $rA, $rB, imm`                                           |
| Encoding    | `0x00 rA rB i i`                                             |
| Notes       |                                                              |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + (imm * 8) + 8` overflows or `> VM_MAX_RAM`

### `MCL`: Memory clear

|             |                          |
|-------------|--------------------------|
| Description | Clear bytes in memory.   |
| Operation   | ```MEM[$rA, $rB] = 0;``` |
| Syntax      | `mcl $rA, $rB`           |
| Encoding    | `0x00 rA rB - -`         |
| Notes       |                          |

Panic if:

- `$rA + $rB` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, $rB]`  does not pass [ownership check](./index.md#ownership)

### `MCLI`: Memory clear immediate

|             |                          |
|-------------|--------------------------|
| Description | Clear bytes in memory.   |
| Operation   | ```MEM[$rA, imm] = 0;``` |
| Syntax      | `mcli $rA, imm`          |
| Encoding    | `0x00 rA i i i`          |
| Notes       |                          |

Panic if:

- `$rA + imm` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, imm]`  does not pass [ownership check](./index.md#ownership)

### `MCP`: Memory copy

|             |                                      |
|-------------|--------------------------------------|
| Description | Copy bytes in memory.                |
| Operation   | ```MEM[$rA, $rC] = MEM[$rB, $rC];``` |
| Syntax      | `mcp $rA, $rB, $rC`                  |
| Encoding    | `0x00 rA rB rC -`                    |
| Notes       |                                      |

Panic if:

- `$rA + $rC` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- The memory ranges `MEM[$rA, $rC]` and `MEM[$rB, $rC]` overlap
- The memory range `MEM[$rA, $rC]`  does not pass [ownership check](./index.md#ownership)

### `MCPI`: Memory copy immediate

|             |                                      |
|-------------|--------------------------------------|
| Description | Copy bytes in memory.                |
| Operation   | ```MEM[$rA, imm] = MEM[$rB, imm];``` |
| Syntax      | `mcpi $rA, $rB, imm`                 |
| Encoding    | `0x00 rA rB imm imm`                 |
| Notes       |                                      |

Panic if:

- `$rA + imm` overflows or `> VM_MAX_RAM`
- `$rB + imm` overflows or `> VM_MAX_RAM`
- The memory ranges `MEM[$rA, imm]` and `MEM[$rB, imm]` overlap
- The memory range `MEM[$rA, imm]`  does not pass [ownership check](./index.md#ownership)

### `MEQ`: Memory equality

|             |                                             |
|-------------|---------------------------------------------|
| Description | Compare bytes in memory.                    |
| Operation   | ```$rA = MEM[$rB, $rD] == MEM[$rC, $rD];``` |
| Syntax      | `meq $rA, $rB, $rC, $rD`                    |
| Encoding    | `0x00 rA rB rC rD`                          |
| Notes       |                                             |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + $rD` overflows or `> VM_MAX_RAM`
- `$rC + $rD` overflows or `> VM_MAX_RAM`

### `PSHH`: Push a set of high registers to stack

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Push a set of registers from range 40..64 to the stack in order.                  |
| Operation   | `tmp=$sp;`<br>`$sp+=popcnt(imm)*8;`<br>`MEM[tmp,$sp]=registers[40..64].mask(imm)` |
| Syntax      | `pshh imm`                                                                        |
| Encoding    | `0x00 i i i i`                                                                    |
| Notes       | The immediate value is used as a bitmask for selecting the registers.             |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pushes the register 61 followed by register 62.

Panic if:

- `$sp + popcnt(imm)*8` overflows
- `$sp + popcnt(imm)*8 > $hp`

### `PSHL`: Push a set of low registers to stack

|             |                                                                                   |
|-------------|-----------------------------------------------------------------------------------|
| Description | Push a set of registers from range 16..40 to the stack in order.                  |
| Operation   | `tmp=$sp;`<br>`$sp+=popcnt(imm)*8;`<br>`MEM[tmp,$sp]=registers[16..40].mask(imm)` |
| Syntax      | `pshl imm`                                                                        |
| Encoding    | `0x00 i i i i`                                                                    |
| Notes       | The immediate value is used as a bitmask for selecting the registers.             |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pushes the register 37 followed by register 38.

Panic if:

- `$sp + popcnt(imm)*8` overflows
- `$sp + popcnt(imm)*8 > $hp`

### `POPH`: Pop a set of high registers from stack

|             |                                                                                       |
|-------------|---------------------------------------------------------------------------------------|
| Description | Pop to a set of registers from range 40..64 from the stack.                           |
| Operation   | `tmp=$sp-popcnt(imm)*8;`<br>`registers[40..64].mask(imm)=MEM[tmp,$sp]`<br>`$sp-=tmp;` |
| Syntax      | `poph imm`                                                                            |
| Encoding    | `0x00 i i i i`                                                                        |
| Notes       | The immediate value is used as a bitmask for selecting the registers.                 |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pops the register 62 followed by register 61.

Note that the order is reverse from `PSHH`, so that `PSHH a; POPH a` returns to the original state.

Panic if:

- `$sp - popcnt(imm)*8` overflows
- `$sp - popcnt(imm)*8 < $ssp`

### `POPL`: Pop a set of low registers from stack

|             |                                                                                       |
|-------------|---------------------------------------------------------------------------------------|
| Description | Pop to a set of registers from range 16..40 from the stack.                           |
| Operation   | `tmp=$sp-popcnt(imm)*8;`<br>`registers[16..40].mask(imm)=MEM[tmp,$sp]`<br>`$sp-=tmp;` |
| Syntax      | `poph imm`                                                                            |
| Encoding    | `0x00 i i i i`                                                                        |
| Notes       | The immediate value is used as a bitmask for selecting the registers.                 |

The nth bit of the bitmask corresponds to nth entry of the register range. In other words, the most significant (i.e. leftmost) bit of the bitmask corresponds to the highest register index. So for instance bitmask `011000000000000000000000` pops the register 38 followed by register 37.

Note that the order is reverse from `PSHL`, so that `PSHL a; POPL a` returns to the original state.

Panic if:

- `$sp - popcnt(imm)*8` overflows
- `$sp - popcnt(imm)*8 < $ssp`

### `SB`: Store byte

|             |                                                                                     |
|-------------|-------------------------------------------------------------------------------------|
| Description | The least significant byte of `$rB` is stored at the address `$rA` offset by `imm`. |
| Operation   | ```MEM[$rA + imm, 1] = $rB[7, 1];```                                                |
| Syntax      | `sb $rA, $rB, imm`                                                                  |
| Encoding    | `0x00 rA rB i i`                                                                    |
| Notes       |                                                                                     |

Panic if:

- `$rA + imm + 1` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA + imm, 1]`  does not pass [ownership check](./index.md#ownership)

### `SQW`: Store quarter word

|             |                                                                                               |
|-------------|-----------------------------------------------------------------------------------------------|
| Description | The two least significant bytes of  of `$rB` is stored at the address `$rA` offset by `imm`.  |
| Operation   | ```MEM[$rA + (imm * 2), 2] = $rB;```                                                          |
| Syntax      | `sqw $rA, $rB, imm`                                                                           |
| Encoding    | `0x00 rA rB i i`                                                                              |
| Notes       |                                                                                               |

### `SHW`: Store half word

|             |                                                                                               |
|-------------|-----------------------------------------------------------------------------------------------|
| Description | The four least significant bytes of  of `$rB` is stored at the address `$rA` offset by `imm`. |
| Operation   | ```MEM[$rA + (imm * 4), 4] = $rB;```                                                          |
| Syntax      | `shw $rA, $rB, imm`                                                                           |
| Encoding    | `0x00 rA rB i i`                                                                              |
| Notes       |                                                                                               |

Panic if:

- `$rA + (imm * 4) + 4` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA + (imm * 4), 4]`  does not pass [ownership check](./index.md#ownership)

### `SW`: Store word

|             |                                                                    |
|-------------|--------------------------------------------------------------------|
| Description | The value of `$rB` is stored at the address `$rA` offset by `imm`. |
| Operation   | ```MEM[$rA + (imm * 8), 8] = $rB;```                               |
| Syntax      | `sw $rA, $rB, imm`                                                 |
| Encoding    | `0x00 rA rB i i`                                                   |
| Notes       |                                                                    |

Panic if:

- `$rA + (imm * 8) + 8` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA + (imm * 8), 8]`  does not pass [ownership check](./index.md#ownership)

## Contract Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation, except for [CALL](#call-call-contract), [`RETD`](#retd-return-from-context-with-data) and [`RVRT`](#rvrt-revert).

### `BAL`: Balance of contract ID

|             |                                                                              |
|-------------|------------------------------------------------------------------------------|
| Description | Set `$rA` to the balance of asset ID at `$rB` for contract with ID at `$rC`. |
| Operation   | ```$rA = balance(MEM[$rB, 32], MEM[$rC, 32]);```                             |
| Syntax      | `bal $rA, $rB, $rC`                                                          |
| Encoding    | `0x00 rA rB rC -`                                                            |
| Effects     | Balance tree read                                                            |
| Notes       |                                                                              |

Where helper `balance(asset_id: byte[32], contract_id: byte[32]) -> uint64` returns the current balance of `asset_id` of contract with ID `contract_id`.

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rC, 32]` is not in `tx.inputs`

### `BHEI`: Block height

|             |                            |
|-------------|----------------------------|
| Description | Get Fuel block height.     |
| Operation   | ```$rA = blockheight();``` |
| Syntax      | `bhei $rA`                 |
| Encoding    | `0x00 rA - - -`            |
| Notes       |                            |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)

### `BHSH`: Block hash

|             |                                      |
|-------------|--------------------------------------|
| Description | Get block header hash.               |
| Operation   | ```MEM[$rA, 32] = blockhash($rB);``` |
| Syntax      | `bhsh $rA $rB`                       |
| Encoding    | `0x00 rA rB - -`                     |
| Notes       |                                      |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

Block header hashes for blocks with height greater than or equal to current block height are zero (```0x00**32```).

### `BURN`: Burn existing coins

|             |                                                             |
|-------------|-------------------------------------------------------------|
| Description | Burn `$rA` coins of the `$rB` ID from the current contract. |
| Operation   | ```burn($rA, $rB);```                                       |
| Syntax      | `burn $rA $rB`                                              |
| Encoding    | `0x00 rA rB - -`                                            |
| Notes       | `$rB` is a pointer to a 32 byte ID in memory.               |

The asset ID is constructed using the asset ID construction method.

Panic if:

- `$rB + 32` overflows or `> VM_MAX_RAM`
- Balance of asset ID from `constructAssetID(MEM[$fp, 32], MEM[$rB, 32])` of output with contract ID `MEM[$fp, 32]` minus `$rA` underflows
- `$fp == 0` (in the script context)

For output with contract ID `MEM[$fp, 32]`, decrease balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB, 32])` by `$rA`.

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts:

| name          | type          | description                                |
|---------------|---------------|--------------------------------------------|
| `type`        | `ReceiptType` | `ReceiptType.Burn`                         |
| `sub_id`      | `byte[32]`    | Asset sub identifier `MEM[$rB, $rB + 32]`. |
| `contract_id` | `byte[32]`    | Contract ID of the current context.        |
| `val`         | `uint64`      | Value of register `$rA`.                   |
| `pc`          | `uint64`      | Value of register `$pc`.                   |
| `is`          | `uint64`      | Value of register `$is`.                   |

### `CALL`: Call contract

|             |                        |
|-------------|------------------------|
| Description | Call contract.         |
| Operation   |                        |
| Syntax      | `call $rA $rB $rC $rD` |
| Encoding    | `0x00 rA rB rC rD`     |
| Effects     | External call          |
| Notes       |                        |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- Reading past `MEM[VM_MAX_RAM - 1]`
- In an external context, if `$rB > MEM[balanceOfStart(MEM[$rC, 32]), 8]`
- In an internal context, if `$rB` is greater than the balance of asset ID `MEM[$rC, 32]` of output with contract ID `MEM[$fp, 32]`

Register `$rA` is a memory address from which the following fields are set (word-aligned):

| bytes | type       | value    | description          |
|-------|------------|----------|----------------------|
| 32    | `byte[32]` | `to`     | Contract ID to call. |
| 8     | `byte[8]`  | `param1` | First parameter.     |
| 8     | `byte[8]`  | `param2` | Second parameter.    |

`$rB` is the amount of coins to forward. `$rC` points to the 32-byte asset ID of the coins to forward. `$rD` is the amount of gas to forward. If it is set to an amount greater than the available gas, all available gas is forwarded.

Append a receipt to the list of receipts:

| name       | type          | description                                                               |
|------------|---------------|---------------------------------------------------------------------------|
| `type`     | `ReceiptType` | `ReceiptType.Call`                                                        |
| `from`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `to`       | `byte[32]`    | Contract ID of called contract.                                           |
| `amount`   | `uint64`      | Amount of coins to forward, i.e. `$rB`.                                   |
| `asset_id` | `byte[32]`    | Asset ID of coins to forward, i.e. `MEM[$rC, 32]`.                        |
| `gas`      | `uint64`      | Gas to forward, i.e. `min($rD, $cgas)`.                                   |
| `param1`   | `uint64`      | First parameter.                                                          |
| `param2`   | `uint64`      | Second parameter.                                                         |
| `pc`       | `uint64`      | Value of register `$pc`.                                                  |
| `is`       | `uint64`      | Value of register `$is`.                                                  |

For output with contract ID `MEM[$rA, 32]`, increase balance of asset ID `MEM[$rC, 32]` by `$rB`. In an external context, decrease `MEM[balanceOfStart(MEM[$rC, 32]), 8]` by `$rB`. In an internal context, decrease asset ID `MEM[$rC, 32]` balance of output with contract ID `MEM[$fp, 32]` by `$rB`.

A [call frame](./index.md#call-frames) is pushed at `$sp`. In addition to filling in the values of the call frame, the following registers are set:

1. `$fp = $sp` (on top of the previous call frame is the beginning of this call frame)
1. Set `$ssp` and `$sp` to the start of the writable stack area of the call frame.
1. Set `$pc` and `$is` to the starting address of the code.
1. `$flag` set to zero.
1. `$bal = $rB` (forward coins)
1. `$cgas = $rD` or all available gas (forward gas)

This modifies the `balanceRoot` field of the appropriate output(s).

### `CB`: Coinbase contract id

|             |                                                                                                                     |
|-------------|---------------------------------------------------------------------------------------------------------------------|
| Description | Get the [coinbase contract id](../protocol/tx-validity.md#coinbase-transaction) associated with the block proposer. |
| Operation   | ```MEM[$rA, 32] = coinbase();```                                                                                    |
| Syntax      | `cb $rA`                                                                                                            |
| Encoding    | `0x00 rA - - -`                                                                                                     |
| Notes       |                                                                                                                     |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

### `CCP`: Code copy

|             |                                                                                                                                                  |
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| Description | Copy `$rD` bytes of code starting at `$rC` for contract with ID equal to the 32 bytes in memory starting at `$rB` into memory starting at `$rA`. |
| Operation   | ```MEM[$rA, $rD] = code($rB, $rC, $rD);```                                                                                                       |
| Syntax      | `ccp $rA, $rB, $rC, $rD`                                                                                                                         |
| Encoding    | `0x00 rA rB rC rD`                                                                                                                               |
| Notes       | If `$rD` is greater than the code size, zero bytes are filled in.                                                                                |

This is used only for reading and inspecting code of other contracts.
Use [`LDC`](#ldc-load-code-from-an-external-contract-blob-or-memory) to load code for executing.

Panic if:

- `$rA + $rD` overflows or `> VM_MAX_RAM`
- `$rB + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, $rD]`  does not pass [ownership check](./index.md#ownership)
- Contract with ID `MEM[$rB, 32]` is not in `tx.inputs`

### `CROO`: Code Merkle root

|             |                                                                                                                                       |
|-------------|---------------------------------------------------------------------------------------------------------------------------------------|
| Description | Set the 32 bytes in memory starting at `$rA` to the code root for contract with ID equal to the 32 bytes in memory starting at `$rB`. |
| Operation   | ```MEM[$rA, 32] = coderoot(MEM[$rB, 32]);```                                                                                          |
| Syntax      | `croo $rA, $rB`                                                                                                                       |
| Encoding    | `0x00 rA rB - -`                                                                                                                      |
| Notes       |                                                                                                                                       |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)
- Contract with ID `MEM[$rB, 32]` is not in `tx.inputs`

Code root computation is defined [here](../identifiers/contract-id.md).

### `CSIZ`: Code size

|             |                                                                                                           |
|-------------|-----------------------------------------------------------------------------------------------------------|
| Description | Set `$rA` to the size of the code for contract with ID equal to the 32 bytes in memory starting at `$rB`. |
| Operation   | ```$rA = codesize(MEM[$rB, 32]);```                                                                       |
| Syntax      | `csiz $rA, $rB`                                                                                           |
| Encoding    | `0x00 rA rB - -`                                                                                          |
| Notes       |                                                                                                           |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rB, 32]` is not in `tx.inputs`

### `LDC`: Load code from an external contract, blob or memory

|             |                                                                                                                                                   |
|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| Description | Copy `$rC` bytes of code at offset `$rB` from object identified with `$rA` into memory starting at `$ssp`. Object type is in `imm`.               |
| Operation   | `code = match imm { 0 => contract_code(mem[$rA,32]), 1 => blob_payload(mem[$rA,32]), 2 => mem[$ra, ..] }; MEM[$ssp, $rC] = code[$rB, $rC];`       |
| Syntax      | `ldc $rA, $rB, $rC, imm`                                                                                                                          |
| Encoding    | `0x00 rA rB rC imm`                                                                                                                               |
| Notes       | If `$rC` is greater than the code size, zero bytes are filled in. Final length is always padded to word boundary.                                 |

Object type from `imm` determines the source for loading as follows:

| `imm` | Object type   |
|-------|---------------|
| `0`   | Contract code |
| `1`   | Blob payload  |
| `2`   | VM memory     |
| other | _reserved_    |

Panic if:

- `$ssp + $rC` overflows or `> VM_MAX_RAM`
- `imm <= 1` and `$rA + 32` overflows or `> VM_MAX_RAM`
- `$ssp + $rC >= $hp`
- `imm == 0` and `$rC > CONTRACT_MAX_SIZE`
- `imm == 0` and contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- `imm == 0` and context is a predicate
- `imm == 1` and blob with ID `MEM[$rA, 32]` is not found in the chain state
- `imm == 2` and `$rA + $rB + $rC` overflows or `> VM_MAX_RAM`
- `imm >= 3` (reserved value)

Increment `$fp->codesize`, `$ssp` by `$rC` padded to word alignment. Then set `$sp` to `$ssp`.

This instruction can be used to concatenate the code of multiple contracts or blobs together. It can only be used when the stack area of the call frame is zero-sized.

### `LOG`: Log event

|             |                                |
|-------------|--------------------------------|
| Description | Log an event. This is a no-op. |
| Operation   | ```log($rA, $rB, $rC, $rD);``` |
| Syntax      | `log $rA, $rB, $rC, $rD`       |
| Encoding    | `0x00 rA rB rC rD`             |
| Notes       |                                |

Append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Log`                                                         |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val0` | `uint64`      | Value of register `$rA`.                                                  |
| `val1` | `uint64`      | Value of register `$rB`.                                                  |
| `val2` | `uint64`      | Value of register `$rC`.                                                  |
| `val3` | `uint64`      | Value of register `$rD`.                                                  |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

### `LOGD`: Log data event

|             |                                 |
|-------------|---------------------------------|
| Description | Log an event. This is a no-op.  |
| Operation   | ```logd($rA, $rB, $rC, $rD);``` |
| Syntax      | `logd $rA, $rB, $rC, $rD`       |
| Encoding    | `0x00 rA rB rC rD`              |
| Notes       |                                 |

Append a receipt to the list of receipts:

| name     | type          | description                                                               |
|----------|---------------|---------------------------------------------------------------------------|
| `type`   | `ReceiptType` | `ReceiptType.LogData`                                                     |
| `id`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val0`   | `uint64`      | Value of register `$rA`.                                                  |
| `val1`   | `uint64`      | Value of register `$rB`.                                                  |
| `ptr`    | `uint64`      | Value of register `$rC`.                                                  |
| `len`    | `uint64`      | Value of register `$rD`.                                                  |
| `digest` | `byte[32]`    | [Hash](#s256-sha-2-256) of `MEM[$rC, $rD]`.                               |
| `pc`     | `uint64`      | Value of register `$pc`.                                                  |
| `is`     | `uint64`      | Value of register `$is`.                                                  |

Logs the memory range `MEM[$rC, $rD]`.

Panics if:

- `$rC + $rD` overflows or `> VM_MAX_RAM`

### `MINT`: Mint new coins

|             |                                                             |
|-------------|-------------------------------------------------------------|
| Description | Mint `$rA` coins of the `$rB` ID from the current contract. |
| Operation   | ```mint($rA, $rB);```                                       |
| Syntax      | `mint $rA $rB`                                              |
| Encoding    | `0x00 rA rB - -`                                            |
| Notes       | `$rB` is a pointer to a 32 byte ID in memory                |

The asset ID will be constructed using the asset ID construction method.

Panic if:

- `$rB + 32` overflows or `> VM_MAX_RAM`
- Balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB])` of output with contract ID `MEM[$fp, 32]` plus `$rA` overflows
- `$fp == 0` (in the script context)

For output with contract ID `MEM[$fp, 32]`, increase balance of asset ID `constructAssetID(MEM[$fp, 32], MEM[$rB])` by `$rA`.

This modifies the `balanceRoot` field of the appropriate output.

Append a receipt to the list of receipts:

| name          | type          | description                                |
|---------------|---------------|--------------------------------------------|
| `type`        | `ReceiptType` | `ReceiptType.Mint`                         |
| `sub_id`      | `byte[32]`    | Asset sub identifier `MEM[$rB, $rB + 32]`. |
| `contract_id` | `byte[32]`    | Contract ID of the current context.        |
| `val`         | `uint64`      | Value of register `$rA`.                   |
| `pc`          | `uint64`      | Value of register `$pc`.                   |
| `is`          | `uint64`      | Value of register `$is`.                   |

### `RETD`: Return from context with data

|             |                                                                         |
|-------------|-------------------------------------------------------------------------|
| Description | Returns from [context](./index.md#contexts) with value `MEM[$rA, $rB]`. |
| Operation   | ```returndata($rA, $rB);```                                             |
| Syntax      | `retd $rA, $rB`                                                         |
| Encoding    | `0x00 rA rB - -`                                                        |
| Notes       | `$ret` is set to the pointer `$rA`, and `$retl` to length `$rB`.        |

Panic if:

- `$rA + $rB` overflows or `> VM_MAX_RAM`

Append a receipt to the list of receipts:

| name     | type          | description                                                               |
|----------|---------------|---------------------------------------------------------------------------|
| `type`   | `ReceiptType` | `ReceiptType.ReturnData`                                                  |
| `id`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `ptr`    | `uint64`      | Value of register `$rA`.                                                  |
| `len`    | `uint64`      | Value of register `$rB`.                                                  |
| `digest` | `byte[32]`    | [Hash](#s256-sha-2-256) of `MEM[$rA, $rB]`.                               |
| `pc`     | `uint64`      | Value of register `$pc`.                                                  |
| `is`     | `uint64`      | Value of register `$is`.                                                  |

If current context is a script, append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `0`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

If current context is external, cease VM execution and return `MEM[$rA, $rB]`.

Returns from contract call, popping the call frame. Before popping, perform the following operations.

Return the unused forwarded gas to the caller:

1. `$cgas = $cgas + $fp->$cgas` (add remaining context gas from previous context to current remaining context gas)

Set the return value:

1. `$ret = $rA`
1. `$retl = $rB`

Then pop the call frame and restore all registers _except_ `$ggas`, `$cgas`, `$ret`, `$retl` and `$hp`. Afterwards, set the following registers:

1. `$pc = $pc + 4` (advance program counter from where we called)

### `RVRT`: Revert

|             |                                                                       |
|-------------|-----------------------------------------------------------------------|
| Description | Halt execution, reverting state changes and returning value in `$rA`. |
| Operation   | ```revert($rA);```                                                    |
| Syntax      | `rvrt $rA`                                                            |
| Encoding    | `0x00 rA - - -`                                                       |
| Notes       |                                                                       |

Append a receipt to the list of receipts:

| name   | type          | description                                                               |
|--------|---------------|---------------------------------------------------------------------------|
| `type` | `ReceiptType` | `ReceiptType.Revert`                                                      |
| `id`   | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `val`  | `uint64`      | Value of register `$rA`.                                                  |
| `pc`   | `uint64`      | Value of register `$pc`.                                                  |
| `is`   | `uint64`      | Value of register `$is`.                                                  |

Then append an additional receipt to the list of receipts:

| name       | type          | description                 |
|------------|---------------|-----------------------------|
| `type`     | `ReceiptType` | `ReceiptType.ScriptResult`  |
| `result`   | `uint64`      | `1`                         |
| `gas_used` | `uint64`      | Gas consumed by the script. |

Cease VM execution and revert script effects. After a revert:

1. All [`OutputContract`](../tx-format/output.md#outputcontract) outputs will have the same `balanceRoot` and `stateRoot` as on initialization.
1. All [`OutputVariable`](../tx-format/output.md#outputvariable) outputs will have `to`, `amount`, and `asset_id` of zero.

### `SMO`: Send message out

|             |                                                                                                                                                               |
|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Description | Send a message to recipient address `MEM[$rA, 32]` from the `MEM[$fp, 32]` sender with message data `MEM[$rB, $rC]` and the `$rD` amount of base asset coins. |
| Operation   | ```outputmessage(MEM[$fp, 32], MEM[$rA, 32], MEM[$rB, $rC], $rD);```                                                                                          |
| Syntax      | `smo $rA, $rB, $rC, $rD`                                                                                                                                      |
| Encoding    | `0x00 rA rB rC rD`                                                                                                                                            |
| Effects     | Output message                                                                                                                                                |
| Notes       |                                                                                                                                                               |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- `$rC > MESSAGE_MAX_DATA_SIZE`
- In an external context, if `$rD > MEM[balanceOfStart(0), 8]`
- In an internal context, if `$rD` is greater than the balance of asset ID 0 of output with contract ID `MEM[$fp, 32]`

Append a receipt to the list of receipts:

| name        | type          | description                                                                     |
|-------------|---------------|---------------------------------------------------------------------------------|
| `type`      | `ReceiptType` | `ReceiptType.MessageOut`                                                        |
| `sender`    | `byte[32]`    | The address of the message sender: `MEM[$fp, 32]`.                              |
| `recipient` | `byte[32]`    | The address of the message recipient: `MEM[$rA, 32]`.                           |
| `amount`    | `uint64`      | Amount of base asset coins sent with message: `$rD`.                            |
| `nonce`     | `byte[32]`    | The message nonce as described [here](../identifiers/utxo-id.md#message-nonce). |
| `len`       | `uint64`      | Length of message data, in bytes: `$rC`.                                        |
| `digest`    | `byte[32]`    | [Hash](#s256-sha-2-256) of `MEM[$rB, $rC]`.                                     |

In an external context, decrease `MEM[balanceOfStart(0), 8]` by `$rD`. In an internal context, decrease asset ID 0 balance of output with contract ID `MEM[$fp, 32]` by `$rD`. This modifies the `balanceRoot` field of the appropriate contract that had its' funds deducted.

### `SCWQ`: State clear sequential 32 byte slots

|             |                                                                               |
|-------------|-------------------------------------------------------------------------------|
| Description | A sequential series of 32 bytes is cleared from the current contract's state. |
| Operation   | ```STATE[MEM[$rA, 32], 32 * $rC] = None;```                                   |
| Syntax      | `scwq $rA, $rB, $rC`                                                          |
| Encoding    | `0x00 rA rB rC -`                                                             |
| Notes       |                                                                               |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if any storage slot in the requested range was already unset (default) and `true` if all the slots were set.

### `SRW`: State read word

|             |                                                   |
|-------------|---------------------------------------------------|
| Description | A word is read from the current contract's state. |
| Operation   | ```$rA = STATE[MEM[$rC, 32]][0, 8];```            |
| Syntax      | `srw $rA, $rB, $rC`                               |
| Encoding    | `0x00 rA rB rC -`                                 |
| Effects     | Storage read                                      |
| Notes       | Returns zero if the state element does not exist. |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB` is a [reserved register](./index.md#semantics)
- `$rC + 32` overflows or `> VM_MAX_RAM`
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if the requested slot is unset (default) and `true` if it's set.

### `SRWQ`: State read sequential 32 byte slots

|             |                                                                            |
|-------------|----------------------------------------------------------------------------|
| Description | A sequential series of 32 bytes is read from the current contract's state. |
| Operation   | ```MEM[$rA, 32 * rD] = STATE[MEM[$rC, 32], 32 * rD];```                    |
| Syntax      | `srwq $rA, $rB, $rC, $rD`                                                  |
| Encoding    | `0x00 rA rB rC rD`                                                         |
| Effects     | Storage read                                                               |
| Notes       | Returns zero if the state element does not exist.                          |

Panic if:

- `$rA + 32 * rD` overflows or `> VM_MAX_RAM`
- `$rC + 32 * rD` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- The memory range `MEM[$rA, 32 * rD]`  does not pass [ownership check](./index.md#ownership)
- `$fp == 0` (in the script context)

Register `$rB` will be set to `false` if any storage slot in the requested range is unset (default) and `true` if all the slots are set.

### `SWW`: State write word

|             |                                                                                 |
|-------------|---------------------------------------------------------------------------------|
| Description | A word is written to the current contract's state.                              |
| Operation   | ```STATE[MEM[$rA, 32]][0, 8] = $rC;```<br>```STATE[MEM[$rA, 32]][8, 24] = 0;``` |
| Syntax      | `sww $rA $rB $rC`                                                               |
| Encoding    | `0x00 rA rB rC -`                                                               |
| Effects     | Storage write                                                                   |
| Notes       | Additional gas is charged when a new storage slot is created.                   |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- `$fp == 0` (in the script context)

The last 24 bytes of `STATE[MEM[$rA, 32]]` are set to `0`. Register `$rB` will be set to the number of new slots written, i.e. `1` if the slot was previously unset, and `0` if it already contained a value.

### `SWWQ`: State write sequential 32 byte slots

|             |                                                                             |
|-------------|-----------------------------------------------------------------------------|
| Description | A sequential series of 32 bytes is written to the current contract's state. |
| Operation   | ```STATE[MEM[$rA, 32], 32 * $rD] = MEM[$rC, 32 * $rD];```                   |
| Syntax      | `swwq $rA, $rB, $rC, $rD`                                                   |
| Encoding    | `0x00 rA rB rC rD`                                                          |
| Effects     | Storage write                                                               |
| Notes       | Additional gas is charged when for each new storage slot created.           |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32 * $rD` overflows or `> VM_MAX_RAM`
- `$rB` is a [reserved register](./index.md#semantics)
- `$fp == 0` (in the script context)

Register `$rB` will be set to the number of storage slots that were previously unset, and were set by this operation.

### `TIME`: Timestamp at height

|             |                                         |
|-------------|-----------------------------------------|
| Description | Get timestamp of block at given height. |
| Operation   | ```$rA = time($rB);```                  |
| Syntax      | `time $rA, $rB`                         |
| Encoding    | `0x00 rA rB - -`                        |
| Notes       |                                         |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB` is greater than the current block height.

Gets the timestamp of the block at height `$rB`. Time is in [TAI64](https://cr.yp.to/libtai/tai64.html) format.

### `TR`: Transfer coins to contract

|             |                                                                           |
|-------------|---------------------------------------------------------------------------|
| Description | Transfer `$rB` coins with asset ID at `$rC` to contract with ID at `$rA`. |
| Operation   | ```transfer(MEM[$rA, 32], $rB, MEM[$rC, 32]);```                          |
| Syntax      | `tr $rA, $rB, $rC`                                                        |
| Encoding    | `0x00 rA rB rC -`                                                         |
| Effects     | Balance tree read, balance tree write                                     |
| Notes       |                                                                           |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- Contract with ID `MEM[$rA, 32]` is not in `tx.inputs`
- In an external context, if `$rB > MEM[balanceOfStart(MEM[$rC, 32]), 8]`
- In an internal context, if `$rB` is greater than the balance of asset ID `MEM[$rC, 32]` of output with contract ID `MEM[$fp, 32]`
- `$rB == 0`

Append a receipt to the list of receipts:

| name       | type          | description                                                               |
|------------|---------------|---------------------------------------------------------------------------|
| `type`     | `ReceiptType` | `ReceiptType.Transfer`                                                    |
| `from`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `to`       | `byte[32]`    | Contract ID of contract to transfer coins to.                             |
| `amount`   | `uint64`      | Amount of coins transferred.                                              |
| `asset_id` | `byte[32]`    | asset ID of coins transferred.                                            |
| `pc`       | `uint64`      | Value of register `$pc`.                                                  |
| `is`       | `uint64`      | Value of register `$is`.                                                  |

For output with contract ID `MEM[$rA, 32]`, increase balance of asset ID `MEM[$rC, 32]` by `$rB`. In an external context, decrease `MEM[balanceOfStart(MEM[$rC, 32]), 8]` by `$rB`. In an internal context, decrease asset ID `MEM[$rC, 32]` balance of output with contract ID `MEM[$fp, 32]` by `$rB`.

This modifies the `balanceRoot` field of the appropriate output(s).

### `TRO`: Transfer coins to output

|             |                                                                                     |
|-------------|-------------------------------------------------------------------------------------|
| Description | Transfer `$rC` coins with asset ID at `$rD` to address at `$rA`, with output `$rB`. |
| Operation   | ```transferout(MEM[$rA, 32], $rB, $rC, MEM[$rD, 32]);```                            |
| Syntax      | `tro $rA, $rB, $rC, $rD`                                                            |
| Encoding    | `0x00 rA rB rC rD`                                                                  |
| Effects     | Balance tree read, balance tree write                                               |
| Notes       |                                                                                     |

There is a `balanceOfStart(asset_id: byte[32]) -> uint32` helper that returns the memory address of the remaining free balance of `asset_id`. If `asset_id` has no free balance remaining, the helper panics.

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rD + 32` overflows or `> VM_MAX_RAM`
- `$rB > tx.outputsCount`
- In an external context, if `$rC > MEM[balanceOfStart(MEM[$rD, 32]), 8]`
- In an internal context, if `$rC` is greater than the balance of asset ID `MEM[$rD, 32]` of output with contract ID `MEM[$fp, 32]`
- `$rC == 0`
- `tx.outputs[$rB].type != OutputType.Variable`
- `tx.outputs[$rB].amount != 0`

Append a receipt to the list of receipts:

| name       | type          | description                                                               |
|------------|---------------|---------------------------------------------------------------------------|
| `type`     | `ReceiptType` | `ReceiptType.TransferOut`                                                 |
| `from`     | `byte[32]`    | Contract ID of current context if in an internal context, zero otherwise. |
| `to`       | `byte[32]`    | Address to transfer coins to.                                             |
| `amount`   | `uint64`      | Amount of coins transferred.                                              |
| `asset_id` | `byte[32]`    | asset ID of coins transferred.                                            |
| `pc`       | `uint64`      | Value of register `$pc`.                                                  |
| `is`       | `uint64`      | Value of register `$is`.                                                  |

In an external context, decrease `MEM[balanceOfStart(MEM[$rD, 32]), 8]` by `$rC`. In an internal context, decrease asset ID `MEM[$rD, 32]` balance of output with contract ID `MEM[$fp, 32]` by `$rC`. Then set:

- `tx.outputs[$rB].to = MEM[$rA, 32]`
- `tx.outputs[$rB].amount = $rC`
- `tx.outputs[$rB].asset_id = MEM[$rD, 32]`

This modifies the `balanceRoot` field of the appropriate output(s).

## Blob Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `BSIZ`: Blob size

|             |                                                                                                           |
|-------------|-----------------------------------------------------------------------------------------------------------|
| Description | Set `$rA` to the size of the blob with ID equal to the 32 bytes in memory starting at `$rB`.              |
| Operation   | `$rA = len(blob(MEM[$rB, 32]));`                                                                          |
| Syntax      | `bsiz $rA, $rB`                                                                                           |
| Encoding    | `0x00 rA rB - -`                                                                                          |
| Notes       |                                                                                                           |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Blob ID `MEM[$rB, 32]` is not found

### `BLDD`: Load data from a blob

|             |                                                                                                             |
|-------------|-------------------------------------------------------------------------------------------------------------|
| Description | Load 32-byte blob id at `$rB`, and copy `$rD` bytes starting from `$rC` into `$sA`.                         |
| Operation   | `MEM[$rA, $rD] = blob(MEM[$rB, 32])[$rC, $rD];`                                                             |
| Syntax      | `bldd $rA, $rB, rC, $rD`                                                                                    |
| Encoding    | `0x00 rA rB rC rD`                                                                                          |
| Notes       | If `$rC >` blob size, zero bytes are filled in.                                                             |

Panic if:

- `$rA + $rD` overflows or `> VM_MAX_RAM` or `> $hp`
- `$rB + 32` overflows or `> VM_MAX_RAM`
- Blob ID `MEM[$rB, 32]` is not found

## Cryptographic Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `ECK1`: Secp256k1 signature recovery

|             |                                                                                                                             |
|-------------|-----------------------------------------------------------------------------------------------------------------------------|
| Description | The 64-byte public key (x, y) recovered from 64-byte signature starting at `$rB` on 32-byte message hash starting at `$rC`. |
| Operation   | ```MEM[$rA, 64] = ecrecover_k1(MEM[$rB, 64], MEM[$rC, 32]);```                                                              |
| Syntax      | `eck1 $rA, $rB, $rC`                                                                                                        |
| Encoding    | `0x00 rA rB rC -`                                                                                                           |
| Notes       | Takes message hash as an input. You can use `S256` to hash the message if needed.                                           |

Panic if:

- `$rA + 64` overflows or `> VM_MAX_RAM`
- `$rB + 64` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 64]` does not pass [ownership check](./index.md#ownership)

Signatures and signature verification are specified [here](../protocol/cryptographic-primitives.md#ecdsa-public-key-cryptography).

If the signature cannot be verified, `MEM[$rA, 64]` is set to `0` and `$err` is set to `1`, otherwise `$err` is cleared.

To get the address from the public key, hash the public key with [SHA-2-256](../protocol/cryptographic-primitives.md#hashing).

### `ECR1`: Secp256r1 signature recovery

|             |                                                                                                                             |
|-------------|-----------------------------------------------------------------------------------------------------------------------------|
| Description | The 64-byte public key (x, y) recovered from 64-byte signature starting at `$rB` on 32-byte message hash starting at `$rC`. |
| Operation   | ```MEM[$rA, 64] = ecrecover_r1(MEM[$rB, 64], MEM[$rC, 32]);```                                                              |
| Syntax      | `ecr1 $rA, $rB, $rC`                                                                                                        |
| Encoding    | `0x00 rA rB rC -`                                                                                                           |
| Notes       | Takes message hash as an input. You can use `S256` to hash the message if needed.                                           |

Panic if:

- `$rA + 64` overflows or `> VM_MAX_RAM`
- `$rB + 64` overflows or `> VM_MAX_RAM`
- `$rC + 32` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 64]` does not pass [ownership check](./index.md#ownership)

Signatures and signature verification are specified [here](../protocol/cryptographic-primitives.md#ecdsa-public-key-cryptography).

If the signature cannot be verified, `MEM[$rA, 64]` is set to `0` and `$err` is set to `1`, otherwise `$err` is cleared.

To get the address from the public key, hash the public key with [SHA-2-256](../protocol/cryptographic-primitives.md#hashing).

### `ED19`: EdDSA curve25519 verification

|             |                                                                                                                             |
|-------------|-----------------------------------------------------------------------------------------------------------------------------|
| Description | Verification 64-byte signature at `$rB` with 32-byte public key at `$rA` for a message starting at `$rC` with length `$rD`. |
| Operation   | ```ed19verify(MEM[$rA, 32], MEM[$rB, 64], MEM[$rC, $rD]);```                                                                |
| Syntax      | `ed19 $rA, $rB, $rC, $rD`                                                                                                   |
| Encoding    | `0x00 rA rB rC rD`                                                                                                          |
| Notes       | Takes message instead of hash. **For backwards compatibility reasons, if `$rD == 0`, it will be treated as `32`.**          |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + 64` overflows or `> VM_MAX_RAM`
- `$rC + $rD` overflows or `> VM_MAX_RAM`

Verification are specified [here](../protocol/cryptographic-primitives.md#eddsa-public-key-cryptography).

If there is an error in verification, `$err` is set to `1`, otherwise `$err` is cleared.

### `K256`: keccak-256

|             |                                                       |
|-------------|-------------------------------------------------------|
| Description | The keccak-256 hash of `$rC` bytes starting at `$rB`. |
| Operation   | ```MEM[$rA, 32] = keccak256(MEM[$rB, $rC]);```        |
| Syntax      | `k256 $rA, $rB, $rC`                                  |
| Encoding    | `0x00 rA rB rC -`                                     |
| Notes       |                                                       |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

### `S256`: SHA-2-256

|             |                                                      |
|-------------|------------------------------------------------------|
| Description | The SHA-2-256 hash of `$rC` bytes starting at `$rB`. |
| Operation   | ```MEM[$rA, 32] = sha256(MEM[$rB, $rC]);```          |
| Syntax      | `s256 $rA, $rB, $rC`                                 |
| Encoding    | `0x00 rA rB rC -`                                    |
| Notes       |                                                      |

Panic if:

- `$rA + 32` overflows or `> VM_MAX_RAM`
- `$rB + $rC` overflows or `> VM_MAX_RAM`
- The memory range `MEM[$rA, 32]`  does not pass [ownership check](./index.md#ownership)

### `ECOP`: Elliptic curve point operation

|             |                                                     |
|-------------|-----------------------------------------------------|
| Description | Perform arithmetic operation `$rC` on points of the elliptic curve `$rB`. Arguments are read from memory at `$rD`, and result is written to the memory at `$rA`, as per the table below.                                                   |
| Operation   | ```MEM[$rA, X] = ecop(MEM[$rD, Y]);```              |
| Syntax      | `ecop $rA, $rB, $rC, $rD`                           |
| Encoding    | `0x00 rA rB rC rD`                                  |
| Notes       | For now, only `$rB` = 0 is accepted                 |

#### Curve ID `$rB` possible values

- `0`: `alt_bn128` elliptic curve.

#### Operation type `$rC` supported

- `0`: two points addition
- `1`: one point and one scalar multiplication

#### Encoding of points and results by curve ID and operation type

- 1P = one point = (X, Y) = ([32 bytes], [32 bytes])
- 1S = one scalar = X = [32 bytes]

| `$rB` Curve ID | `$rC` Operation type | `$rA` format         | `$rD` format               |
|----------------|----------------------|----------------------|----------------------------|
|    `0`         | `0`                  | `MEM[$rA, 64]` `1P`  | `MEM[$rD, 128]` `1P1P`     |
|    `0`         | `1`                  | `MEM[$rA, 64]` `1P`  | `MEM[$rD, 96]` `1P1S`      |

#### Panic cases

- Curve ID is not supported (`$rB`)
- Operation type is not supported (`$rC`)
- `$rD` + (size depending on the table above) overflows or `> VM_MAX_RAM`
- Decoding of `$rD` memory doesn't match the expected format described above for each case.
- The memory range at `$rA` (size depending on the curve/operation types) does not pass [ownership check](./index.md#ownership)

### `EPAR`: Elliptic curve point pairing check

|             |                                                     |
|-------------|-----------------------------------------------------|
| Description | Check if `$rC` groups of points at `$rD` all form valid pairings in (curve, pairing type) identified by `$rB`. Set `$rA` to the result of the pairing, either `0` or `1`. |
| Operation   | ```$rA = epar(MEM[$rD, X * $rC]);```                |
| Syntax      | `epar $rA, $rB, $rC, $rD`                           |
| Encoding    | `0x00 rA rB rC rD`                                  |
| Notes       | For now, only `$rB` = 0 is accepted.                |

<!-- markdownlint-disable-next-line no-duplicate-header -->
#### Curve/Pairing ID `$rB` possible values

- `0`: optimal ate pairing on `alt_bn128` elliptic curve.

#### Encoding of points by curve ID and check type

- 1P = one point = (X, Y) = ([32 bytes], [32 bytes])

| `$rB` Curve / Pairing ID  | `$rD` format               |
|---------------------------|----------------------------|
|    `0`                    | `MEM[$rD, (64 + 64 + 64) * $rC]` Each element is `1P1P1P` (three points coordinates) (192 bytes)   |

<!-- markdownlint-disable-next-line no-duplicate-header -->
#### Panic cases

- Curve ID/Pairing is not supported (`$rB`)
- `$rD` has elements than described in `$rC`
- `$rD` + (size depending on the table above) overflows or `> VM_MAX_RAM`
- Decoding of `$rD` memory doesn't match the expected format described above for each case.
- The memory range at `$rA` (size depending on the curve/operation types) does not pass [ownership check](./index.md#ownership)

## Other Instructions

All these instructions advance the program counter `$pc` by `4` after performing their operation.

### `ECAL`: Call external function

|             |                                                                          |
|-------------|--------------------------------------------------------------------------|
| Description | Call an external function that has full access to the VM state.          |
| Operation   | `external(&mut vm, $rA, $rB, $rC, $rD)`                                  |
| Syntax      | `ecal $rA $rB $rC $rD`                                                   |
| Encoding    | `0x00 rA rB rC rD`                                                       |
| Notes       | Does nothing by default, but the VM user can define this to do anything. |

This function provides an escape hatch from the VM, similar to `ecall` instruction of RISC-V. The suggested convention is to use `$rA` for "system call number", i.e. identifying the procedure to call, but all arguments can be used freely. The operation can modify the VM state freely, including writing to registers and memory. Again, the suggested convention is to use `$rA` for the return value and `$err` for any possible errors. However, these conventions can be ignored when necessary.

Panic if:

- The external function panics.

### `FLAG`: Set flags

|             |                       |
|-------------|-----------------------|
| Description | Set `$flag` to `$rA`. |
| Operation   | ```$flag = $rA;```    |
| Syntax      | `flag $rA`            |
| Encoding    | `0x00 rA - - -`       |
| Notes       |                       |

Panic if:

- Any reserved flags are set

### `GM`: Get metadata

|             |                           |
|-------------|---------------------------|
| Description | Get metadata from memory. |
| Operation   | Varies (see below).       |
| Syntax      | `gm $rA, imm`             |
| Encoding    | `0x00 rA imm imm imm`     |
| Notes       |                           |

Read metadata from memory. A convenience instruction to avoid manually extracting metadata.

| name                         | value     | description                      |
|------------------------------|-----------|----------------------------------|
| `GM_IS_CALLER_EXTERNAL`      | `0x00001` | Get if caller is external.       |
| `GM_GET_CALLER`              | `0x00002` | Get caller's contract ID.        |
| `GM_GET_VERIFYING_PREDICATE` | `0x00003` | Get index of current predicate.  |
| `GM_GET_CHAIN_ID`            | `0x00004` | Get the value of `CHAIN_ID`      |
| `GM_TX_START`                | `0x00005` | Transaction start memory address |
| `GM_BASE_ASSET_ID`           | `0x00006` | Base asset ID                    |
| `GM_GET_GAS_PRICE`           | `0x00007` | Get the gas price of the block.  |

If `imm == GM_IS_CALLER_EXTERNAL`:

Panic if:

- `$fp == 0` (in an external context)

Set `$rA` to `true` if parent is an external context, `false` otherwise.

If `imm == GM_GET_CALLER`:

Panic if:

- `$fp == 0` (in an external context)
- `$fp->$fp == 0` (if parent context is external)

Set `$rA` to `$fp->$fp` (i.e. `$rA` will point to the previous call frame's contract ID).

If `imm == GM_GET_VERIFYING_PREDICATE`:

Panic if:

- not in a predicate context

Set `$rA` to the index of the currently-verifying predicate.

If `imm == GM_GET_GAS_PRICE`:

Panic if:

- in a predicate context

Set `$rA` to the gas price of the block.

### `GTF`: Get transaction fields

|             |                                         |
|-------------|-----------------------------------------|
| Description | Get transaction fields.                 |
| Operation   | Set `$rA` according to the table below. |
| Syntax      | `gtf $rA, $rB, imm`                     |
| Encoding    | `0x00 rA rB i i`                        |
| Notes       | `$rB` is ignored for many variants.     |

Get [fields from the transaction](../tx-format/transaction.md).

| name                                      | `imm`   | set `$rA` to                                                      |
|-------------------------------------------|---------|-------------------------------------------------------------------|
| `GTF_TYPE`                                | `0x001` | `tx.type`                                                         |
| `GTF_SCRIPT_GAS_LIMIT`                    | `0x002` | `tx.scriptGasLimit`                                               |
| `GTF_SCRIPT_SCRIPT_LENGTH`                | `0x003` | `tx.scriptLength`                                                 |
| `GTF_SCRIPT_SCRIPT_DATA_LENGTH`           | `0x004` | `tx.scriptDataLength`                                             |
| `GTF_SCRIPT_INPUTS_COUNT`                 | `0x005` | `tx.inputsCount`                                                  |
| `GTF_SCRIPT_OUTPUTS_COUNT`                | `0x006` | `tx.outputsCount`                                                 |
| `GTF_SCRIPT_WITNESSES_COUNT`              | `0x007` | `tx.witnessesCount`                                               |
| `GTF_SCRIPT_SCRIPT`                       | `0x009` | Memory address of `tx.script`                                     |
| `GTF_SCRIPT_SCRIPT_DATA`                  | `0x00A` | Memory address of `tx.scriptData`                                 |
| `GTF_SCRIPT_INPUT_AT_INDEX`               | `0x00B` | Memory address of `tx.inputs[$rB]`                                |
| `GTF_SCRIPT_OUTPUT_AT_INDEX`              | `0x00C` | Memory address of `t.outputs[$rB]`                                |
| `GTF_SCRIPT_WITNESS_AT_INDEX`             | `0x00D` | Memory address of `tx.witnesses[$rB]`                             |
| `GTF_TX_LENGTH`                           | `0x00E` | Length of raw transaction types in memory                        |
| `GTF_CREATE_BYTECODE_WITNESS_INDEX`       | `0x101` | `tx.bytecodeWitnessIndex`                                         |
| `GTF_CREATE_STORAGE_SLOTS_COUNT`          | `0x102` | `tx.storageSlotsCount`                                            |
| `GTF_CREATE_INPUTS_COUNT`                 | `0x103` | `tx.inputsCount`                                                  |
| `GTF_CREATE_OUTPUTS_COUNT`                | `0x104` | `tx.outputsCount`                                                 |
| `GTF_CREATE_WITNESSES_COUNT`              | `0x105` | `tx.witnessesCount`                                               |
| `GTF_CREATE_SALT`                         | `0x106` | Memory address of `tx.salt`                                       |
| `GTF_CREATE_STORAGE_SLOT_AT_INDEX`        | `0x107` | Memory address of `tx.storageSlots[$rB]`                          |
| `GTF_CREATE_INPUT_AT_INDEX`               | `0x108` | Memory address of `tx.inputs[$rB]`                                |
| `GTF_CREATE_OUTPUT_AT_INDEX`              | `0x109` | Memory address of `t.outputs[$rB]`                                |
| `GTF_CREATE_WITNESS_AT_INDEX`             | `0x10A` | Memory address of `tx.witnesses[$rB]`                             |
| `GTF_INPUT_TYPE`                          | `0x200` | `tx.inputs[$rB].type`                                             |
| `GTF_INPUT_COIN_TX_ID`                    | `0x201` | Memory address of `tx.inputs[$rB].txID`                           |
| `GTF_INPUT_COIN_OUTPUT_INDEX`             | `0x202` | `tx.inputs[$rB].outputIndex`                                      |
| `GTF_INPUT_COIN_OWNER`                    | `0x203` | Memory address of `tx.inputs[$rB].owner`                          |
| `GTF_INPUT_COIN_AMOUNT`                   | `0x204` | `tx.inputs[$rB].amount`                                           |
| `GTF_INPUT_COIN_ASSET_ID`                 | `0x205` | Memory address of `tx.inputs[$rB].asset_id`                       |
| `GTF_INPUT_COIN_WITNESS_INDEX`            | `0x207` | `tx.inputs[$rB].witnessIndex`                                     |
| `GTF_INPUT_COIN_PREDICATE_LENGTH`         | `0x209` | `tx.inputs[$rB].predicateLength`                                  |
| `GTF_INPUT_COIN_PREDICATE_DATA_LENGTH`    | `0x20A` | `tx.inputs[$rB].predicateDataLength`                              |
| `GTF_INPUT_COIN_PREDICATE`                | `0x20B` | Memory address of `tx.inputs[$rB].predicate`                      |
| `GTF_INPUT_COIN_PREDICATE_DATA`           | `0x20C` | Memory address of `tx.inputs[$rB].predicateData`                  |
| `GTF_INPUT_COIN_PREDICATE_GAS_USED`       | `0x20D` | `tx.inputs[$rB].predicateGasUsed`                                 |
| `GTF_INPUT_CONTRACT_CONTRACT_ID`          | `0x225` | Memory address of `tx.inputs[$rB].contractID`                     |
| `GTF_INPUT_MESSAGE_SENDER`                | `0x240` | Memory address of `tx.inputs[$rB].sender`                         |
| `GTF_INPUT_MESSAGE_RECIPIENT`             | `0x241` | Memory address of `tx.inputs[$rB].recipient`                      |
| `GTF_INPUT_MESSAGE_AMOUNT`                | `0x242` | `tx.inputs[$rB].amount`                                           |
| `GTF_INPUT_MESSAGE_NONCE`                 | `0x243` | Memory address of `tx.inputs[$rB].nonce`                          |
| `GTF_INPUT_MESSAGE_WITNESS_INDEX`         | `0x244` | `tx.inputs[$rB].witnessIndex`                                     |
| `GTF_INPUT_MESSAGE_DATA_LENGTH`           | `0x245` | `tx.inputs[$rB].dataLength`                                       |
| `GTF_INPUT_MESSAGE_PREDICATE_LENGTH`      | `0x246` | `tx.inputs[$rB].predicateLength`                                  |
| `GTF_INPUT_MESSAGE_PREDICATE_DATA_LENGTH` | `0x247` | `tx.inputs[$rB].predicateDataLength`                              |
| `GTF_INPUT_MESSAGE_DATA`                  | `0x248` | Memory address of `tx.inputs[$rB].data`                           |
| `GTF_INPUT_MESSAGE_PREDICATE`             | `0x249` | Memory address of `tx.inputs[$rB].predicate`                      |
| `GTF_INPUT_MESSAGE_PREDICATE_DATA`        | `0x24A` | Memory address of `tx.inputs[$rB].predicateData`                  |
| `GTF_INPUT_MESSAGE_PREDICATE_GAS_USED`    | `0x24B` | `tx.inputs[$rB].predicateGasUsed`                                 |
| `GTF_OUTPUT_TYPE`                         | `0x300` | `tx.outputs[$rB].type`                                            |
| `GTF_OUTPUT_COIN_TO`                      | `0x301` | Memory address of `tx.outputs[$rB].to`                            |
| `GTF_OUTPUT_COIN_AMOUNT`                  | `0x302` | `tx.outputs[$rB].amount`                                          |
| `GTF_OUTPUT_COIN_ASSET_ID`                | `0x303` | Memory address of `tx.outputs[$rB].asset_id`                      |
| `GTF_OUTPUT_CONTRACT_INPUT_INDEX`         | `0x304` | `tx.outputs[$rB].inputIndex`                                      |
| `GTF_OUTPUT_CONTRACT_BALANCE_ROOT`        | `0x305` | Memory address of `tx.outputs[$rB].balanceRoot`                   |
| `GTF_OUTPUT_CONTRACT_STATE_ROOT`          | `0x306` | Memory address of `tx.outputs[$rB].stateRoot`                     |
| `GTF_OUTPUT_CONTRACT_CREATED_CONTRACT_ID` | `0x307` | Memory address of `tx.outputs[$rB].contractID`                    |
| `GTF_OUTPUT_CONTRACT_CREATED_STATE_ROOT`  | `0x308` | Memory address of `tx.outputs[$rB].stateRoot`                     |
| `GTF_WITNESS_DATA_LENGTH`                 | `0x400` | `tx.witnesses[$rB].dataLength`                                    |
| `GTF_WITNESS_DATA`                        | `0x401` | Memory address of `tx.witnesses[$rB].data`                        |
| `GTF_POLICY_TYPES`                        | `0x500` | `tx.policies.policyTypes`                                         |
| `GTF_POLICY_TIP`                          | `0x501` | `tx.policies[0x00].tip`                                           |
| `GTF_POLICY_WITNESS_LIMIT`                | `0x502` | `tx.policies[count_ones(0b11 & tx.policyTypes) - 1].witnessLimit` |
| `GTF_POLICY_MATURITY`                     | `0x503` | `tx.policies[count_ones(0b111 & tx.policyTypes) - 1].maturity`    |
| `GTF_POLICY_MAX_FEE`                      | `0x504` | `tx.policies[count_ones(0b1111 & tx.policyTypes) - 1].maxFee`     |
| `GTF_POLICY_EXPIRATION`                   | `0x505` | `tx.policies[count_ones(0b11111 & tx.policyTypes) - 1].expiration`|
| `GTF_UPLOAD_ROOT`                         | `0x600` | Memory address of `tx.root`                                       |
| `GTF_UPLOAD_WITNESS_INDEX`                | `0x601` | Set `$rA` to `tx.witnessIndex`                                    |
| `GTF_UPLOAD_SUBSECTION_INDEX`             | `0x602` | Set `$rA` to `tx.subsectionIndex`                                 |
| `GTF_UPLOAD_SUBSECTIONS_COUNT`            | `0x603` | Set `$rA` to `tx.subsectionsNumber`                               |
| `GTF_UPLOAD_PROOF_SET_COUNT`              | `0x604` | Set `$rA` to `tx.proofSetCount`                                   |
| `GTF_UPLOAD_PROOF_SET_AT_INDEX`           | `0x605` | Set `$rA` to `Memory address of tx.proofSet[$rB]`                 |
| `GTF_BLOB_ID`                             | `0x700` | Set `$rA` to `Memory address of tx.id`                            |
| `GTF_BLOB_WITNESS_INDEX`                  | `0x701` | Set `$rA` to the blob `tx.witnessIndex`                           |
| `GTF_UPGRADE_PURPOSE`                     | `0x800` | Set `$rA` to `Memory address of tx.purpose`                       |
| `GTF_TX_INPUTS_COUNT`                     | `0x900` | Set `$rA` to `tx.inputsCount`                                     |
| `GTF_TX_OUTPUTS_COUNT`                    | `0x901` | Set `$rA` to `tx.outputsCount`                                    |
| `GTF_TX_WITNESSES_COUNT`                  | `0x902` | Set `$rA` to `tx.witnessesCount`                                  |
| `GTF_TX_INPUT_AT_INDEX`                   | `0x903` | Set `$rA` to `Memory address of tx.inputs[$rB]`                   |
| `GTF_TX_OUTPUT_AT_INDEX`                  | `0x904` | Set `$rA` to `Memory address of t.outputs[$rB]`                   |
| `GTF_TX_WITNESS_AT_INDEX`                 | `0x905` | Set `$rA` to `Memory address of tx.witnesses[$rB]`                |

Panic if:

- `$rA` is a [reserved register](./index.md#semantics)
- `imm` is not one of the values listed above
- The value of `$rB` results in an out of bounds access for variable-length fields
- The input or output type does not match (`OutputChange` and `OutputVariable` count as `OutputCoin`)
- The requested policy type is not set for this transaction.

For fixed-length fields, the value of `$rB` is ignored.


---

### File: docs/nightly/fuel-specs/src/identifiers/asset.md

# Asset ID

The _asset ID_ (also called _asset hash_) of a asset is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of the `CONTRACT_ID` and a 256-bit `SUB_IDENTIFIER`.

```python
sha256(CONTRACT_ID ++ SUB_IDENTIFIER)
```


---

### File: docs/nightly/fuel-specs/src/identifiers/blob-id.md

# Blob ID

The _blob ID_ (also called _blob hash_) of a transaction is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of the blob data.

Blob ID calculation doesn't vary between chains.

```python
sha256(blob_data)
```


---

### File: docs/nightly/fuel-specs/src/identifiers/contract-id.md

# Contract ID

For a transaction of type `TransactionType.Create`, `tx`, the contract ID is
`sha256(0x4655454C ++ tx.data.salt ++ root(tx.data.witnesses[bytecodeWitnessIndex].data) ++ root_smt(tx.storageSlots))`,
where `root` is the Merkle root of [the binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) with
each leaf being 16KiB of instructions, and `root_smt` is the
[Sparse Merkle tree](../protocol/cryptographic-primitives.md#sparse-merkle-tree) root of the provided key-value pairs.
If the bytecode is not a multiple of 16 KiB, the final leaf should be zero-padded rounding up to the nearest multiple
of 8 bytes.


---

### File: docs/nightly/fuel-specs/src/identifiers/index.md

# Identifiers

This chapter defines how to compute unique identifiers.

- [Asset ID](./asset.md)
- [Blob ID](./blob-id.md)
- [Contract ID](./contract-id.md)
- [Predicate ID](./predicate-id.md)
- [Transaction ID](./transaction-id.md)
- [UTXO ID](./utxo-id.md)
  - [Coin ID](./utxo-id.md#coin-id)
  - [Message ID](./utxo-id.md#message-id)
    - [Message Nonce](./utxo-id.md#message-nonce)
  - [Fee ID](./utxo-id.md#fee-id)


---

### File: docs/nightly/fuel-specs/src/identifiers/predicate-id.md

# Predicate ID

For an input of type `InputType.Coin` or `InputType.Message`, `input`, the predicate owner is calculated as:
`sha256(0x4655454C ++ root(input.predicate))`, where `root` is the Merkle root of
[the binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) each leaf being 16KiB of instructions.
If the bytecode is not a multiple of 16 KiB, the final leaf should be zero-padded rounding up to the nearest multiple of 8 bytes.


---

### File: docs/nightly/fuel-specs/src/identifiers/transaction-id.md

# Transaction ID

The _transaction ID_ (also called _transaction hash_) of a transaction is computed as
the [hash](../protocol/cryptographic-primitives.md#hashing) of `CHAIN_ID` and the
[serialized transaction](../tx-format/transaction.md) with [fields zeroed out for signing](../tx-format/index.md)
(see different inputs and outputs for which fields are set to zero), and without witness data. In other words, only
all non-witness data is hashed.

```python
sha256(CHAIN_ID ++ serialized_tx(tx))
```


---

### File: docs/nightly/fuel-specs/src/identifiers/utxo-id.md

# UTXO ID

## Coin ID

Is represented as an _outpoint_: a pair of [transaction ID](./transaction-id.md) as `byte[32]` and output index as a `uint16`.

## Message ID

The ID of a message is computed as the [hash](../protocol/cryptographic-primitives.md#hashing) of:

1. the sender address as `byte[32]`,
1. the recipient address as `byte[32]`,
1. the [Message nonce](#message-nonce) as `byte[32]`,
1. the amount being sent with the message as `uint64`,
1. the message data as `byte[]`

`hash(byte[32] ++ byte[32] ++ byte[32] ++ uint64 ++ byte[])`. The address values are serialized as a byte array of length 32 left-padded with zeroes, and all other value types are serialized according to the standard [transaction serialization](../tx-format/transaction.md). Note that the message data length is not included since there is only one dynamically sized field and can be implicitly determined by the hash preimage size.

### Message Nonce

The nonce value for `InputMessage` is determined by the sending system and is published at the time the message is sent. The nonce value for `OutputMessage` is computed as the [hash](../protocol/cryptographic-primitives.md#hashing) of the [Transaction ID](./transaction-id.md) that emitted the message and the index of the message receipt `uint16` (with canonical encoding): `hash(byte[32] ++ canonical(uint16))`.

## Fee ID

The UTXO ID of collected fees in a block is the block height as a 32-byte big-endian unsigned integer (i.e. the first byte of the 32-byte array is the most significant byte, and so on).


---

### File: docs/nightly/fuel-specs/src/index.md

# Fuel Specifications

<!-- markdownlint-disable-next-line MD036 -->
**Fuel: A Secure Decentralized Generalized Massively Scalable Transaction Ledger**

This book specifies the Fuel protocol, including the Fuel Virtual Machine
(short: FuelVM), a blazingly fast verifiable blockchain virtual machine.

## Protocol

- [**Transaction Format**](./tx-format/index.md) - The Fuel transaction format.
- [**Computing Identifiers**](./identifiers/index.md) - Computing unique IDs for transactions, contracts and UTXOs.
- [**Transaction Validity**](./protocol/tx-validity.md) - Defines transaction validity rules.
- [**Cryptographic Primitives**](./protocol/cryptographic-primitives.md) - Cryptographic primitives used in Fuel.
- [**Application Binary Interface (ABI)**](./abi/index.md) - Low-level details on interfacing with Fuel bytecode.
- [**Storage Slot Initialization**](./protocol/storage-initialization.md) - JSON format for contract storage slot initialization.
- [**Block Header Format**](./protocol/block-header.md) - The Fuel block header format.
- [**Relayer/Bridge**](./protocol/relayer.md) - The Fuel relayer/bridge protocol.

## FuelVM

- [**Overview**](./fuel-vm/index.md) - Describes the FuelVM at a high level, from its architecture to how it is initialized.
- [**Instruction Set**](./fuel-vm/instruction-set.md) - Defines the FuelVM instruction set.

## Network-Specific

- [**Proof of Authority (PoA)**](./networks/poa.md) - The Fuel Proof of Authority Network.

## Testing

- [**Sparse Merkle Tree**](./tests/sparse-merkle-tree-tests.md) - A test suite for verifying correctness of SMT outputs.


---

### File: docs/nightly/fuel-specs/src/networks/index.md

# Networks

Specifications for network-specific components of the protocol.

- [PoA Network](./poa.md)


---

### File: docs/nightly/fuel-specs/src/networks/poa.md

# PoA Network

## Consensus Header

Wraps the [application header](../protocol/block-header.md#application-header).

name              | type       | description
------------------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------
`prevRoot`        | `byte[32]` | [Merkle root](../protocol/cryptographic-primitives.md#binary-merkle-tree) of all previous consensus header hashes (i.e. not including this block).
`height`          | `uint32`   | Height of this block.
`timestamp`       | `uint64`   | Time this block was created, in [TAI64](https://cr.yp.to/libtai/tai64.html) format.
`applicationHash` | `byte[32]` | [Hash](../protocol/cryptographic-primitives.md#hashing) of serialized [application header](../protocol/block-header.md#application-header) for this block.

Consensus for the consensus header is a single [signature](../protocol/cryptographic-primitives.md#public-key-cryptography) from the authority over the [hash](../protocol/cryptographic-primitives.md#hashing) of the serialized consensus header.

Since the system is secure under the assumption the authority is honest, there is no need for committing to the authority signatures in the header.


---

### File: docs/nightly/fuel-specs/src/protocol/block-header.md

# Block Header

## Application Header

The application header is a network-agnostic block header. Different [networks](../networks/index.md) may wrap the application header in a consensus header, depending on their consensus protocol.

| name                             | type       | description                                                                                                                                                                                                                                         |
|----------------------------------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `da_height`                      | `uint64`   | Height of the data availability layer up to which (inclusive) input messages are processed.                                                                                                                                                         |
| `consensusParametersVersion`     | `uint32`   | The version of the consensus parameters used to execute this block.                                                                                                                                                                                 |
| `stateTransitionBytecodeVersion` | `uint32`   | The version of the state transition bytecode used to execute this block.                                                                                                                                                                            |
| `txCount`                        | `uint16`   | Number of [transaction](../tx-format/transaction.md)s in this block.                                                                                                                                                                                |
| `message_receipt_count`          | `uint32`   | Number of [output message](../abi/receipts.md#messageout-receipt)s in this block.                                                                                                                                                                   |
| `txRoot`                         | `byte[32]` | [Merkle root](./cryptographic-primitives.md#binary-merkle-tree) of [transaction](../tx-format/transaction.md)s in this block.                                                                                                                       |
| `message_outbox_root`            | `byte[32]` | [Merkle root](./cryptographic-primitives.md#binary-merkle-tree) of [output message](../abi/receipts.md#messageout-receipt)s [`messageId`](../identifiers/utxo-id.md#message-id) in this block.                                                      |
| `event_inbox_root`               | `byte[32]` | [Merkle root](./cryptographic-primitives.md#binary-merkle-tree) of all [events](./relayer.md) imported from L1 in this block. The order of the events added to the Merkle tree is the L1 block order, and the index of each event within each block |


---

### File: docs/nightly/fuel-specs/src/protocol/cryptographic-primitives.md

# Cryptographic Primitives

- [Hashing](#hashing)
- [Merkle Trees](#merkle-trees)
  - [Binary Merkle Tree](#binary-merkle-tree)
  - [Sparse Merkle Tree](#sparse-merkle-tree)
- [EcDSA Public-Key Cryptography](#ecdsa-public-key-cryptography)
- [EdDSA Public-Key Cryptography](#eddsa-public-key-cryptography)

## Hashing

All hashing is done with SHA-2-256 (also known as SHA-256), defined in [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).

## `HashDigest`

Output of the [hashing](#hashing) function. Exactly 256 bits (32 bytes) long.

## Merkle Trees

Two Merkle tree structures are used: a Binary Merkle Tree (to commit to bytecode) and a Sparse Merkle Tree (to commit to contract storage, i.e. state).

### Binary Merkle Tree

Binary Merkle trees are constructed in the same fashion as described in [Certificate Transparency (RFC-6962)](https://tools.ietf.org/html/rfc6962), except for using [a different hashing function](#hashing). Leaves are hashed once to get leaf node values and internal node values are the hash of the concatenation of their children (either leaf nodes or other internal nodes).

Nodes contain a single field:

| name | type                      | description |
|------|---------------------------|-------------|
| `v`  | [`HashDigest`](#hashdigest) | Node value. |

The base case (an empty tree) is defined as the [hash](#hashing) of the empty string:

```C++
node.v = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```

For leaf node `node` of leaf data `d`:

```C++
node.v = h(0x00, serialize(d))
```

For internal node `node` with children `l` and `r`:

```C++
node.v = h(0x01, l.v, r.v)
```

Note that rather than duplicating the last node if there are an odd number of nodes (the [Bitcoin design](https://github.com/bitcoin/bitcoin/blob/5961b23898ee7c0af2626c46d5d70e80136578d3/src/consensus/merkle.cpp#L9-L43)), trees are allowed to be imbalanced. In other words, the height of each leaf may be different. For an example, see Section 2.1.3 of [Certificate Transparency (RFC-6962)](https://tools.ietf.org/html/rfc6962#section-2.1.3).

Leaves and internal nodes are hashed differently: the one-byte `0x00` is prepended for leaf nodes while `0x01` is prepended for internal nodes. This avoids a second-preimage attack [where internal nodes are presented as leaves](https://en.wikipedia.org/wiki/Merkle_tree#Second_preimage_attack) trees with leaves at different heights.

#### Binary Merkle Tree Inclusion Proofs

| name       | type                          | description                                                     |
|------------|-------------------------------|-----------------------------------------------------------------|
| `root`     | [`HashDigest`](#hashdigest)`[]` | The expected root of the Merkle tree.                           |
| `data`     | Bytes                         | The data of the leaf (unhashed).                                |
| `siblings` | [`HashDigest`](#hashdigest)`[]` | Sibling hash values, ordered starting from the leaf's neighbor. |

A proof for a leaf in a [binary Merkle tree](#binary-merkle-tree), as per Section 2.1.1 of [Certificate Transparency (RFC-6962)](https://tools.ietf.org/html/rfc6962#section-2.1.1).

In some contexts, the array of sibling hashes is also known as the proof set. Note that proof format prescribes that leaf data be in its original, unhashed state, while the proof set (array of sibling data) uses hashed data. This format precludes the proof set from itself including the leaf data from the leaf undergoing the proof; rather, proof verification explicitly requires hashing the leaf data during the calculation of the proof set root.

### Sparse Merkle Tree

Sparse Merkle Trees (SMTs) are _sparse_, i.e. they contain mostly empty leaves. They can be used as key-value stores for arbitrary data, as each leaf is keyed by its index in the tree. Storage efficiency is achieved through clever use of implicit defaults, avoiding the need to store empty leaves.

Additional rules are added on top of plain [binary Merkle trees](#binary-merkle-tree):

1. Default values are given to leaf nodes with empty leaves.
1. While the above rule is sufficient to pre-compute the values of intermediate nodes that are roots of empty subtrees, a further simplification is to extend this default value to all nodes that are roots of empty subtrees. The 32-byte zero, i.e. `0x0000000000000000000000000000000000000000000000000000000000000000`, is used as the default value. This rule takes precedence over the above one.
1. The number of hashing operations can be reduced to be logarithmic in the number of non-empty leaves on average, assuming a uniform distribution of non-empty leaf keys. An internal node that is the root of a subtree that contains exactly one non-empty leaf is replaced by that leaf's leaf node.

Nodes contain a single field:

| name | type                      | description |
|------|---------------------------|-------------|
| `v`  | [`HashDigest`](#hashdigest) | Node value. |

In the base case, where a sparse Merkle tree has `height = 0`, the root of a tree is defined as the [hash](#hashing) of the empty string:

```C++
node.v = 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
```

When a sparse Merkle tree has a height of 0, it can have no leaves, and, therefore, no default value children. The root is then calculated as the hash of the empty string, similar to that of an empty binary Merkle tree.

For a tree with `height > 0`, the root of an empty tree is defined as the default value:

```C++
node.v = 0x0000000000000000000000000000000000000000000000000000000000000000
```

Note that this is in contrast to the base case of the sparse and binary Merkle trees, where the root is the hash of the empty string. When a sparse Merkle tree has a height greater than 0, a new tree instance is composed of default value leaves. Nodes containing only default value children have the default value as well. Applying these rules recursively percolates the default value up to the tree's root.

For leaf node `node` of leaf data `d` with key `k`:

```C++
node.v = h(0x00, k, h(serialize(d)))
```

The key of leaf nodes must be prepended, since the index of a leaf node that is not at maximum depth cannot be determined without this information. Leaf values are hashed so that they do not need to be included in full in non-membership proofs.

For internal node `node` with children `l` and `r`:

```C++
node.v = h(0x01, l.v, r.v)
```

#### Insertion

Before insertion of the key-value pair, each key of the Sparse Merkle Tree should be hashed with `sha256` to prevent tree structure manipulations.
During the proof verification, the original leaf key should be hashed similarly. Otherwise, the root will not match.

#### Sparse Merkle Tree Inclusion Proofs

SMTs can further be extended with _compact_ proofs. Merkle proofs are composed, among other things, of a list of sibling node values. We note that, since nodes that are roots of empty subtrees have known values (the default value), these values do not need to be provided explicitly; it is sufficient to simply identify which siblings in the Merkle branch are roots of empty subtrees, which can be done with one bit per sibling.

For a Merkle branch of height `h`, an `h`-bit value is appended to the proof. The lowest bit corresponds to the sibling of the leaf node, and each higher bit corresponds to the next parent. A value of `1` indicates that the next value in the list of values provided explicitly in the proof should be used, and a value of `0` indicates that the default value should be used.

A proof into an SMT is structured as:

| name               | type                          | description                                                              |
|--------------------|-------------------------------|--------------------------------------------------------------------------|
| `depth`            | `uint16`                      | Depth of the leaf node. The root node is at depth `0`. Must be `<= 256`. |
| `siblings`         | [`HashDigest`](#hashdigest)`[]` | Sibling hash values, ordered starting from the leaf's neighbor.          |
| `includedSiblings` | `byte[32]`                    | Bitfield of explicitly included sibling hashes.                          |

The `includedSiblings` is ordered by most-significant-byte first, with each byte ordered by most-significant-bit first. The lowest bit corresponds to the leaf node level.

A specification describing a suite of test vectors and outputs of a Sparse Merkle Tree is [here](../tests/sparse-merkle-tree-tests.md).

## ECDSA Public-Key Cryptography

Consensus-critical data is authenticated using [ECDSA](https://www.secg.org/sec1-v2.pdf), with the curve [secp256k1](https://en.bitcoin.it/wiki/Secp256k1). A highly-optimized library is available in [C](https://github.com/bitcoin-core/secp256k1), with wrappers in [Go](https://pkg.go.dev/github.com/ethereum/go-ethereum/crypto/secp256k1) and [Rust](https://docs.rs/crate/secp256k1).

Public keys are encoded in uncompressed form, as the concatenation of the `x` and `y` values. No prefix is needed to distinguish between encoding schemes as this is the only encoding supported.

Deterministic signatures ([RFC-6979](https://www.rfc-editor.org/rfc/rfc6979)) should be used when signing, but this is not enforced at the protocol level as it cannot be.

Signatures are represented as the `r` and `s` (each 32 bytes), and `v` (1-bit) values of the signature. `r` and `s` take on their usual meaning (see: [SEC 1, 4.1.3 Signing Operation](https://www.secg.org/sec1-v2.pdf)), while `v` is used for recovering the public key from a signature more quickly (see: [SEC 1, 4.1.6 Public Key Recovery Operation](https://www.secg.org/sec1-v2.pdf)). Only low-`s` values in signatures are valid (i.e. `s <= secp256k1.n//2`); `s` can be replaced with `-s mod secp256k1.n` during the signing process if it is high. Given this, the first bit of `s` will always be `0`, and can be used to store the 1-bit `v` value.

`v` represents the parity of the `Y` component of the point, `0` for even and `1` for odd. The `X` component of the point is assumed to always be low, since [the possibility of it being high is negligible](https://bitcoin.stackexchange.com/a/38909).

Putting it all together, the encoding for signatures is:

<!-- markdownlint-disable-next-line MD040 -->
```
|    32 bytes   ||           32 bytes           |
[256-bit r value][1-bit v value][255-bit s value]
```

This encoding scheme is derived from [EIP 2098: Compact Signature Representation](https://eips.ethereum.org/EIPS/eip-2098).

## EdDSA Public-Key Cryptography

[Ed25519](https://datatracker.ietf.org/doc/html/rfc8032) is supported for use by applications built on Fuel. Edwards curve operations are performed by the [ed25519-dalek](https://github.com/dalek-cryptography/ed25519-dalek) Rust library.

Public keys are encoded in compressed form as specified by the Ed25519 format [RFC-8032 5.1.5](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5). Point compression is performed by replacing the most significant bit in the final octet of the `y` coordinate with the sign bit from the `x` coordinate:

```rust
let mut pk = y;
pk ^= x.is_negative().unwrap_u8() << 7;
```

Public keys are required to be strong enough to prevent malleability, and are checked for weakness during signature verification.

Signatures are 64 bytes, represented as the concatenation of `R` (32 bytes) and `S` (32 bytes) Where `R` and `S` are defined in [RFC-8032 5.1.6](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.6).

Signatures must conform to strict [verification requirements](https://github.com/dalek-cryptography/ed25519-dalek#validation-criteria) to avoid malleability concerns. While this is not part of the original Ed25519 specification, it has become a growing concern especially in cryptocurrency applications.


---

### File: docs/nightly/fuel-specs/src/protocol/index.md

# Protocol

- [Transaction Validity](./tx-validity.md)
- [Cryptographic Primitives](./cryptographic-primitives.md)
- [Storage Slot Initialization](./storage-initialization.md)
- [Block Header Format](./block-header.md)
- [Relayer/Bridge](./relayer.md)


---

### File: docs/nightly/fuel-specs/src/protocol/relayer.md

# Layer 1 Relayer/Bridge Protocol

The Fuel relayer/bridge protocol is a set of rules that govern the interaction between the Fuel blockchain and the
Layer 1 (L1) blockchain (e.g. Ethereum).  

The Fuel blockchain can emit messages that will be processed by the smart contract on the L1 blockchain. The smart
contract on the L1 can also emit events that will be processed by the Fuel blockchain.
This is used to move any data between the L1 blockchain and the Fuel blockchain.

## Fuel Message Outbox

The message outbox is the set of messages sent to the L1 blockchain from the Fuel blockchain.

## Fuel Event Inbox

The event inbox is the set of events received from the L1 blockchain by the Fuel blockchain.

The block producer will receive a list of events from the L1 by some relayer, and then include the
merkle root of the events in the block header.

There are two types of events that can be received from the L1:

1. Messages
2. Transactions

### Messages

An arbitrary message sent from the L1 to the Fuel blockchain. This can be used to move assets from the L1
to the Fuel blockchain or send other arbitrary information to the Fuel blockchain.

| name        | type    | description                                                         |
|-------------|---------|---------------------------------------------------------------------|
| `sender`    | `bytes[32]` | The identity of the sender of the message on the L1                 |
| `recipient` | `bytes[32]` | The recipient of the message on the Fuel Blockchain                 |
| `nonce`     | `bytes[32]` | Unique identifier of the message assigned by the L1 contract                                 |
| `amount`    | `uint64`  | The amount of the base asset transfer                              |
| `data`      | `byte[]`  | Arbitrary message data                                              |

### Transactions

These are transactions that are submitted on the L1 that must be executed on the Fuel blockchain.
This "Forced Transaction Inclusion" is a security feature that allows participants of the Fuel Blockchain to access
their funds in the (unlikely) event that the Fuel blockchain block production is compromised or malicious, e.g. the
block producer is censoring transactions.

| name                     | type      | description                                                                                                                               |
|--------------------------|-----------|-------------------------------------------------------------------------------------------------------------------------------------------|
| `nonce`                  | `bytes[32]` | Unique identifier of the transaction assigned by the L1                                                                          contract |
| `max_gas`                | `uint64`   | The maximum amount of gas allowed to use on  Fuel Blockchain                                                                              |
| `serialized_transaction` | `byte[]`   | The serialized transaction bytes following canonical serialization                                                                        |

The `serialized_transaction` can be any [transaction variant](../tx-format/transaction.md) except the `Mint` transaction, which
is only ever created by the block producer. `Mint` transactions will be rejected by the Fuel blockchain if they are relayed
from the L1.

### Ordering

It is important that the L1 events are ordered correctly when they are relayed to the Fuel blockchain. The events will
be ordered by the L1 block height and then by the index of the event within the block.

The order is important because a merkle root will be generated each time events from L1 are included in a Fuel block.
This merkle root can later be used to prove that an arbitrary event was included on that block without having to store
every event on the block header explicitly. Just the merkle root will be on the [block header](./block-header.md).
The order of the events affects the value of the merkle root.


---

### File: docs/nightly/fuel-specs/src/protocol/storage-initialization.md

# JSON Format for Contract Storage Initializers

Contracts can request that certain storage slots are initialized to specific values. These initialized slots are represented in JSON format as an array where each element represents a storage slot and has the following properties:

- `"key"`: String, a 32-byte key for a given storage slot;
- `"value"`: String, a 32-byte value that initializes the slot;

For instance, the following is a JSON object that requests that the 3 storage slots with keys `0x11..11`, `0x22..22`, and `0x33..33`, are respectively initialized to the values indicated.

```json
[
  {
    "key": "0x1111111111111111111111111111111111111111111111111111111111111111",
    "value": "0x1010101010101010101010101010101010101010101010101010101010101010"
  }, 
  {
    "key": "0x2222222222222222222222222222222222222222222222222222222222222222",
    "value": "0x2020202020202020202020202020202020202020202020202020202020202020"
  },
  {
    "key": "0x3333333333333333333333333333333333333333333333333333333333333333",
    "value": "0x0303030303030303030303030303030303030303030303030303030303030303"
  },
]
```


---

### File: docs/nightly/fuel-specs/src/protocol/tx-validity.md

# Transaction Validity

- [Transaction Life Cycle](#transaction-life-cycle)
- [Access Lists](#access-lists)
- [VM Precondition Validity Rules](#vm-precondition-validity-rules)
  - [Base Sanity Checks](#base-sanity-checks)
  - [Spending UTXOs and Created Contracts](#spending-utxos-and-created-contracts)
  - [Sufficient Balance](#sufficient-balance)
  - [Valid Signatures](#valid-signatures)
- [Predicate Verification](#predicate-verification)
- [Script Execution](#script-execution)
- [VM Postcondition Validity Rules](#vm-postcondition-validity-rules)
  - [Correct Change](#correct-change)
  - [State Changes](#state-changes)

## Transaction Life Cycle

Once a transaction is seen, it goes through several stages of validation, in this order:

1. [Pre-checks](#vm-precondition-validity-rules)
1. [Predicate verification](#predicate-verification)
1. [Script execution](#script-execution)
1. [Post-checks](#vm-postcondition-validity-rules)

## Access Lists

The validity rules below assume sequential transaction validation for side effects (i.e. state changes). However, by construction, transactions with disjoint write access lists can be validated in parallel, including with overlapping read-only access lists. Transactions with overlapping write access lists must be validated and placed in blocks in topological order.

UTXOs and contracts in the read-only and write-destroy access lists must exist (i.e. have been created previously) in order for a transaction to be valid. In other words, for a unique state element ID, the write-create must precede the write-destroy.

Read-only access list:

Write-destroy access list:

- For each [input `InputType.Coin`](../tx-format/input.md#inputcoin)
  - The [UTXO ID](../identifiers/utxo-id.md) `(txId, outputIndex)`
- For each [input `InputType.Contract`](../tx-format/input.md#inputcontract)
  - The [UTXO ID](../identifiers/utxo-id.md) `(txId, outputIndex)`
- For each [input `InputType.Message`](../tx-format/input.md#inputmessage)
  - The [message ID](../identifiers/utxo-id.md#message-id) `messageID`

Write-create access list:

- For each [output `OutputType.ContractCreated`](../tx-format/output.md#outputcontractcreated)
  - The contract ID `contractID`
- For each output
  - The [created UTXO ID](../identifiers/utxo-id.md)

Note that block proposers use the contract ID `contractID` for inputs and outputs of type [`InputType.Contract`](../tx-format/input.md#inputcontract) and [`OutputType.Contract`](../tx-format/output.md#outputcontract) rather than the pair of `txId` and `outputIndex`.

## VM Precondition Validity Rules

This section defines _VM precondition validity rules_ for transactions: the bare minimum required to accept an unconfirmed transaction into a mempool, and preconditions that the VM assumes to hold prior to execution. Chains of unconfirmed transactions are omitted.

For a transaction `tx`, UTXO set `state`, contract set `contracts`, and message set `messages`, the following checks must pass.

> **Note:** [`InputMessages`](../tx-format/input.md#inputmessage) where `input.dataLength > 0` are not dropped from the `messages` message set until they are included in a transaction of type `TransactionType.Script` with a `ScriptResult` receipt where `result` is equal to `0` indicating a successful script exit.

### Base Sanity Checks

Base sanity checks are defined in the [transaction format](../tx-format/index.md).

### Spending UTXOs and Created Contracts

```py
for input in tx.inputs:
    if input.type == InputType.Contract:
        if not input.contractID in contracts:
                return False
    elif input.type == InputType.Message:
        if not input.nonce in messages:
                return False
    else:
        if not (input.txId, input.outputIndex) in state:
            return False
return True
```

If this check passes, the UTXO ID `(txId, outputIndex)` fields of each contract input is set to the UTXO ID of the respective contract. The `txPointer` of each input is also set to the TX pointer of the UTXO with ID `utxoID`.

### Sufficient Balance

For each asset ID `assetId` in the input and output set:

```py
def gas_to_fee(gas, gasPrice) -> int:
    """
    Converts gas units into a fee amount
    """
    return ceil(gas * gasPrice / GAS_PRICE_FACTOR)


def sum_data_messages(tx, assetId) -> int:
    """
    Returns the total balance available from messages containing data
    """
    total: int = 0
    if assetId == 0:
        for input in tx.inputs:
            if input.type == InputType.Message and input.dataLength > 0:
                total += input.amount
    return total


def sum_inputs(tx, assetId) -> int:
    total: int = 0
    for input in tx.inputs:
        if input.type == InputType.Coin and input.assetId == assetId:
            total += input.amount
        elif input.type == InputType.Message and assetId == 0 and input.dataLength == 0:
            total += input.amount
    return total


def transaction_size_gas_fees(tx) -> int:
    """
    Computes the intrinsic gas cost of a transaction based on size in bytes
    """
    return size(tx) * GAS_PER_BYTE


def minted(tx, assetId) -> int:
    """
    Returns any minted amounts by the transaction
    """
    if tx.type != TransactionType.Mint or assetId != tx.mintAssetId:
        return 0
    return tx.mint_amount


def sum_outputs(tx, assetId) -> int:
    total: int = 0
    for output in tx.outputs:
        if output.type == OutputType.Coin and output.assetId == assetId:
            total += output.amount
    return total


def input_gas_fees(tx) -> int:
    """
    Computes the intrinsic gas cost of verifying input utxos
    """
    total: int = 0
    witnessIndices = set()
    for input in tx.inputs:
        if input.type == InputType.Coin or input.type == InputType.Message:
            # add fees allocated for predicate execution
            if input.predicateLength == 0:
                # notate witness index if input is signed
                witnessIndices.add(input.witnessIndex)
            else:
                # add intrinsic gas cost of predicate merkleization based on number of predicate bytes
                total += contract_code_root_gas_fee(input.predicateLength)
                total += input.predicateGasUsed
                # add intrinsic cost of vm initialization
                total += vm_initialization_gas_fee()
    # add intrinsic cost of verifying witness signatures
    total += len(witnessIndices) * eck1_recover_gas_fee()
    return total


def metadata_gas_fees(tx) -> int:
    """
    Computes the intrinsic gas cost of processing transaction outputs
    
    The `contract_code_root_gas_fee`, `sha256_gas_fee`, and `contract_state_root_gas_fee` 
    are based on the benchmarked gas costs of these operations.
    
    Consensus parameters contain definitions of gas costs for all operations and opcodes in the network.
    """
    total: int = 0
    if tx.type == TransactionType.Create:
        for output in tx.outputs:
            if output.type == OutputType.OutputContractCreated:
                # add intrinsic cost of calculating the code root based on the size of the contract bytecode
                total += contract_code_root_gas_fee(tx.witnesses[tx.bytecodeWitnessIndex].dataLength)
                # add intrinsic cost of calculating the state root based on the number of sotrage slots
                total += contract_state_root_gas_fee(tx.storageSlotCount)
                # add intrinsic cost of calculating the contract id 
                # size = 4 byte seed + 32 byte salt + 32 byte code root + 32 byte state root
                total += sha256_gas_fee(100)
    elif tx.type == TransactionType.Upgrade:
        if tx.upgradePurpose.type == UpgradePurposeType.ConsensusParameters:
            # add intrinsic cost of calculating the consensus parameters hash
            total += sha256_gas_fee(size(tx.witnesses[tx.upgradePurpose.witnessIndex].data))
    elif tx.type == TransactionType.Upload:
        # add intrinsic cost of calculating the root based on the number of bytecode subsections
        total += contract_state_root_gas_fee(tx.subsectionsNumber)
        # add intrinsic cost of hashing the subsection for verification of the connection with Binary Merkle tree root
        total += sha256_gas_fee(size(tx.witnesses[tx.witnessIndex]))
            
    if tx.type != TransactionType.Mint:
        # add intrinsic cost of calculating the transaction id
        total += sha256_gas_fee(size(tx))
    return total


def intrinsic_gas_fees(tx) -> int:
    """
    Computes intrinsic costs for a transaction
    """
    fees: int = 0
    # add the cost of initializing a vm for the script
    if tx.type == TransactionType.Create or tx.type == TransactionType.Script:
        fees += vm_initialization_gas_fee()
        fees += metadata_gas_fees(tx)
        fees += intrinsic_input_gas_fees(tx)
    return fees


def min_gas(tx) -> int:
    """
    Comutes the minimum amount of gas required for a transaction to begin processing.
    """
    gas = transaction_size_gas_fees(tx) + intrinsic_gas_fees(tx)
    if tx.type == TransactionType.Upload
        # charge additionally for storing bytecode on chain
        gas += transaction_size_gas_fees(size(tx.witnesses[tx.witnessIndex]))
        
    return gas


def max_gas(tx) -> int:
    """
    Computes the amount of gas required to process a transaction.
    """
    gas = min_gas(tx)
    gas = gas + (tx.witnessBytesLimit - tx.witnessBytes) * GAS_PER_BYTE
    if tx.type == TransactionType.Script:
       gas += tx.gasLimit
    return gas
    
    
def maxFee(tx, assetId, gasPrice) -> int:
    """
    Computes the maximum potential amount of fees that may need to be charged to process a transaction.
    """
    maxGas = max_gas(tx)
    feeBalance = gas_to_fee(maxGas, gasPrice)
    # Only base asset can be used to pay for gas
    if assetId == 0:
        return feeBalance
    else:
        return 0


def available_balance(tx, assetId) -> int:
    """
    Make the data message balance available to the script
    """
    availableBalance = sum_inputs(tx, assetId) + sum_data_messages(tx, assetId) + minted(tx, assetId)
    return availableBalance


def unavailable_balance(tx, assetId) -> int:
    sentBalance = sum_outputs(tx, assetId)
    # Total fee balance
    feeBalance = tx.policies.max_fee
    # Only base asset can be used to pay for gas
    if assetId == 0:
        return sentBalance + feeBalance
    return sentBalance


# The sum_data_messages total is not included in the unavailable_balance since it is spendable as long as there 
# is enough base asset amount to cover gas costs without using data messages. Messages containing data can't
# cover gas costs since they are retryable.
return available_balance(tx, assetId) >= (unavailable_balance(tx, assetId) + sum_data_messages(tx, assetId))
```

### Valid Signatures

```py
def address_from(pubkey: bytes) -> bytes:
    return sha256(pubkey)[0:32]

for input in tx.inputs:
    if (input.type == InputType.Coin or input.type == InputType.Message) and input.predicateLength == 0:
        # ECDSA signatures must be 64 bytes
        if tx.witnesses[input.witnessIndex].dataLength != 64:
            return False
        # Signature must be from owner
        if address_from(ecrecover_k1(txhash(), tx.witnesses[input.witnessIndex].data)) != input.owner:
            return False
return True
```

Signatures and signature verification are specified [here](./cryptographic-primitives.md#public-key-cryptography).

The transaction hash is computed as defined [here](../identifiers/transaction-id.md).

## Predicate Verification

For each input of type `InputType.Coin` or `InputType.Message`, and `predicateLength > 0`, [verify its predicate](../fuel-vm/index.md#predicate-verification).

## Script Execution

Given transaction `tx`, the following checks must pass:

If `tx.scriptLength == 0`, there is no script and the transaction defines a simple balance transfer, so no further checks are required.

If `tx.scriptLength > 0`, the script must be executed. For each asset ID `assetId` in the input set, the free balance available to be moved around by the script and called contracts is `freeBalance[assetId]`. The initial message balance available to be moved around by the script and called contracts is `messageBalance`:

```py
freeBalance[assetId] = available_balance(tx, assetId) - unavailable_balance(tx, assetId)
messageBalance = sum_data_messages(tx, 0)
```

Once the free balances are computed, the [script is executed](../fuel-vm/index.md#script-execution). After execution, the following is extracted:

1. The transaction in-memory on VM termination is used as the final transaction which is included in the block.
1. The unspent free balance `unspentBalance` for each asset ID.
1. The unspent gas `unspentGas` from the `$ggas` register.

`size(tx)` encompasses the entire transaction serialized according to the transaction format, including witness data.
This ensures every byte of block space either on Fuel or corresponding DA layer can be accounted for.

If the transaction as included in a block does not match this final transaction, the block is invalid.

### Fees

The cost of a transaction can be described by:

```py
def cost(tx, gasPrice) -> int:
    return gas_to_fee(min_gas(tx) + tx.gasLimit - unspentGas, gasPrice)
```

where:

- `min_gas(tx)` is the minimum cost of the transaction in gas, including intrinsic gas fees incurred from:
  - The number of bytes comprising the transaction
  - Processing inputs, including predicates
  - Processing outputs
  - VM initialization
- `unspentGas` is the amount gas left over after intrinsic fees and execution of the transaction, extracted from the `$ggas` register. Converting unspent gas to a fee describes how much "change" is left over from the user's payment; the block producer collects this unspent gas as reward.
- `gas_to_fee` is a function that converts gas to a concrete fee based on a given gas price.

Fees incurred by transaction processing outside the context of execution are collectively referred to as intrinsic fees. Intrinsic fees include the cost of storing the transaction, calculated on a per-byte basis, the cost of processing inputs and outputs, including predicates and signature verification, and initialization of the VM prior to any predicate or script execution. Because intrinsic fees are independent of execution, they can be determined _a priori_ and represent the bare minimum cost of the transaction.

A naturally occurring result of a variable gas limit is the concept of minimum and maximum fees. The minimum fee is, thus, the exact fee required to pay the fee balance, while the maximum fee is the minimum fee plus the gas limit:

```py
min_gas = min_gas(tx)
max_gas = min_gas + (tx.witnessBytesLimit - tx.witnessBytes) * GAS_PER_BYTE + tx.gasLimit
min_fee = gas_to_fee(min_gas, gasPrice)
max_fee = gas_to_fee(max_gas, gasPrice)
```

The cost of the transaction `cost(tx)` must lie within the range defined by [`min_fee`, `max_fee`]. `min_gas` is defined as the sum of all intrinsic costs of the transaction known prior to execution. The definition of `max_gas` illustrates that the delta between minimum gas and maximum gas is the sum of:

- The remaining allocation of witness bytes, converted to gas
- The user-defined `tx.gasLimit`

Note that `gasLimit` applies to transactions of type `Script`. `gasLimit` is not applicable for transactions of type `Create` and is defined to equal `0` in the above formula.

A transaction cost `cost(tx)`, in gas, greater than `max_gas` is invalid and must be rejected; this signifies that the user must provide a higher gas limit for the given transaction. `min_fee` is the minimum reward the producer is guaranteed to collect, and `max_fee` is the maximum reward the producer is potentially eligible to collect. In practice, the user is always charged intrinsic fees; thus, `unspentGas` is the remainder of `max_gas` after intrinsic fees and the variable cost of execution. Calculating a conversion from `unspentGas` to an unspent fee describes the reward the producer will collect in addition to `min_fee`.

## VM Postcondition Validity Rules

This section defines _VM postcondition validity rules_ for transactions: the requirements for a transaction to be valid after it has been executed.

Given transaction `tx`, state `state`, and contract set `contracts`, the following checks must pass.

### Correct Change

If change outputs are present, they must have:

- if the transaction does not revert;
  - if the asset ID is `0`; an `amount` of `unspentBalance + floor((unspentGas * gasPrice) / GAS_PRICE_FACTOR)`
  - otherwise; an `amount` of the unspent free balance for that asset ID after VM execution is complete
- if the transaction reverts;
  - if the asset ID is `0`; an `amount` of the initial free balance plus `(unspentGas * gasPrice) - messageBalance`
  - otherwise; an `amount` of the initial free balance for that asset ID.

### State Changes

Transaction processing is completed by removing spent UTXOs from the state and adding created UTXOs to the state.

### Coinbase Transaction

The coinbase transaction is a mechanism for block creators to collect transaction fees.

In order for a coinbase transaction to be valid:

1. It must be a [Mint](../tx-format/transaction.md#TransactionMint) transaction.
1. The coinbase transaction must be the last transaction within a block, even if there are no other transactions in the block and the fee is zero.
1. The `mintAmount` doesn't exceed the total amount of fees processed from all other transactions within the same block.
1. The `mintAssetId` matches the `assetId` that fees are paid in (`assetId == 0`).

The minted amount of the coinbase transaction intrinsically increases the balance corresponding to the `inputContract`.
This means the balance of `mintAssetId` is directly increased by `mintAmount` on the input contract,
without requiring any VM execution. Compared to coin outputs, intrinsically increasing a contract balance to collect
coinbase amounts prevents the accumulation of dust during low-usage periods.


---

### File: docs/nightly/fuel-specs/src/tests/index.md

# Testing

Test suites for verifying the correctness of a Fuel implementation.

- [Sparse Merkle Tree Tests](./sparse-merkle-tree-tests.md)


---

### File: docs/nightly/fuel-specs/src/tests/sparse-merkle-tree-tests.md

# Sparse Merkle Tree Test Specifications

## Version

0.1.1

Last updated 2022/07/11

## Abstract

This document outlines a test suite specification that can be used to verify the correctness of a Sparse Merkle Tree's outputs. The scope of this document covers only Sparse Merkle Tree (SMT) implementations that are compliant with [Celestia Sparse Merkle Tree Specification](https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/data_structures.md#sparse-merkle-tree). The goal of this document is to equip SMT library developers with a supplemental indicator of correctness. Libraries implementing an SMT can additionally implement this test suite specification in the code base's native language. Passing all tests in the concrete test suite is an indication of correctness and consistency with the reference specification; however, it is not an absolute guarantee.

The tests described in this document are designed to test features common to most Sparse Merkle Tree implementations. Test specifications are agnostic of the implementation details or language, and therefore take a black-box testing approach. A test specification may provide an example of what a compliant test may look like in the form of pseudocode.

A test specification follows the format:

- Test name
- Test description
- Test inputs
- Test outputs
- Example pseudocode

For a concrete test to comply with its corresponding test specification, the System Under Test (SUT) must take in the prescribed inputs. When the SUT produces the prescribed outputs, the test passes. When the SUT produces any result or error that is not prescribed by the specification, the test fails. For a library to comply with the complete specification described herein, it must implement all test specifications, and each test must pass.

All test specifications assume that the Merkle Tree implementation under test uses the SHA-2-256 hashing algorithm as defined in [FIPS PUB 180-4](https://doi.org/10.6028/NIST.FIPS.180-4) to produce its outputs. The following test cases stipulate a theoretical function `Sum(N)` that takes in a big endian data slice `N` and returns the 32 byte SHA-256 hash of `N`.

## Root Signature Tests

1. [Test Empty Root](#test-empty-root)
2. [Test Update 1](#test-update-1)
3. [Test Update 2](#test-update-2)
4. [Test Update 3](#test-update-3)
5. [Test Update 5](#test-update-5)
6. [Test Update 10](#test-update-10)
7. [Test Update 100](#test-update-100)
8. [Test Update With Repeated Inputs](#test-update-with-repeated-inputs)
9. [Test Update Overwrite Key](#test-update-overwrite-key)
10. [Test Update Union](#test-update-union)
11. [Test Update Sparse Union](#test-update-sparse-union)
12. [Test Update With Empty Data](#test-update-with-empty-data)
13. [Test Update With Empty Data Performs Delete](#test-update-with-empty-data-performs-delete)
14. [Test Update 1 Delete 1](#test-update-1-delete-1)
15. [Test Update 2 Delete 1](#test-update-2-delete-1)
16. [Test Update 10 Delete 5](#test-update-10-delete-5)
17. [Test Delete Non-existent Key](#test-delete-non-existent-key)
18. [Test Interleaved Update Delete](#test-interleaved-update-delete)
19. [Test Delete Sparse Union](#test-delete-sparse-union)

---

### Test Empty Root

**Description**:

Tests the default root given no update or delete operations. The input set is described by `S = {Ø}`.

**Inputs**:

_No inputs_.

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 1

**Description**:

Tests the root after performing a single update call with the specified input.

**Inputs**:

1. Update the empty tree with `(K, D)` where leaf key `K = Sum(0u32)` (32 bytes) and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
root = smt.root()
expected_root = '39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 2

**Description**:

Tests the root after performing two update calls with the specified inputs.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x8d0ae412ca9ca0afcb3217af8bcd5a673e798bd6fd1dfacad17711e883f494cb`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x01"), b"DATA")
root = smt.root()
expected_root = '8d0ae412ca9ca0afcb3217af8bcd5a673e798bd6fd1dfacad17711e883f494cb'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 3

**Description**:

Tests the root after performing three update calls with the specified inputs.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. Update the tree with `(K, D)`, where leaf key `K = Sum(2u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x52295e42d8de2505fdc0cc825ff9fead419cbcf540d8b30c7c4b9c9b94c268b7`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x01"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x02"), b"DATA")
root = smt.root()
expected_root = '52295e42d8de2505fdc0cc825ff9fead419cbcf540d8b30c7c4b9c9b94c268b7'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 5

**Description**:

Tests the root after performing five update calls with the specified inputs.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. Update the tree with `(K, D)`, where leaf key `K = Sum(2u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
4. Update the tree with `(K, D)`, where leaf key `K = Sum(3u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
5. Update the tree with `(K, D)`, where leaf key `K = Sum(4u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 10

**Description**:

Tests the root after performing 10 update calls with the specified inputs.

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x21ca4917e99da99a61de93deaf88c400d4c082991cb95779e444d43dd13e8849`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '21ca4917e99da99a61de93deaf88c400d4c082991cb95779e444d43dd13e8849'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 100

**Description**:

Tests the root after performing 100 update calls with the specified inputs.

**Inputs**:

1. For each `i` in `0..100`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x82bf747d455a55e2f7044a03536fc43f1f55d43b855e72c0110c986707a23e4d`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..100 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '82bf747d455a55e2f7044a03536fc43f1f55d43b855e72c0110c986707a23e4d'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update With Repeated Inputs

**Description**:

Tests the root after performing two update calls with the same inputs. The resulting input set is described by `S = {A} U {A} = {A}`, where `{A}` is the input. This test expects a root signature identical to that produced by [Test Update 1](#test-update-1).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree again with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
root = smt.root()
expected_root = '39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update Overwrite Key

**Description**:

Tests the root after performing two update calls with the same leaf keys but different leaf data. The second update call is expected to overwrite the data originally written by the first update call.

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"CHANGE"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0xdd97174c80e5e5aa3a31c61b05e279c1495c8a07b2a08bca5dbc9fb9774f9457`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x00"), b"CHANGE")
root = smt.root()
expected_root = 'dd97174c80e5e5aa3a31c61b05e279c1495c8a07b2a08bca5dbc9fb9774f9457'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update Union

**Description**:

Tests the root after performing update calls with discontinuous sets of inputs. The resulting input set is described by `S = [0..5) U [10..15) U [20..25)`.

**Inputs**:

1. For each `i` in `0..5`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `10..15`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. For each `i` in `20..25`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0x7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 10..15 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 20..25 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = '7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update Sparse Union

**Description**:

Tests the root after performing update calls with discontinuous sets of inputs. The resulting input set is described by `S = [0, 2, 4, 6, 8]`.

**Inputs**:

1. For each `i` in `0..5`, update the tree with `(K, D)`, where leaf key `K = Sum(i * 2)` and leaf data `D = b"DATA"` (bytes, UTF-8)

**Outputs**:

- The expected root signature: `0xe912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32 * 2).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
root = smt.root()
expected_root = 'e912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update With Empty Data

**Description**:

Tests the root after performing one update call with empty data. Updating the empty tree with empty data does not change the root, and the expected root remains the default root. The resulting input set is described by `S = {Ø} U {Ø} = {Ø}`. This test expects a root signature identical to that produced by [Test Empty Root](#test-empty-root).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and empty leaf data `D = b""` (0 bytes)

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"")
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update With Empty Data Performs Delete

**Description**:

Tests the root after performing one update call with arbitrary data followed by a second update call on the same key with empty data. Updating a key with empty data is equivalent to calling delete. By deleting the only key, we have an empty tree and expect to arrive at the default root. The resulting input set is described by `S = {0} - {0} = {Ø}`. This test expects a root signature identical to that produced by [Test Empty Root](#test-empty-root).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(0u32)` and empty leaf data `D = b""` (0 bytes)

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x00"), b"")
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 1 Delete 1

**Description**:

Tests the root after performing one update call followed by a subsequent delete call on the same key. By deleting the only key, we have an empty tree and expect to arrive at the default root. The resulting input set is described by `S = {0} - {0} = {Ø}`. This test expects a root signature identical to that produced by [Test Empty Root](#test-empty-root).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Delete `(K)` from the tree, where leaf key `K = Sum(0u32)`  

**Outputs**:

- The expected root signature: `0x0000000000000000000000000000000000000000000000000000000000000000`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.delete(&sum(b"\x00\x00\x00\x00"))
root = smt.root()
expected_root = '0000000000000000000000000000000000000000000000000000000000000000'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 2 Delete 1

**Description**:

Tests the root after performing two update calls followed by a subsequent delete call on the first key. By deleting the second key, we have a tree with only one key remaining, equivalent to a single update. This test expects a root signature identical to that produced by [Test Update 1](#test-update-1).

**Inputs**:

1. Update the empty tree with `(K, D)`, where leaf key `K = Sum(0u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Update the tree with `(K, D)`, where leaf key `K = Sum(1u32)` and leaf data `D = b"DATA"` (bytes, UTF-8)
3. Delete `(K)` from the tree, where leaf key `K = Sum(1u32)`

**Outputs**:

- The expected root signature: `0x39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
smt.update(&sum(b"\x00\x00\x00\x00"), b"DATA")
smt.update(&sum(b"\x00\x00\x00\x01"), b"DATA")
smt.delete(&sum(b"\x00\x00\x00\x01"))
root = smt.root()
expected_root = '39f36a7cb4dfb1b46f03d044265df6a491dffc1034121bc1071a34ddce9bb14b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Update 10 Delete 5

**Description**:

Tests the root after performing 10 update calls followed by 5 subsequent delete calls on the latter keys. By deleting the last five keys, we have a tree with the first five keys remaining, equivalent to five updates. This test expects a root signature identical to that produced by [Test Update 5](#test-update-5).

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `5..10`, delete `(K)` from the tree, where leaf key `K = Sum(i)`

**Outputs**:

- The expected root signature: `0x108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 5..10 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
root = smt.root()
expected_root = '108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Delete Non-existent Key

**Description**:

Tests the root after performing five update calls followed by a subsequent delete on a key that is not present in the input set. This test expects a root signature identical to that produced by [Test Update 5](#test-update-5).

**Inputs**:

1. For each `i` in `0..5`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. Delete `(K)` from the tree, where leaf key `K = Sum(1024u32)`

**Outputs**:

- The expected root signature: `0x108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..5 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
smt.delete(&sum(b"\x00\x00\x04\x00"))

root = smt.root()
expected_root = '108f731f2414e33ae57e584dc26bd276db07874436b2264ca6e520c658185c6b'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Interleaved Update Delete

**Description**:

Tests the root after performing a series of interleaved update and delete calls. The resulting input set is described by `[0..5) U [10..15) U [20..25)`. This test demonstrates the inverse relationship between operations `update` and `delete`. This test expects a root signature identical to that produced by [Test Update Union](#test-update-union).

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `5..15`, delete `(K)` from the tree, where leaf key `K = Sum(i)` from the tree
3. For each `i` in `10..20`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
4. For each `i` in `15..25`, delete `(K)` from the tree, where leaf key `K = Sum(i)` from the tree
5. For each `i` in `20..30`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
6. For each `i` in `25..35`, delete `(K)` from the tree, where leaf key `K = Sum(i)` from the tree

**Outputs**:

- The expected root signature: `0x7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 5..15 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
for i in 10..20 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 15..25 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
for i in 20..30 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 25..35 {
    key = &(i as u32).to_big_endian_bytes()
    smt.delete(&sum(key))
}
root = smt.root()
expected_root = '7e6643325042cfe0fc76626c043b97062af51c7e9fc56665f12b479034bce326'
expect(hex_encode(root), expected_root).to_be_equal
```

---

### Test Delete Sparse Union

**Description**:

Tests the root after performing delete calls with discontinuous sets of inputs. The resulting input set is described by `S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - [1, 3, 5, 7, 9] = [0, 2, 4, 6, 8]`. This test expects a root signature identical to that produced by [Test Update Sparse Union](#test-update-sparse-union).

**Inputs**:

1. For each `i` in `0..10`, update the tree with `(K, D)`, where leaf key `K = Sum(i)` and leaf data `D = b"DATA"` (bytes, UTF-8)
2. For each `i` in `0..5`, delete `(K)` from the tree, where leaf key `K = Sum(i * 2 + 1)`

**Outputs**:

- The expected root signature: `0xe912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696`

**Example Pseudocode**:

```text
smt = SparseMerkleTree.new(Storage.new(), sha256.new())
for i in 0..10 {
    key = &(i as u32).to_big_endian_bytes()
    data = b"DATA"
    smt.update(&sum(key), data)
}
for i in 0..5 {
    key = &(i as u32 * 2 + 1).to_big_endian_bytes()
    smt.delete(&sum(key))
}
root = smt.root()
expected_root = 'e912e97abc67707b2e6027338292943b53d01a7fbd7b244674128c7e468dd696'
expect(hex_encode(root), expected_root).to_be_equal
```


---

### File: docs/nightly/fuel-specs/src/tx-format/consensus_parameters.md

# Consensus Parameters

| name                        | type      | description                                                    |
|-----------------------------|-----------|----------------------------------------------------------------|
| `GAS_PER_BYTE`              | `uint64`  | Gas charged per byte of the transaction.                       |
| `GAS_PRICE_FACTOR`          | `uint64`  | Unit factor for gas price.                                     |
| `MAX_GAS_PER_TX`            | `uint64`  | Maximum gas per transaction.                                   |
| `MAX_INPUTS`                | `uint64`  | Maximum number of inputs.                                      |
| `MAX_OUTPUTS`               | `uint64`  | Maximum number of outputs.                                     |
| `MAX_PREDICATE_LENGTH`      | `uint64`  | Maximum length of predicate, in instructions.                  |
| `MAX_GAS_PER_PREDICATE`     | `uint64`  | Maximum gas per predicate.                                     |
| `MAX_PREDICATE_DATA_LENGTH` | `uint64`  | Maximum length of predicate data, in bytes.                    |
| `MAX_SCRIPT_LENGTH`         | `uint64`  | Maximum length of script, in instructions.                     |
| `MAX_SCRIPT_DATA_LENGTH`    | `uint64`  | Maximum length of script data, in bytes.                       |
| `MAX_MESSAGE_DATA_LENGTH`   | `uint64`  | Maximum length of message data, in bytes.                      |
| `MAX_STORAGE_SLOTS`         | `uint64`  | Maximum number of initial storage slots.                       |
| `MAX_TRANSACTION_SIZE`      | `uint64`  | Maximum size of a transaction, in bytes.                       |
| `MAX_WITNESSES`             | `uint64`  | Maximum number of witnesses.                                   |
| `MAX_BYTECODE_SUBSECTIONS`  | `uint64`  | Maximum number of bytecode subsections.                        |
| `CHAIN_ID`                  | `uint64`  | A unique per-chain identifier.                                 |
| `BASE_ASSET_ID`             | `bytes32` | The base asset of the chain.                                   |
| `PRIVILEGED_ADDRESS`        | `bytes32` | The privileged address of the network who can perform upgrade. |


---

### File: docs/nightly/fuel-specs/src/tx-format/index.md

# Transaction Format

The Fuel Transaction Format.

- [Consensus Parameters](./consensus_parameters.md)
- [Transaction](./transaction.md)
  - [`TransactionScript`](./transaction.md#transactionscript)
  - [`TransactionCreate`](./transaction.md#transactioncreate)
  - [`TransactionMint`](./transaction.md#transactionmint)
  - [`TransactionUpgrade`](./transaction.md#transactionupgrade)
  - [`TransactionUpload`](./transaction.md#transactionupload)
  - [`TransactionBlob`](./transaction.md#transactionblob)
- [Input](./input.md)
  - [`InputCoin`](./input.md#inputcoin)
  - [`InputContract`](./input.md#inputcontract)
  - [`InputMessage`](./input.md#inputmessage)
- [Output](./output.md)
  - [`OutputCoin`](./output.md#outputcoin)
  - [`OutputContract`](./output.md#outputcontract)
  - [`OutputChange`](./output.md#outputchange)
  - [`OutputVariable`](./output.md#outputvariable)
  - [`OutputContractCreated`](./output.md#outputcontractcreated)
- [`Witness`](./witness.md)
- [`Policy`](./policy.md)
- [`TXPointer`](./tx-pointer.md)


---

### File: docs/nightly/fuel-specs/src/tx-format/input.md

# Input

```c++
enum InputType : uint8 {
    Coin = 0,
    Contract = 1,
    Message = 2,
}
```

| name   | type                                                                                              | description    |
|--------|---------------------------------------------------------------------------------------------------|----------------|
| `type` | [`InputType`](#input)                                                                               | Type of input. |
| `data` | One of [`InputCoin`](#inputcoin), [`InputContract`](#inputcontract), or [`InputMessage`](#inputmessage) | Input data.    |

Transaction is invalid if:

- `type > InputType.Message`

## `InputCoin`

| name                  | type                         | description                                                            |
|-----------------------|------------------------------|------------------------------------------------------------------------|
| `txID`                | `byte[32]`                   | Hash of transaction.                                                   |
| `outputIndex`         | `uint16`                      | Index of transaction output.                                           |
| `owner`               | `byte[32]`                   | Owning address or predicate root.                                      |
| `amount`              | `uint64`                     | Amount of coins.                                                       |
| `asset_id`            | `byte[32]`                   | Asset ID of the coins.                                                 |
| `txPointer`           | [`TXPointer`](./tx-pointer.md) | Points to the TX whose output is being spent.                          |
| `witnessIndex`        | `uint16`                     | Index of witness that authorizes spending the coin.                    |
| `predicateGasUsed`    | `uint64`                     | Gas used by predicate.                                                 |
| `predicateLength`     | `uint64`                     | Length of predicate, in instructions.                                  |
| `predicateDataLength` | `uint64`                     | Length of predicate input data, in bytes.                              |
| `predicate`           | `byte[]`                     | Predicate bytecode.                                                    |
| `predicateData`       | `byte[]`                     | Predicate input data (parameters).                                     |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- `witnessIndex >= tx.witnessesCount`
- `predicateLength > MAX_PREDICATE_LENGTH`
- `predicateDataLength > MAX_PREDICATE_DATA_LENGTH`
- If `predicateLength > 0`; the computed predicate root (see below) is not equal `owner`
- `predicateLength * 4 != len(predicate)`
- `predicateDataLength != len(predicateData)`
- `predicateGasUsed > MAX_GAS_PER_PREDICATE`

> **Note:** when signing a transaction, `txPointer` and `predicateGasUsed` are set to zero.
>
> **Note:** when verifying and estimating a predicate or executing a script, `txPointer` and `predicateGasUsed` are initialized to zero.

The predicate root is computed [here](../identifiers/predicate-id.md).

## `InputContract`

| name          | type                         | description                                                             |
|---------------|------------------------------|-------------------------------------------------------------------------|
| `txID`        | `byte[32]`                   | Hash of transaction.                                                    |
| `outputIndex` | `uint16`                      | Index of transaction output.                                            |
| `balanceRoot` | `byte[32]`                   | Root of amount of coins owned by contract before transaction execution. |
| `stateRoot`   | `byte[32]`                   | State root of contract before transaction execution.                    |
| `txPointer`   | [`TXPointer`](./tx-pointer.md) | Points to the TX whose output is being spent.                           |
| `contractID`  | `byte[32]`                   | Contract ID.                                                            |

Transaction is invalid if:

- there is not exactly one output of type `OutputType.Contract` with `inputIndex` equal to this input's index

> **Note:** when signing a transaction, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are set to zero.
>
> **Note:** when verifying a predicate or executing a script, `txID`, `outputIndex`, `balanceRoot`, `stateRoot`, and `txPointer` are initialized to zero.

## `InputMessage`

| name                  | type       | description                                             |
|-----------------------|------------|---------------------------------------------------------|
| `sender`              | `byte[32]` | The address of the message sender.                      |
| `recipient`           | `byte[32]` | The address or predicate root of the message recipient. |
| `amount`              | `uint64`   | Amount of base asset coins sent with message.           |
| `nonce`               | `byte[32]` | The message nonce.                                      |
| `witnessIndex`        | `uint16`   | Index of witness that authorizes spending the coin.     |
| `predicateGasUsed`    | `uint64`   | Gas used by predicate execution.                        |
| `dataLength`          | `uint64`   | Length of message data, in bytes.                       |
| `predicateLength`     | `uint64`   | Length of predicate, in instructions.                   |
| `predicateDataLength` | `uint64`   | Length of predicate input data, in bytes.               |
| `data`                | `byte[]`   | The message data.                                       |
| `predicate`           | `byte[]`   | Predicate bytecode.                                     |
| `predicateData`       | `byte[]`   | Predicate input data (parameters).                      |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- `witnessIndex >= tx.witnessesCount`
- `dataLength > MAX_MESSAGE_DATA_LENGTH`
- `predicateLength > MAX_PREDICATE_LENGTH`
- `predicateDataLength > MAX_PREDICATE_DATA_LENGTH`
- If `predicateLength > 0`; the computed predicate root (see below) is not equal `recipient`
- `dataLength != len(data)`
- `predicateLength * 4 != len(predicate)`
- `predicateDataLength != len(predicateData)`
- `predicateGasUsed > MAX_GAS_PER_PREDICATE`

The predicate root is computed [here](../identifiers/predicate-id.md).

> **Note:** `InputMessages` with data length greater than zero are not considered spent until they are included in a transaction of type `TransactionType.Script` with a `ScriptResult` receipt where `result` is equal to `0` indicating a successful script exit
>
> **Note:** when signing a transaction, `predicateGasUsed` is set to zero.
>
> **Note:** when verifying and estimating a predicate, `predicateGasUsed` is initialized to zero.


---

### File: docs/nightly/fuel-specs/src/tx-format/output.md

# Output

```c++
enum OutputType : uint8 {
    Coin = 0,
    Contract = 1,
    Change = 2,
    Variable = 3,
    ContractCreated = 4,
}
```

| name   | type                                                                                                                                                                                       | description     |
|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------|
| `type` | [`OutputType`](#output)                                                                                                                                                                      | Type of output. |
| `data` | One of [`OutputCoin`](#outputcoin), [`OutputContract`](#outputcontract), [`OutputChange`](#outputchange), [`OutputVariable`](#outputvariable), or [`OutputContractCreated`](#outputcontractcreated). | Output data.    |

Transaction is invalid if:

- `type > OutputType.ContractCreated`

## `OutputCoin`

| name       | type       | description                          |
|------------|------------|--------------------------------------|
| `to`       | `byte[32]` | Receiving address or predicate root. |
| `amount`   | `uint64`   | Amount of coins to send.             |
| `asset_id` | `byte[32]` | Asset ID of coins.                   |

## `OutputContract`

| name          | type       | description                                                            |
|---------------|------------|------------------------------------------------------------------------|
| `inputIndex`  | `uint16`    | Index of input contract.                                               |
| `balanceRoot` | `byte[32]` | Root of amount of coins owned by contract after transaction execution. |
| `stateRoot`   | `byte[32]` | State root of contract after transaction execution.                    |

Transaction is invalid if:

- `inputIndex >= tx.inputsCount`
- `tx.inputs[inputIndex].type != InputType.Contract`

> **Note:** when signing a transaction, `balanceRoot` and `stateRoot` are set to zero.
>
> **Note:** when verifying a predicate or executing a script, `balanceRoot` and `stateRoot` are initialized to zero.

The balance root `balanceRoot` is the root of the [SMT](../protocol/cryptographic-primitives.md#sparse-merkle-tree) of balance leaves. Each balance is a `uint64`, keyed by asset ID (a `byte[32]`).

The state root `stateRoot` is the root of the [SMT](../protocol/cryptographic-primitives.md#sparse-merkle-tree) of storage slots. Each storage slot is a `byte[32]`, keyed by a `byte[32]`.

## `OutputChange`

| name       | type       | description                          |
|------------|------------|--------------------------------------|
| `to`       | `byte[32]` | Receiving address or predicate root. |
| `amount`   | `uint64`   | Amount of coins to send.             |
| `asset_id` | `byte[32]` | Asset ID of coins.                   |

Transaction is invalid if:

- any other output has type `OutputType.OutputChange` and asset ID `asset_id` (i.e. only one change output per asset ID is allowed)

> **Note:** when signing a transaction, `amount` is set to zero.
>
> **Note:** when verifying a predicate or executing a script, `amount` is initialized to zero.

This output type indicates that the output's amount may vary based on transaction execution, but is otherwise identical to a [Coin](#outputcoin) output. An `amount` of zero after transaction execution indicates that the output is unspendable and can be pruned from the UTXO set.

## `OutputVariable`

| name       | type       | description                          |
|------------|------------|--------------------------------------|
| `to`       | `byte[32]` | Receiving address or predicate root. |
| `amount`   | `uint64`   | Amount of coins to send.             |
| `asset_id` | `byte[32]` | Asset ID of coins.                   |

> **Note:** when signing a transaction, `to`, `amount`, and `asset_id` are set to zero.
>
> **Note:** when verifying a predicate or executing a script, `to`, `amount`, and `asset_id` are initialized to zero.

This output type indicates that the output's amount and owner may vary based on transaction execution, but is otherwise identical to a [Coin](#outputcoin) output. An `amount` of zero after transaction execution indicates that the output is unspendable and can be pruned from the UTXO set.

## `OutputContractCreated`

| name         | type       | description                     |
|--------------|------------|---------------------------------|
| `contractID` | `byte[32]` | Contract ID.                    |
| `stateRoot`  | `byte[32]` | Initial state root of contract. |


---

### File: docs/nightly/fuel-specs/src/tx-format/policy.md

# Policy

```c++
// index using powers of 2 for efficient bitmasking
enum PolicyType : uint32 {
    Tip = 1,
    WitnessLimit = 2,
    Maturity = 4,
    MaxFee = 8,
    Expiration = 16,
}
```

| name   | type                                                                              | description  |
|--------|-----------------------------------------------------------------------------------|--------------|
| `data` | One of [`Tip`](#tip), [`WitnessLimit`](#witnesslimit), [`Maturity`](#maturity) or [`Expiration`](#expiration) | Policy data. |

## `Tip`

| name       | type     | description                                                                                   |
|------------|----------|-----------------------------------------------------------------------------------------------|
| `tip` | `uint64` | Additional, optional fee in `BASE_ASSET` to incentivize block producer to include transaction |

## `WitnessLimit`

| name           | type     | description                                                    |
|----------------|----------|----------------------------------------------------------------|
| `witnessLimit` | `uint64` | The maximum amount of witness data allowed for the transaction |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- `len(tx.witnesses) > witnessLimit`

## `Maturity`

| name       | type     | description                              |
|------------|----------|------------------------------------------|
| `maturity` | `uint32` | Block until which the transaction cannot be included. |

Transaction is invalid if:

- `blockheight() < maturity`

## `Expiration`

| name         | type     | description                              |
|--------------|----------|------------------------------------------|
| `expiration` | `uint32` | Block after which the transaction cannot be included. |

Transaction is invalid if:

- `blockheight() > expiration`

## `MaxFee`

| name      | type     | description                                                                                                                                                           |
|-----------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `max_fee` | `uint64` | Required policy to specify the maximum fee payable by this transaction using `BASE_ASSET`. This is used to check transactions before the actual `gas_price` is known. |

Transaction is invalid if:

- `max_fee > sum_inputs(tx, BASE_ASSET_ID) - sum_outputs(tx, BASE_ASSET_ID)`
- `max_fee < max_fee(tx, BASE_ASSET_ID, gas_price)`


---

### File: docs/nightly/fuel-specs/src/tx-format/transaction.md

# Transaction

```c++
enum TransactionType : uint8 {
    Script = 0,
    Create = 1,
    Mint = 2,
    Upgrade = 3,
    Upload = 4,
    Blob = 5,
}
```

| name   | type                                                                                                                                                                                                                          | description       |
|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
| `type` | [`TransactionType`](#transaction)                                                                                                                                                                                             | Transaction type. |
| `data` | One of [`TransactionScript`](#transactionscript), [`TransactionCreate`](#transactioncreate), [`TransactionMint`](#transactionmint), [`TransactionUpgrade`](#transactionupgrade), or [`TransactionUpload`](#transactionupload) | Transaction data. |

Given helper `max_gas()` returns the maximum gas that the transaction can use.
Given helper `count_ones()` that returns the number of ones in the binary representation of a field.
Given helper `count_variants()` that returns the number of variants in an enum.
Given helper `sum_variants()` that sums all variants of an enum.

Transaction is invalid if:

- `type` is not valid `TransactionType` value
- `inputsCount > MAX_INPUTS`
- `outputsCount > MAX_OUTPUTS`
- `witnessesCount > MAX_WITNESSES`
- `size > MAX_TRANSACTION_SIZE`. The size of a transaction is calculated as the sum of the sizes of its static and dynamic parts, as determined by canonical serialization.
- No inputs are of type `InputType.Coin` or `InputType.Message` with `input.dataLength` == 0
- More than one output is of type `OutputType.Change` for any asset ID in the input set
- More than one output is of type `OutputType.Change` with identical `asset_id` fields.
- Any output is of type `OutputType.Change` for any asset ID not in the input set
- More than one input of type `InputType.Coin` for any [Coin ID](../identifiers/utxo-id.md#coin-id) in the input set
- More than one input of type `InputType.Contract` for any [Contract ID](../identifiers/utxo-id.md#contract-id) in the input set
- More than one input of type `InputType.Message` for any [Message ID](../identifiers/utxo-id.md#message-id) in the input set
- if `type != TransactionType.Mint`
  - `max_gas(tx) > MAX_GAS_PER_TX`
  - No policy of type `PolicyType.MaxFee` is set
  - `count_ones(policyTypes) > count_variants(PolicyType)`
  - `policyTypes > sum_variants(PolicyType)`
  - `len(policies) > count_ones(policyTypes)`

When serializing a transaction, fields are serialized as follows (with inner structs serialized recursively):

1. `uint8`, `uint16`, `uint32`, `uint64`: big-endian right-aligned to 8 bytes.
1. `byte[32]`: as-is.
1. `byte[]`: as-is, with padding zeroes aligned to 8 bytes.

When deserializing a transaction, the reverse is done. If there are insufficient bytes or too many bytes, the transaction is invalid.

## `TransactionScript`

```c++
enum ReceiptType : uint8 {
    Call = 0,
    Return = 1,
    ReturnData = 2,
    Panic = 3,
    Revert = 4,
    Log = 5,
    LogData = 6,
    Transfer = 7,
    TransferOut = 8,
    ScriptResult = 9,
    MessageOut = 10,
    Mint = 11,
    Burn = 12,
}
```

| name               | type                        | description                             |
|--------------------|-----------------------------|-----------------------------------------|
| `scriptGasLimit`   | `uint64`                    | Gas limits the script execution.        |
| `receiptsRoot`     | `byte[32]`                  | Merkle root of receipts.                |
| `scriptLength`     | `uint64`                    | Script length, in instructions.         |
| `scriptDataLength` | `uint64`                    | Length of script input data, in bytes.  |
| `policyTypes`      | `uint32`                    | Bitfield of used policy types.          |
| `inputsCount`      | `uint16`                    | Number of inputs.                       |
| `outputsCount`     | `uint16`                    | Number of outputs.                      |
| `witnessesCount`   | `uint16`                    | Number of witnesses.                    |
| `script`           | `byte[]`                    | Script to execute.                      |
| `scriptData`       | `byte[]`                    | Script input data (parameters).         |
| `policies`         | [Policy](./policy.md)`[]`   | List of policies, sorted by `PolicyType`. |
| `inputs`           | [Input](./input.md)`[]`     | List of inputs.                         |
| `outputs`          | [Output](./output.md)`[]`   | List of outputs.                        |
| `witnesses`        | [Witness](./witness.md)`[]` | List of witnesses.                      |

Given helper `len()` that returns the number of bytes of a field.

Transaction is invalid if:

- Any output is of type `OutputType.ContractCreated`
- `scriptLength > MAX_SCRIPT_LENGTH`
- `scriptDataLength > MAX_SCRIPT_DATA_LENGTH`
- `scriptLength * 4 != len(script)`
- `scriptDataLength != len(scriptData)`

> **Note:** when signing a transaction, `receiptsRoot` is set to zero.
>
> **Note:** when verifying a predicate or executing a script, `receiptsRoot` is initialized to zero.

The receipts root `receiptsRoot` is the root of the [binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) of receipts. If there are no receipts, its value is set to the root of the empty tree, i.e. `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`.

## `TransactionCreate`

| name                   | type                        | description                                       |
|------------------------|-----------------------------|---------------------------------------------------|
| `bytecodeWitnessIndex` | `uint16`                    | Witness index of contract bytecode to create.     |
| `salt`                 | `byte[32]`                  | Salt.                                             |
| `storageSlotsCount`    | `uint64`                    | Number of storage slots to initialize.            |
| `policyTypes`          | `uint32`                    | Bitfield of used policy types.                    |
| `inputsCount`          | `uint16`                    | Number of inputs.                                 |
| `outputsCount`         | `uint16`                    | Number of outputs.                                |
| `witnessesCount`       | `uint16`                    | Number of witnesses.                              |
| `storageSlots`         | `(byte[32], byte[32]])[]`   | List of storage slots to initialize (key, value). |
| `policies`             | [Policy](./policy.md)`[]`    | List of policies.                                  |
| `inputs`               | [Input](./input.md)`[]`     | List of inputs.                                   |
| `outputs`              | [Output](./output.md)`[]`   | List of outputs.                                  |
| `witnesses`            | [Witness](./witness.md)`[]` | List of witnesses.                                |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- It does not have exactly one output of type `OutputType.ContractCreated`
- `tx.data.witnesses[bytecodeWitnessIndex].dataLength > CONTRACT_MAX_SIZE`
- `bytecodeWitnessIndex >= tx.witnessesCount`
- The keys of `storageSlots` are not in ascending lexicographic order
- The computed contract ID (see below) is not equal to the `contractID` of the one `OutputType.ContractCreated` output
- `storageSlotsCount > MAX_STORAGE_SLOTS`
- The [Sparse Merkle tree](../protocol/cryptographic-primitives.md#sparse-merkle-tree) root of `storageSlots` is not equal to the `stateRoot` of the one `OutputType.ContractCreated` output

Creates a contract with contract ID as computed [here](../identifiers/contract-id.md).

## `TransactionMint`

The transaction is created by the block producer and is not signed. Since it is not usable outside of block creation or execution, all fields must be fully set upon creation without any zeroing.
This means that the transaction ID must also include the correct `txPointer` value, not zeroed out.

| name             | type                            | description                                                                |
|------------------|---------------------------------|----------------------------------------------------------------------------|
| `txPointer`      | [`TXPointer`](./tx-pointer.md)  | The location of the `Mint` transaction in the block.                       |
| `inputContract`  | [`InputContract`](./input.md)   | The contract UTXO that assets are minted to.                               |
| `outputContract` | [`OutputContract`](./output.md) | The contract UTXO that assets are being minted to.                         |
| `mintAmount`     | `uint64`                        | The amount of funds minted.                                                |
| `mintAssetId`    | `byte[32]`                      | The asset IDs corresponding to the minted amount.                          |
| `gasPrice`       | `uint64`                        | The gas price to be used in calculating all fees for transactions on block |

Transaction is invalid if:

- `txPointer` is zero or doesn't match the block.
- `outputContract.inputIndex` is not zero

## `TransactionUpgrade`

The `Upgrade` transaction allows upgrading either consensus parameters or state transition function used by the network to produce future blocks. The `Upgrade Purpose` type defines the purpose of the upgrade.

The `Upgrade` transaction is chargeable, and the sender should pay for it. Transaction inputs should contain only base assets.

Only the privileged address from [`ConsensusParameters`](./consensus_parameters.md) can upgrade the network. The privileged address can be either a real account or a predicate.

When the upgrade type is `UpgradePurposeType.ConsensusParameters` serialized consensus parameters are available in the witnesses and the `Upgrade` transaction is self-contained because it has all the required information.

When the upgrade type is `UpgradePurposeType.StateTransition`, the `bytecodeRoot` field contains the Merkle root of the new bytecode of the state transition function. The bytecode should already be available on the blockchain at the upgrade point; otherwise, the upgrade will fail. The bytecode can be part of the genesis block or can be uploaded via the `TransactionUpload` transaction.

The block header contains information about which versions of consensus parameters and state transition function are used to produce a block, and the `Upgrade` transaction defines behavior corresponding to the version. When the block executes the `Upgrade` transaction, it defines new behavior for either `BlockHeader.consensusParametersVersion + 1` or `BlockHeader.stateTransitionBytecodeVersion + 1`(it depends on the purpose of the upgrade).

When the `Upgrade` transaction is included in the block, it doesn't affect the current block execution. Since behavior is now defined, the inclusion of the `Upgrade` transaction allows the production of the next block with a new version. The block producer can still continue to use the previous version and start using a new version later unless the state transition function forbids it.

The behavior is set once per version. It is forbidden to override the behavior of the network. Each behavior should have its own version. The version should grow monotonically without jumps.

The `BlockHeader.consensusParametersVersion` and `BlockHeader.stateTransitionBytecodeVersion` are independent and can grow at different speeds.

| name             | type                                   | description                    |
|------------------|----------------------------------------|--------------------------------|
| `upgradePurpose` | [UpgradePurpose](./upgrade_purpose.md) | The purpose of the upgrade.    |
| `policyTypes`    | `uint32`                               | Bitfield of used policy types. |
| `inputsCount`    | `uint16`                               | Number of inputs.              |
| `outputsCount`   | `uint16`                               | Number of outputs.             |
| `witnessesCount` | `uint16`                               | Number of witnesses.           |
| `policies`       | [Policy](./policy.md)`[]`              | List of policies.              |
| `inputs`         | [Input](./input.md)`[]`                | List of inputs.                |
| `outputs`        | [Output](./output.md)`[]`              | List of outputs.               |
| `witnesses`      | [Witness](./witness.md)`[]`            | List of witnesses.             |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- No input where `InputType.Message.owner == PRIVILEGED_ADDRESS` or `InputType.Coint.owner == PRIVILEGED_ADDRESS`
- The `UpgradePurpose` is invalid

## `TransactionUpload`

The `Upload` transaction allows the huge bytecode to be divided into subsections and uploaded slowly to the chain. The [Binary Merkle root](../protocol/cryptographic-primitives.md#binary-merkle-tree) built on top of subsections is an identifier of the bytecode.

Each transaction uploads a subsection of the code and must contain proof of connection to the root. All subsections should be uploaded sequentially, which allows the concatenation of previously uploaded subsections with new subsection. The bytecode is considered final when the last subsection is uploaded, and future `Upload` transactions with the same `root` fields should be rejected.

When the bytecode is completed it can be used to upgrade the network.

The size of each subsection can be arbitrary; the only limit is the maximum number of subsections allowed by the network. The combination of the transaction gas limit and the number of subsections limits the final maximum size of the bytecode.

| name                | type                        | description                                                                             |
|---------------------|-----------------------------|-----------------------------------------------------------------------------------------|
| `root`              | `byte[32]`                  | The root of the Merkle tree is created over the bytecode.                               |
| `witnessIndex`      | `uint16`                    | The witness index of the subsection of the bytecode.                                    |
| `subsectionIndex`   | `uint16`                    | The index of the subsection of the bytecode.                                            |
| `subsectionsNumber` | `uint16`                    | The total number of subsections on which bytecode was divided.                          |
| `proofSetCount`     | `uint16`                    | Number of Merkle nodes in the proof.                                                    |
| `policyTypes`       | `uint32`                    | Bitfield of used policy types.                                                          |
| `inputsCount`       | `uint16`                    | Number of inputs.                                                                       |
| `outputsCount`      | `uint16`                    | Number of outputs.                                                                      |
| `witnessesCount`    | `uint16`                    | Number of witnesses.                                                                    |
| `proofSet`          | `byte[32][]`                | The proof set of Merkle nodes to verify the connection of the subsection to the `root`. |
| `policies`          | [Policy](./policy.md)`[]`   | List of policies.                                                                       |
| `inputs`            | [Input](./input.md)`[]`     | List of inputs.                                                                         |
| `outputs`           | [Output](./output.md)`[]`   | List of outputs.                                                                        |
| `witnesses`         | [Witness](./witness.md)`[]` | List of witnesses.                                                                      |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- `witnessIndex >= tx.witnessesCount`
- `subsectionIndex` >= `subsectionsNumber`
- `subsectionsNumber > MAX_BYTECODE_SUBSECTIONS`
- The [Binary Merkle tree](../protocol/cryptographic-primitives.md#binary-merkle-tree) root calculated from `(witnesses[witnessIndex], subsectionIndex, subsectionsNumber, proofSet)` is not equal to the `root`. Root calculation is affected by all fields, so modification of one of them invalidates the proof.

## `TransactionBlob`

The `Blob` inserts a simple binary blob in the chain. It's raw immutable data that can be cheaply loaded by the VM and used as instructions or just data. Unlike `Create`, it doesn't hold any state or balances.

`Blob`s are content-addressed, i.e. the they are uniquely identified by hash of the data field. Programs running on the VM can load an already-posted blob just by the hash, without having to specify it in contract inputs.

| name                | type                        | description                      |
|---------------------|-----------------------------|----------------------------------|
| `id`                | `byte[32]`                  | Blob id, i.e. hash of the data.  |
| `witnessIndex`      | `uint16`                    | The witness index of the data.   |
| `policyTypes`       | `uint32`                    | Bitfield of used policy types.   |
| `inputsCount`       | `uint16`                    | Number of inputs.                |
| `outputsCount`      | `uint16`                    | Number of outputs.               |
| `witnessesCount`    | `uint16`                    | Number of witnesses.             |
| `policies`          | [Policy](./policy.md)`[]`   | List of policies.                |
| `inputs`            | [Input](./input.md)`[]`     | List of inputs.                  |
| `outputs`           | [Output](./output.md)`[]`   | List of outputs.                 |
| `witnesses`         | [Witness](./witness.md)`[]` | List of witnesses.               |

Transaction is invalid if:

- Any input is of type `InputType.Contract` or `InputType.Message` where `input.dataLength > 0`
- Any input uses non-base asset.
- Any output is of type `OutputType.Contract` or `OutputType.Variable` or `OutputType.Message` or `OutputType.ContractCreated`
- Any output is of type `OutputType.Change` with non-base `asset_id`
- `witnessIndex >= tx.witnessesCount`
- `sha256(witnesses[witnessIndex]) != id`


---

### File: docs/nightly/fuel-specs/src/tx-format/tx-pointer.md

# `TXPointer`

The location of the transaction in the block. It can be used by UTXOs as a reference to the transaction or by the transaction itself to make it unique.

| name          | type     | description        |
|---------------|----------|--------------------|
| `blockHeight` | `uint32` | Block height.      |
| `txIndex`     | `uint16` | Transaction index. |


---

### File: docs/nightly/fuel-specs/src/tx-format/upgrade_purpose.md

# `UpgradePurposeType`

```c++
enum UpgradePurposeType : uint8 {
    ConsensusParameters = 0,
    StateTransition = 1,
}
```

| name   | type                                                                                        | description              |
|--------|---------------------------------------------------------------------------------------------|--------------------------|
| `type` | [`UpgradePurposeType`](#upgradepurposetype)                                                 | Type of upgrade purpose. |
| `data` | One of [`ConsensusParameters`](#consensusparameters), [`StateTransition`](#statetransition) | Upgrade purposes.        |

Transaction is invalid if:

- `type` is not valid `UpgradePurposeType` value`

## `ConsensusParameters`

| name           | type       | description                                                                                                                   |
|----------------|------------|-------------------------------------------------------------------------------------------------------------------------------|
| `witnessIndex` | `uint16`   | Index of witness that contains a serialized(with [postcard](https://docs.rs/postcard/latest/postcard/)) consensus parameters. |
| `checksum`     | `byte[32]` | The hash of the serialized consensus parameters.                                                                              |

Given helper `deserialize_consensus_parameters()` that deserializes the consensus parameters from a witness by using [postcard](https://docs.rs/postcard/latest/postcard/) algorithm.

Transaction is invalid if:

- `witnessIndex >= tx.witnessesCount`
- `checksum != sha256(tx.data.witnesses[witnessIndex])`
- `deserialize_consensus_parameters(tx.data.witnesses[witnessIndex])` returns an error.

## `StateTransition`

| name           | type       | description                                                    |
|----------------|------------|----------------------------------------------------------------|
| `bytecodeRoot` | `byte[32]` | The root of the new bytecode of the state transition function. |


---

### File: docs/nightly/fuel-specs/src/tx-format/witness.md

# Witness

| name         | type     | description                       |
|--------------|----------|-----------------------------------|
| `dataLength` | `uint64` | Length of witness data, in bytes. |
| `data`       | `byte[]` | Witness data.                     |


---

### File: docs/nightly/fuel-token-overview/docs/src/claim-genesis-drop.md

# Claim Genesis Drop

Please visit [app.fuel.network/earn-points/drop/](https://app.fuel.network/earn-points/drop/) to claim your FUEL airdrop. Below is a brief help guide to assist you.

## Check Eligibility

Start by connecting all accounts eligible for Phase 1 of the FUEL airdrop. This includes GitHub accounts, Fuel wallets (both native and non-native), and Ethereum wallets.

![Connect Accounts](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/1-connect-wallet.png)

You connect all three wallet types at the same time and view the claimable amount for each individual account.

![Airdrop Amount Multi](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/2-airdrop-amount-multi.png)

Note that any eligible Ethereum accounts you connect will automatically load their corresponding eligible Fuel accounts. If rewards were earned using a non-Fuel wallet, they will still appear in the Fuel Wallet where the tokens were bridged.

![Airdrop Amount Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/3-airdrop-amount-pt3.png)

## Claim

To start the claiming process, click “Join the Claim Queue.”

![Join Queue](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/4-join-queue.png)

Once you have joined the queue, you will have exactly 10 minutes to claim your FUEL tokens from each of your eligible accounts or else you will have to requeue.

![Claim](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/5-claim.png)

Please carefully read over the terms of service before proceeding to claim your tokens. Once you’re ready, simply click “Claim.”

![Claim Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/6-claim-pt2.png)

When claiming through an Ethereum wallet, you can connect a Fuel wallet to receive your tokens. Plus, as a bonus, if you don't have any ETH on Fuel Ignition, you’ll get a small amount of  gas to help you claim your Fuel tokens!

![Claim Eth](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/claim-genesis-drop/7-claim-eth.png)

Congratulations and thank you for being a part of the Fuel community! Now, please head over to Fuel Ignition and follow this [guide](./stake-on-fuel.md) to stake your tokens.


---

### File: docs/nightly/fuel-token-overview/docs/src/fuel-v1-upgrade.md

# How to Upgrade Fuel V1 to FUEL

> The Fuel V1 token was the previous iteration of the FUEL token. The initial supply of Fuel V1 tokens was 100 million. The supply of the current FUEL token is 10 billion. Fuel V1 tokens can accordingly be upgraded at a ratio of 1:100.

Please visit [app.fuel.network/upgrade](https://app.fuel.network/upgrade) to upgrade your Fuel V1 tokens to FUEL tokens. Below is a short help guide:

## Connecting an EVM Wallet

Fuel V1 grants exist only on the Ethereum mainnet. Please connect an EVM wallet with a token grant or Fuel V1 tokens using the button in the top-right corner.

![Connect EVM Wallet](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/1-connect-evm-wallet.png)

## Claiming a Token Grant

If you have a token grant, the amount of unclaimed tokens will be displayed, along with a button to claim the tokens into your wallet. If you already have Fuel V1 tokens ready to upgrade, you can skip this step.

![Claim Token Grant](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/2-claim-token-grant.png)

## Upgrade Fuel V1 Tokens to Fuel Tokens

Once you have Fuel V1 tokens in your wallet, click the "Upgrade to FUEL" button to start the upgrading process. This will take you to two screens.

![Upgrade To FUEL](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/3-convert-to-fuel.png)

The first screen is to approve the amount of tokens to be upgraded.

![Approve Amount](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/4-approve-amount.png)

The second screen is to complete upgrading of Fuel V1 tokens to FUEL tokens.

![Confirm Conversion](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/5-confirm-conversion.png)

That's it! You can now deposit and delegate your tokens to start earning rewards. Since your tokens are on the Ethereum mainnet, you have two options:

1. Stake on Ethereum:

    Use [app.fuel.network/staking/on-ethereum](https://app.fuel.network/staking/on-ethereum) to stake your tokens on the shared sequencer network from Ethereum. Note that this interface differs from the one used for tokens on Fuel Ignition. Follow the instructions provided in [How to Stake on Mainnet Ethereum](./stake-on-ethereum.md).

2. Bridge and Stake on Fuel Ignition:

    Alternatively, you can withdraw and bridge your tokens to Fuel Ignition to benefit from lower costs and higher speeds. Use the [Fuel Bridge](https://app.fuel.network/bridge?from=eth&to=fuel) to transfer your tokens, then stake them using [app.fuel.network/staking/on-fuel](https://app.fuel.network/staking/on-fuel). Follow the instructions provided in the [How to Stake on Fuel Ignition guide](./stake-on-fuel.md).

![Balance](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-upgrade-fuel-v1/6-balance.png)

> **Note:** It may take some time for your balance to appear on the shared sequencer network. Please don’t panic—your balance will update soon.


---

### File: docs/nightly/fuel-token-overview/docs/src/index.md

# FUEL Token

| Property                | Details                                    |
|-------------------------|--------------------------------------------|
| Ticker                  | FUEL                                       |
| Total supply at genesis | 10,000,000,000 FUEL                        |
| Decimals                | 9                                          |
| Address                 | [0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c](https://etherscan.io/address/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c) |
| Inflation Schedule      | 3% annually                                |

## The Role of FUEL

FUEL powers Fuels decentralized sequencer and eliminates gas fees for users by introducing a novel economic incentive structure based on Application Specific Sequencing. By enabling fee-less, web2-like, fee-less experiences for users, FUEL makes blockchain technology more usable and accessible to the masses.

FUEL secures the Fuel sequencing network, pays for chain resources and eliminates transaction fees for users– all while fostering new markets for L2 applications. Beyond sequencing, FUEL is on a mission to make blockchain usable without compromising on decentralization, setting a new standard for rollups in a space dominated by centralized solutions today.

Learn more about the Fuel Sequencer or see the [Fuel Genesis announcement](https://fuel.mirror.xyz/T6A4x8ReVu5ucAdwXXhrJawN9n4op7de4y7xW9MJ8ew) to learn more about the FUEL token's utility and distribution.

## FUEL Overview

![Fuel Banner](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/about/1-fuel-banner.png)

$FUEL will secure the Fuel sequencing network, pay for chain resources and eliminate transaction fees for users while creating new markets for L2 applications.

### 1. Securing the Network

The rollup landscape today is dominated by centralized sequencing solutions, raising concerns about censorship resistance, fairness, and liveness.

Fuel is taking steps to address these challenges. Initially, Fuel will decentralize a network of proposers, then decentralize building, and then will aim to increase the total number of proposers and builders.

The Fuel sequencer employs proof-of-stake (PoS) based on the Tendermint consensus, enabling a decentralized staking network. Users can actively participate in securing the network by delegating their FUEL to sequencer proposers in exchange for a share of staking rewards.

Our vision is to fully decentralize sequencing, which is essential for improving fault tolerance, liveness and censorship resistance. While centralized solutions dominate the space today, Fuel is committed to evolving toward a shared, permissionless network for its rollups.

Validator participation and staking will commence with Fuel Genesis, with detailed information on permissionless staking and running a validator available at a later date.

### 2. Paying for Chain Resources

FUEL will be used to pay for sequencer resources such as data availability, ordering and inclusion of blocks for rollups on the Fuel sequencer. FUEL will also be used for sequencer network fees, which play an essential role in decentralizing L2s built on Fuel as well as ensuring an open and decentralized sequencing network.

Fuel Ignition will continue to accept gas fees in ETH.

### 3. Application Specific Sequencing & Eliminating Fees

FUEL gives dApps greater influence on the inclusion and sequencing of transactions, while avoiding the complexities and limitations of traditional blockchain architectures. Stakers can bond their FUEL tokens to a specific application and earn rewards from those applications in exchange for locking their tokens. This allows transactions to be free for the user and executed according to application specific order. The result is a novel market for L2 chain resources that engages stakers to enable best in class user experiences (i.e. staking resources will receive tokens from applications, and enable free user transactions).

Note: More details about these activities, including instructions on how to delegate and stake will be provided soon.

## Progressive Decentralization

We outline three key phases for advancing the decentralization of the network.

- Phase 0, now completed, established 12 sequencer proposers and introduced initial security measures.
- Phase 1 focuses on decentralized block building and enhanced security.
- Phase 2 aims to significantly scale the network with more proposers, and advanced security features.

This is just the start of our journey, and we're excited to share our plans for advancing the network.

![Progressive Decentralization](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/about/2-progressive-decentralization.png)

## Helpful Links

- Have a question? Ask us a question at [forum.fuel.network](https://forum.fuel.network/) or [Discord](https://discord.com/invite/xfpK4Pe)
- [Genesis Drop Claims](./claim-genesis-drop.md)
- [Upgrade Fuel V1 to FUEL](./fuel-v1-upgrade.md)
- [Stake, Withdrawal and Reward Claims from Fuel Ignition](./stake-on-fuel.md)
- [Stake, Withdrawal and Reward Claims from Ethereum](./stake-on-ethereum.md)


---

### File: docs/nightly/fuel-token-overview/docs/src/stake-on-ethereum.md

# How to Stake on Mainnet Ethereum

Please visit [app.fuel.network/staking/on-ethereum](https://app.fuel.network/staking/on-ethereum) to stake your tokens on the Fuel Shared Sequencer Network from Ethereum. Below is a help guide:

## Connect EVM Wallet

Start by connecting an Ethereum wallet with FUEL tokens, whether they are already in the shared sequencer network or in your mainnet wallet.

![Connect EVM Wallet](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/1-connect-evm-wallet.png)

## Stake

From left to right, you can see your balance of FUEL tokens in your Ethereum wallet, your balance of FUEL tokens in the shared sequencer network, and the rewards accumulated.

Please note that tokens still in your mainnet Ethereum wallet must be migrated to the shared sequencer network first before you can delegate and stake. Don’t worry, as this will follow the same flow.

![Token Balances](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/2-token-balances.png)

### Select Validator

Scroll down to the bottom of the page. There, you will see a list of validators. From the list, choose the validator to which you want to stake and delegate your FUEL tokens. Click the "Deposit" button.

![Select Validator](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/3-select-validator.png)

### Delegating Tokens

Select the amount of FUEL tokens you want to delegate, and approve those tokens.

![Delegate Tokens](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/4-delegation-amount.png)

Once approved, confirm your delegation.

![Open Positions](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/5-confirm-delegation.png)

After the tokens have been successfully delegated and staked, you will see your tokens under "Delegated Positions."

![Open Positions](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/5.5-open-delegated-positions.png)

## Claim Rewards

After staking your FUEL tokens, you will immediately start to accumulate FUEL rewards, which you can claim. Click "Claim" on any of your open delegated positions to collect your rewards.

![Claim Rewards](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/6-claim-rewards.png)

Your rewards will be added to your balance in the Fuel shared sequencer network.

![Claim Rewards Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/7-claim-rewards-pt2.png)

## Withdrawal

You can undelegate and withdraw your staked FUEL tokens at any time. However, there is a standard 14-day unbonding period before the undelegation is completed, ensuring economic security within the PoS shared sequencer network and the Ethereum mainnet. After the 14-day period, the withdrawal process requires 4096 sequencer blocks approximately seven more hours before your tokens become available in your mainnet Ethereum wallet.

### Undelegate

To undelegate your open positions, simply press the hamburger button beside your position and click the "Undelegate" button.

![Withdrawal](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/8-undelegate.png)

Here, you can select how many delegated tokens you wish to undelegate. These tokens will return to your balance in the shared sequencer network.

![Withdrawal Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/9-undelegate-pt2.png)

### Withdraw Balance in Sequencer

Lastly, you can withdraw your tokens from the shared sequencer network back to your mainnet Ethereum wallet by clicking the "Withdraw" button beside your balance in the shared sequencer.

![Withdrawal](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/10-withdrawal.png)

Here you can specify how many tokens you want to withdraw.

![Withdrawal Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-mainnet-ethereum/10.5-withdrawal-pt2.png)


---

### File: docs/nightly/fuel-token-overview/docs/src/stake-on-fuel.md

# How to Stake on Fuel

Please visit [app.fuel.network/staking/on-fuel](https://app.fuel.network/staking/on-fuel) to stake your tokens on the Fuel Shared Sequencer Network through Fuel Ignition. Below, you'll find a helpful guide to get started.

## Connect Fuel Wallet

Start by connecting a Fuel wallet with FUEL tokens. This includes both non-native EVM and SVM wallets.

![Connect EVM Wallet](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/1-connect-wallet.png)  
![Connect EVM Wallet 1.5](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/1.5-connect-wallet.png)

## Stake

From left to right, you can view your FUEL token balance in your Fuel wallet, your staked FUEL token balance on the shared sequencer network, and your accumulated rewards.

Press the "Stake" button next to your balance to begin the staking process.

![Stake Tokens](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/2-stake-token.png)

Enter the number of tokens you wish to delegate to the validators. Then, click the "Deposit" button to stake your tokens.

Please note: unlike staking on mainnet Ethereum, the validator delegation process is automatically assigned, so you don’t need to manage each validator manually.

![Stake Tokens](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/3-stake-token-pt2.png)

After successfully depositing, your total staked token balance will update. The dashboard below will display the distribution of your delegated tokens. In the example diagram, the tokens are distributed evenly among the validators.

![Validator Distribution](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/4-validator-distribution.png)

## Withdraw

Withdrawing from the shared sequencer network is as simple as staking. Click the "Withdraw" button beside the amount of tokens you have staked.

![Withdrawal](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/5-withdrawal.png)

Select the amount of FUEL tokens you wish to withdraw, then click the "Withdraw" button.

![Withdrawal Pt2](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/6-withdrawal-pt2.png)

Your undelegated token balance will return to your Fuel wallet, and the validator dashboard will update accordingly as well.

![Withdrawal Pt3](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/6.5-withdrawal-pt3.png)

## Claim Rewards

Once you have staked your FUEL tokens, you will start to accumulate FUEL rewards. Click "Claim" next to your earned rewards balance to collect your tokens.

![Claim Rewards](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/how-to-stake-fuel-ignition/7-claim-rewards.png)


---

### File: docs/nightly/fuel-token-overview/docs/src/tokenomics.md

# Tokenomics

With the introduction of FUEL and its total initial supply of 10 billion tokens, we aim to create a level playing field that ensures fair access for both existing members and newcomers to our growing ecosystem. To acknowledge and reward our long-standing friends, builders, and users, 20% of the initial supply will be distributed to the community, with eligibility determined by factors such as participation in the Fuel Points Program and our incentivized testnet. In total, over 51% of all FUEL tokens will ultimately be allocated to the community, the broader ecosystem, and ongoing research and development efforts, reflecting our commitment to inclusivity and shared growth.

![Allocation Pie Chart](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/tokenomics/1-pie.png)

| Group                | Details                                                                                                                                                                                                    | Amount       |
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|
| Community Expansion  | Used for incentives, programs, campaigns and activations for the Fuel community and expansion.                                                                                                             | 2.00 billion |
| Ecosystem and R&D    | Used to establish the sequencing network, and for ecosystem development and Fuel technology R&D.                                                                                                           | 1.55 billion |
| Ecosystem and R&D 24 | Same as above. These locked tokens can be staked during the 24 month block-by-block linear release. Staking rewards will only be used for ecosystem development efforts and to enable L2 level incentives. | 1.55 billion |
| Contributors 24      | Includes past and present Fuel contributors.                                                                                                                                                               | 0.60 billion |
| Contributors 48      | Core project contributors.                                                                                                                                                                                 | 0.98 billion |
| Purchasers           | Token purchasers from 2020 to 2022.                                                                                                                                                                        | 3.31 billion |

## Inflation

Inflation will be 3% annually. Note that inflation and Fuel economics are configured by the sequencer validator set.

## Unlocks

Note: Team and Purchasers can't stake locked tokens.

![Release Schedule](https://raw.githubusercontent.com/FuelLabs/fuel-token-overview/refs/heads/main/assets/tokenomics/2-release-schedule.png)

| Group                | Details                                                                                                                                                                                                    | Vesting Schedule        |
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|
| Community            | Used for incentives, programs, campaigns and activations for the Fuel community and expansion.                                                                                                             | Immediate               |
| Ecosystem and R&D    | Used to establish the sequencing network, and for ecosystem development and Fuel technology R&D.                                                                                                           | Immediate               |
| Ecosystem and R&D 24 | Same as above. These locked tokens can be staked during the 24 month block-by-block linear release. Staking rewards will only be used for ecosystem development efforts and to enable L2 level incentives. | 24 month linear release |
| Contributors 24      | Includes past and present Fuel contributors.                                                                                                                                                               | 24 month linear release |
| Contributors 48      | Core project contributors.                                                                                                                                                                                 | 48 month linear release |
| Purchasers           | Token purchasers from 2020 to 2022.                                                                                                                                                                        | 24 month linear release |


---

### File: docs/nightly/fuels-rs/docs/src/abigen/index.md

# Generating bindings with abigen

You might have noticed this snippet in the previous sections:

```rust,ignore
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
```

<!-- This section should explain the purpose of the abigen -->
<!-- abigen:example:start -->
The SDK lets you transform ABI methods of a smart contract, specified as JSON objects (which you can get from [Forc](https://github.com/FuelLabs/sway/tree/master/forc)), into Rust structs and methods that are type-checked at compile time.
In order to call your contracts, scripts or predicates, you first need to generate the Rust bindings for them.
<!-- abigen:example:end -->

The following subsections contain more details about the `abigen!` syntax and the code generated from it.


---

### File: docs/nightly/fuels-rs/docs/src/abigen/the-abigen-macro.md

# abigen

<!-- This section explain the `abigen!` macro -->
<!-- abigen:example:start -->
`abigen!` is a procedural macro -- it generates code. It accepts inputs in the format of:

```text
ProgramType(name="MyProgramType", abi="my_program-abi.json")...
```

where:

- `ProgramType` is one of: `Contract`, `Script` or `Predicate`,

- `name` is the name that will be given to the generated bindings,

- `abi` is either a path to the JSON ABI file or its actual contents.
<!-- abigen:example:end -->

---
So, an `abigen!` which generates bindings for two contracts and one script looks like this:

```rust,ignore
        abigen!(
            Contract(
                name = "ContractA",
                abi = "e2e/sway/bindings/sharing_types/contract_a/out/release/contract_a-abi.json"
            ),
            Contract(
                name = "ContractB",
                abi = "e2e/sway/bindings/sharing_types/contract_b/out/release/contract_b-abi.json"
            ),
            Script(
                name = "MyScript",
                abi = "e2e/sway/scripts/arguments/out/release/arguments-abi.json"
            ),
            Predicate(
                name = "MyPredicateEncoder",
                abi = "e2e/sway/predicates/basic_predicate/out/release/basic_predicate-abi.json"
            ),
        );
```

## How does the generated code look?

A rough overview:

```rust,ignore
pub mod abigen_bindings {
    pub mod contract_a_mod {
        struct SomeCustomStruct{/*...*/};
        // other custom types used in the contract

        struct ContractA {/*...*/};
        impl ContractA {/*...*/};
        // ...
    }
    pub mod contract_b_mod {
        // ...
    }
    pub mod my_script_mod {
        // ...
    }
    pub mod my_predicate_mod{
        // ...
    }
    pub mod shared_types{
        // ...
    }
}

pub use contract_a_mod::{/*..*/};
pub use contract_b_mod::{/*..*/};
pub use my_predicate_mod::{/*..*/};
pub use shared_types::{/*..*/};
```

Each `ProgramType` gets its own `mod` based on the `name` given in the `abigen!`. Inside the respective mods, the custom types used by that program are generated, and the bindings through which the actual calls can be made.

One extra `mod` called `shared_types` is generated if `abigen!` detects that the given programs share types. Instead of each `mod` regenerating the type for itself, the type is lifted out into the `shared_types` module, generated only once, and then shared between all program bindings that use it. Reexports are added to each mod so that even if a type is deemed shared, you can still access it as though each `mod` had generated the type for itself (i.e. `my_contract_mod::SharedType`).

A type is deemed shared if its name and definition match up. This can happen either because you've used the same library (a custom one or a type from the `stdlib`) or because you've happened to define the exact same type.

Finally, `pub use` statements are inserted, so you don't have to fully qualify the generated types. To avoid conflict, only types that have unique names will get a `pub use` statement. If you find `rustc` can't find your type, it might just be that there is another generated type with the same name. To fix the issue just qualify the path by doing `abigen_bindings::whatever_contract_mod::TheType`.

> **Note:**
> It is **highly** encouraged that you generate all your bindings in one `abigen!` call. Doing it in this manner will allow type sharing and avoid name collisions you'd normally get when calling `abigen!` multiple times inside the same namespace. If you choose to proceed otherwise, keep in mind the generated code overview presented above and appropriately separate the `abigen!` calls into different modules to resolve the collision.

## Using the bindings

Let's look at a contract with two methods: `initialize_counter(arg: u64) -> u64` and `increment_counter(arg: u64) -> u64`, with the following JSON ABI:

```json,ignore
{
  "programType": "contract",
  "specVersion": "1",
  "encodingVersion": "1",
  "concreteTypes": [
    {
      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
      "type": "u64"
    }
  ],
  "functions": [
    {
      "inputs": [
        {
          "name": "value",
          "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
        }
      ],
      "name": "initialize_counter",
      "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    },
    {
      "inputs": [
        {
          "name": "value",
          "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
        }
      ],
      "name": "increment_counter",
      "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
    }
  ],
  "metadataTypes": []
}

```

By doing this:

```rust,ignore
            use fuels::prelude::*;
            // Replace with your own JSON abi path (relative to the root of your crate)
            abigen!(Contract(
                name = "MyContractName",
                abi = "examples/rust_bindings/src/abi.json"
            ));
```

or this:

```rust,ignore
            use fuels::prelude::*;
            abigen!(Contract(
                name = "MyContract",
                abi = r#"
            {
              "programType": "contract",
              "specVersion": "1",
              "encodingVersion": "1",
              "concreteTypes": [
                {
                  "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0",
                  "type": "u64"
                }
              ],
              "functions": [
                {
                  "inputs": [
                    {
                      "name": "value",
                      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                    }
                  ],
                  "name": "initialize_counter",
                  "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                },
                {
                  "inputs": [
                    {
                      "name": "value",
                      "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                    }
                  ],
                  "name": "increment_counter",
                  "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0"
                }
              ],
              "metadataTypes": []
            }
            "#
            ));
```

you'll generate this (shortened for brevity's sake):

```rust,ignore
pub mod abigen_bindings {
    pub mod my_contract_mod {
        #[derive(Debug, Clone)]
        pub struct MyContract<A: ::fuels::accounts::Account> {
            contract_id: ::fuels::types::ContractId,
            account: A,
            log_decoder: ::fuels::core::codec::LogDecoder,
            encoder_config: ::fuels::core::codec::EncoderConfig,
        }
        impl<A: ::fuels::accounts::Account> MyContract<A> {
            pub fn new(contract_id: ::fuels::types::ContractId, account: A) -> Self {
                let log_decoder = ::fuels::core::codec::LogDecoder::new(
                    ::fuels::core::codec::log_formatters_lookup(vec![], contract_id.clone().into()),
                );
                let encoder_config = ::fuels::core::codec::EncoderConfig::default();
                Self {
                    contract_id,
                    account,
                    log_decoder,
                    encoder_config,
                }
            }
            pub fn contract_id(&self) -> &::fuels::types::ContractId {
                self.contract_id
            }
            pub fn account(&self) -> A {
                self.account.clone()
            }
            pub fn with_account<U: ::fuels::accounts::Account>(self, account: U) -> MyContract<U> {
                MyContract {
                    contract_id: self.contract_id,
                    account,
                    log_decoder: self.log_decoder,
                    encoder_config: self.encoder_config,
                }
            }
            pub fn with_encoder_config(
                mut self,
                encoder_config: ::fuels::core::codec::EncoderConfig,
            ) -> MyContract<A> {
                self.encoder_config = encoder_config;
                self
            }
            pub async fn get_balances(
                &self,
            ) -> ::fuels::types::errors::Result<
                ::std::collections::HashMap<::fuels::types::AssetId, u64>,
            > {
                ::fuels::accounts::ViewOnlyAccount::try_provider(&self.account)?
                    .get_contract_balances(&self.contract_id)
                    .await
                    .map_err(::std::convert::Into::into)
            }
            pub fn methods(&self) -> MyContractMethods<A> {
                MyContractMethods {
                    contract_id: self.contract_id.clone(),
                    account: self.account.clone(),
                    log_decoder: self.log_decoder.clone(),
                    encoder_config: self.encoder_config.clone(),
                }
            }
        }
        pub struct MyContractMethods<A: ::fuels::accounts::Account> {
            contract_id: ::fuels::types::ContractId,
            account: A,
            log_decoder: ::fuels::core::codec::LogDecoder,
            encoder_config: ::fuels::core::codec::EncoderConfig,
        }
        impl<A: ::fuels::accounts::Account> MyContractMethods<A> {
            #[doc = " This method will read the counter from storage, increment it"]
            #[doc = " and write the incremented value to storage"]
            pub fn increment_counter(
                &self,
                value: ::core::primitive::u64,
            ) -> ::fuels::programs::calls::CallHandler<
                A,
                ::fuels::programs::calls::ContractCall,
                ::core::primitive::u64,
            > {
                ::fuels::programs::calls::CallHandler::new_contract_call(
                    self.contract_id.clone(),
                    self.account.clone(),
                    ::fuels::core::codec::encode_fn_selector("increment_counter"),
                    &[::fuels::core::traits::Tokenizable::into_token(value)],
                    self.log_decoder.clone(),
                    false,
                    self.encoder_config.clone(),
                )
            }
            pub fn initialize_counter(
                &self,
                value: ::core::primitive::u64,
            ) -> ::fuels::programs::calls::CallHandler<
                A,
                ::fuels::programs::calls::ContractCall,
                ::core::primitive::u64,
            > {
                ::fuels::programs::calls::CallHandler::new_contract_call(
                    self.contract_id.clone(),
                    self.account.clone(),
                    ::fuels::core::codec::encode_fn_selector("initialize_counter"),
                    &[::fuels::core::traits::Tokenizable::into_token(value)],
                    self.log_decoder.clone(),
                    false,
                    self.encoder_config.clone(),
                )
            }
        }
        impl<A: ::fuels::accounts::Account> ::fuels::programs::calls::ContractDependency for MyContract<A> {
            fn id(&self) -> ::fuels::types::ContractId {
                self.contract_id.clone()
            }
            fn log_decoder(&self) -> ::fuels::core::codec::LogDecoder {
                self.log_decoder.clone()
            }
        }
        #[derive(Clone, Debug, Default)]
        pub struct MyContractConfigurables {
            offsets_with_data: ::std::vec::Vec<(u64, ::std::vec::Vec<u8>)>,
            encoder: ::fuels::core::codec::ABIEncoder,
        }
        impl MyContractConfigurables {
            pub fn new(encoder_config: ::fuels::core::codec::EncoderConfig) -> Self {
                Self {
                    encoder: ::fuels::core::codec::ABIEncoder::new(encoder_config),
                    ..::std::default::Default::default()
                }
            }
        }
        impl From<MyContractConfigurables> for ::fuels::core::Configurables {
            fn from(config: MyContractConfigurables) -> Self {
                ::fuels::core::Configurables::new(config.offsets_with_data)
            }
        }
    }
}
pub use abigen_bindings::my_contract_mod::MyContract;
pub use abigen_bindings::my_contract_mod::MyContractConfigurables;
pub use abigen_bindings::my_contract_mod::MyContractMethods;

```

> **Note:** that is all **generated** code. No need to write any of that. Ever. The generated code might look different from one version to another, this is just an example to give you an idea of what it looks like.

Then, you're able to use it to call the actual methods on the deployed contract:

```rust,ignore
        // This will generate your contract's methods onto `MyContract`.
        // This means an instance of `MyContract` will have access to all
        // your contract's methods that are running on-chain!
        // ANCHOR: abigen_example
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        // ANCHOR_END: abigen_example

        // This is an instance of your contract which you can use to make calls to your functions
        let contract_instance = MyContract::new(contract_id_2, wallet);

        let response = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .call() // Perform the network call
            .await?;

        assert_eq!(42, response.value);

        let response = contract_instance
            .methods()
            .increment_counter(10)
            .call()
            .await?;

        assert_eq!(52, response.value);
```


---

### File: docs/nightly/fuels-rs/docs/src/abigen/the-json-abi-file.md

# The JSON ABI file

<!-- This section should talk about the importance of the ABI -->
<!-- abi:example:start -->
Whether you want to deploy or connect to a pre-existing smart contract, the JSON ABI file is extremely important: it's what tells the SDK about the [ABI methods](https://docs.fuel.network/guides/quickstart/building-a-smart-contract/#abi) in your smart contracts.
<!-- abi:example:end -->

For the same example Sway code as above:

```Rust
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

The JSON ABI file looks like this:

```json
$ cat out/release/my-test-abi.json
[
  {
    "type": "function",
    "inputs": [],
    "name": "test_function",
    "outputs": [
      {
        "name": "",
        "type": "bool",
        "components": null
      }
    ]
  }
]
```

The Fuel Rust SDK will take this file as input and generate equivalent methods (and custom types if applicable) that you can call from your Rust code.


---

### File: docs/nightly/fuels-rs/docs/src/accounts.md

# Accounts

The `ViewOnlyAccount` trait provides a common interface to query balances.

The `Account` trait, in addition to the above, also provides a way to transfer assets. When performing actions in the SDK that lead to a transaction, you will typically need to provide an account that will be used to allocate resources required by the transaction, including transaction fees.

The traits are implemented by the following types:

- [`Wallet`](./wallets/index.md)
- [`Predicate`](./predicates/index.md)

## Transferring assets

An account implements the following methods for transferring assets:

- `transfer`
- `force_transfer_to_contract`
- `withdraw_to_base_layer`

The following examples are provided for a `Wallet` account. A `Predicate` account would work similarly, but you might need to set its predicate data before attempting to spend resources owned by it.

With `wallet.transfer` you can initiate a transaction to transfer an asset from your account to a target address.

```rust,ignore
        use fuels::prelude::*;

        // Setup 2 test wallets with 1 coin each.
        let num_wallets = 2;
        let coins_per_wallet = 1;
        let coin_amount = 2;

        let wallets = launch_custom_provider_and_get_wallets(
            WalletsConfig::new(Some(num_wallets), Some(coins_per_wallet), Some(coin_amount)),
            None,
            None,
        )
        .await?;

        // Transfer the base asset with amount 1 from wallet 1 to wallet 2.
        let transfer_amount = 1;
        let asset_id = Default::default();
        let _res = wallets[0]
            .transfer(
                wallets[1].address(),
                transfer_amount,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        let wallet_2_final_coins = wallets[1].get_coins(AssetId::zeroed()).await?;

        // Check that wallet 2 now has 2 coins.
        assert_eq!(wallet_2_final_coins.len(), 2);
```

You can transfer assets to a contract via `wallet.force_transfer_to_contract`.

```rust,ignore
        // Check the current balance of the contract with id 'contract_id'.
        let contract_balances = wallet
            .try_provider()?
            .get_contract_balances(&contract_id)
            .await?;
        assert!(contract_balances.is_empty());

        // Transfer an amount of 300 to the contract.
        let amount = 300;
        let asset_id = random_asset_id;
        let _res = wallet
            .force_transfer_to_contract(contract_id, amount, asset_id, TxPolicies::default())
            .await?;

        // Check that the contract now has 1 coin.
        let contract_balances = wallet
            .try_provider()?
            .get_contract_balances(&contract_id)
            .await?;
        assert_eq!(contract_balances.len(), 1);

        let random_asset_balance = contract_balances.get(&random_asset_id).unwrap();
        assert_eq!(*random_asset_balance, 300);
```

For transferring assets to the base layer chain, you can use `wallet.withdraw_to_base_layer`.

```rust,ignore
        use std::str::FromStr;

        use fuels::prelude::*;

        let wallets = launch_custom_provider_and_get_wallets(
            WalletsConfig::new(Some(1), None, None),
            None,
            None,
        )
        .await?;
        let wallet = wallets.first().unwrap();

        let amount = 1000;
        let base_layer_address = Address::from_str(
            "0x4710162c2e3a95a6faff05139150017c9e38e5e280432d546fae345d6ce6d8fe",
        )?;

        // Transfer an amount of 1000 to the specified base layer address.
        let response = wallet
            .withdraw_to_base_layer(base_layer_address, amount, TxPolicies::default())
            .await?;

        let _block_height = wallet.provider().produce_blocks(1, None).await?;

        // Retrieve a message proof from the provider.
        let proof = wallet
            .try_provider()?
            .get_message_proof(&response.tx_id, &response.nonce, None, Some(2))
            .await?;

        // Verify the amount and recipient.
        assert_eq!(proof.amount, amount);
        assert_eq!(proof.recipient, base_layer_address);
```

The above example creates an `Address` from a string. Next, it calls `wallet.withdraw_to_base_layer` by providing the address, the amount to be transferred, and the transaction policies. Lastly, to verify that the transfer succeeded, the relevant message proof is retrieved with `provider.get_message_proof,` and the amount and the recipient are verified.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/call-params.md

# Call parameters

<!-- This section should explain what the call params are and how to configure them -->
<!-- call_params:example:start -->
The parameters for a contract call are:

1. Amount
2. Asset ID
3. Gas forwarded
<!-- call_params:example:end -->

You can use these to forward coins to a contract. You can configure these parameters by creating an instance of [`CallParameters`](https://docs.rs/fuels/latest/fuels/programs/calls/struct.CallParameters.html) and passing it to a chain method called `call_params`.
<!-- use_call_params:example:end -->

For instance, suppose the following contract that uses Sway's `msg_amount()` to return the amount sent in that transaction.

```rust,ignore
    #[payable]
    fn get_msg_amount() -> u64 {
        msg_amount()
    }
```

Then, in Rust, after setting up and deploying the above contract, you can configure the amount being sent in the transaction like this:

```rust,ignore
        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();

        let tx_policies = TxPolicies::default();

        // Forward 1_000_000 coin amount of base asset_id
        // this is a big number for checking that amount can be a u64
        let call_params = CallParameters::default().with_amount(1_000_000);

        let response = contract_methods
            .get_msg_amount() // Our contract method.
            .with_tx_policies(tx_policies) // Chain the tx policies.
            .call_params(call_params)? // Chain the call parameters.
            .call() // Perform the contract call.
            .await?;
        let response = contract_methods
            .initialize_counter(42)
            .call_params(CallParameters::default())?
            .call()
            .await?;
```

<!-- This section should explain why `call_params` returns a result -->
<!-- payable:example:start -->
`call_params` returns a result to ensure you don't forward assets to a contract method that isn't payable.
<!-- payable:example:end -->
In the following example, we try to forward an amount of `100` of the base asset to `non_payable`. As its name suggests, `non_payable` isn't annotated with `#[payable]` in the contract code. Passing `CallParameters` with an amount other than `0` leads to an error:

```rust,ignore
    let err = contract_methods
        .non_payable()
        .call_params(CallParameters::default().with_amount(100))
        .expect_err("should return error");

    assert!(matches!(err, Error::Other(s) if s.contains("assets forwarded to non-payable method")));
```

> **Note:** forwarding gas to a contract call is always possible, regardless of the contract method being non-payable.

You can also use `CallParameters::default()` to use the default values:

```rust,ignore
pub const DEFAULT_CALL_PARAMS_AMOUNT: u64 = 0;
```

This way:

```rust,ignore
        let response = contract_methods
            .initialize_counter(42)
            .call_params(CallParameters::default())?
            .call()
            .await?;
```

<!-- This section should explain what the `gas_forwarded` parameter does -->
<!-- gas:example:start -->
The `gas_forwarded` parameter defines the limit for the actual contract call as opposed to the gas limit for the whole transaction. This means that it is constrained by the transaction limit. If it is set to an amount greater than the available gas, all available gas will be forwarded.
<!-- gas:example:end -->

```rust,ignore
        // Set the transaction `gas_limit` to 1_000_000 and `gas_forwarded` to 4300 to specify that
        // the contract call transaction may consume up to 1_000_000 gas, while the actual call may
        // only use 4300 gas
        let tx_policies = TxPolicies::default().with_script_gas_limit(1_000_000);
        let call_params = CallParameters::default().with_gas_forwarded(4300);

        let response = contract_methods
            .get_msg_amount() // Our contract method.
            .with_tx_policies(tx_policies) // Chain the tx policies.
            .call_params(call_params)? // Chain the call parameters.
            .call() // Perform the contract call.
            .await?;
```

<!-- This section should explain the default forwarding behavior for a call -->
<!-- forwarding:example:start -->
If you don't set the call parameters or use `CallParameters::default()`, the transaction gas limit will be forwarded instead.
<!-- forwarding:example:end -->


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/call-response.md

# Call response

<!-- This section should why you have to chain `.call().await.unwrap()` so often -->
<!-- chaining:example:start -->
You've probably noticed that you're often chaining `.call().await.unwrap()`. That's because:

1. You have to choose between `.call()` and `.simulate()` (more on this in the next section).
2. Contract calls are asynchronous, so you can choose to either `.await` it or perform concurrent tasks, making full use of Rust's async.
3. `.unwrap()` the `Result<CallResponse, Error>` returned by the contract call.
<!-- chaining:example:end -->

<!-- This section should preface what the `CallResponse` is -->
<!-- call_resp:example:start -->
Once you unwrap the `CallResponse`, you have access to this struct:
<!-- call_resp:example:end -->

```rust,ignore
pub struct CallResponse<D> {
    pub value: D,
    pub tx_status: Success,
    pub tx_id: Option<TxId>,
    pub log_decoder: LogDecoder,
}
```

<!-- This section should explain the fields of the `CallResponse` struct -->
<!-- call_resp_fields:example:start -->
Where `value` will hold the value returned by its respective contract method, represented by the exact type returned by the FuelVM, E.g., if your contract returns a FuelVM's `u64`, `value`'s `D` will be a `u64`. If it's a FuelVM's tuple `(u8,bool)`, then `D` will be a `(u8,bool)`. If it's a custom type, for instance, a Sway struct `MyStruct` containing two components, a `u64`, and a `b256`, `D` will be a struct generated at compile-time, called `MyStruct` with `u64` and a `[u8; 32]` (the equivalent of `b256` in Rust).

- `receipts` will hold all [receipts](https://docs.fuel.network/docs/specs/abi/receipts/) generated by that specific contract call.
- `gas_used` is the amount of gas consumed by the contract call.
- `tx_id` will hold the ID of the corresponding submitted transaction.
<!-- call_resp_fields:example:end -->

## Error handling

<!-- This section should explain how to use the `is_ok` and `is_err` methods for a call response -->
<!-- call_resp_ok:example:start -->
You can use the `is_ok` and `is_err` methods to check if a contract call `Result` is `Ok` or contains an error. These methods will return either `true` or `false`.
<!-- call_resp_ok:example:end -->

<!-- This section should show an example of how to use the `is_ok` and `is_err` methods for a call response -->
<!-- call_resp_ok_code:example:start -->
```rust, ignore
let is_ok = response.is_ok();
let is_error = response.is_err();
```
<!-- call_resp_ok_code:example:end -->

<!-- This section should explain how to use the `unwrap_err` method for a call response -->
<!-- call_resp_error:example:start -->
If `is_err` returns `true`, you can use the `unwrap_err` method to unwrap the error message.
<!-- call_resp_error:example:end -->

<!-- This section should show an example of how to unwrap a call response error -->
<!-- call_resp_error_code:example:start -->
```rust, ignore
if response.is_err() {
    let err = response.unwrap_err();
    println!("ERROR: {:?}", err);
};
```
<!-- call_resp_error_code:example:end -->


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/calls-with-different-wallets.md

# Calls with different wallets

<!-- This section should explain how to call a contract with a certain wallet -->
<!-- wallet:example:start -->
You can use the `with_account()` method on an existing contract instance as a shorthand for creating a new instance connected to the provided wallet. This lets you make contracts calls with different wallets in a chain like fashion.
<!-- wallet:example:end-->

```rust,ignore
        // Create contract instance with wallet_1
        let contract_instance = MyContract::new(contract_id, wallet_1.clone());

        // Perform contract call with wallet_2
        let response = contract_instance
            .with_account(wallet_2) // Connect wallet_2
            .methods() // Get contract methods
            .get_msg_amount() // Our contract method
            .call() // Perform the contract call.
            .await?; // This is an async call, `.await` for it.
```

> **Note:** connecting a different wallet to an existing instance ignores its set provider in favor of the provider used to deploy the contract. If you have two wallets connected to separate providers (each communicating with a separate fuel-core), the one assigned to the deploying wallet will also be used for contract calls. This behavior is only relevant if multiple providers (i.e. fuel-core instances) are present and can otherwise be ignored.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/cost-estimation.md

# Estimating contract call cost

With the function `estimate_transaction_cost(tolerance: Option<f64>, block_horizon: Option<u32>)` provided by `CallHandler`, you can get a cost estimation for a specific call. The return type, `TransactionCost`, is a struct that contains relevant information for the estimation:

```rust,ignore
pub struct TransactionCost {
    pub gas_price: u64,
    pub metered_bytes_size: u64,
    pub total_fee: u64,
    pub script_gas: u64,
    pub total_gas: u64,
}
```

> **Note** `script_gas` refers to the part of the gas spent on the script execution.

Below are examples that show how to get the estimated transaction cost from single and multi call transactions.

```rust,ignore
        let contract_instance = MyContract::new(contract_id, wallet);

        let tolerance = Some(0.0);
        let block_horizon = Some(1);
        let transaction_cost = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .estimate_transaction_cost(tolerance, block_horizon) // Get estimated transaction cost
            .await?;
```

```rust,ignore
        let call_handler_1 = contract_methods.initialize_counter(42);
        let call_handler_2 = contract_methods.get_array([42; 2]);

        let multi_call_handler = CallHandler::new_multi_call(wallet.clone())
            .add_call(call_handler_1)
            .add_call(call_handler_2);

        let tolerance = Some(0.0);
        let block_horizon = Some(1);
        let transaction_cost = multi_call_handler
            .estimate_transaction_cost(tolerance, block_horizon) // Get estimated transaction cost
            .await?;
```

The transaction cost estimation can be used to set the gas limit for an actual call, or to show the user the estimated cost.

> **Note** The same estimation interface is available for scripts.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/custom-asset-transfer.md

# Custom asset transfer

<!-- This section should explain the `add_custom_asset()` method -->
<!-- transfer:example:start -->
The SDK provides the option to transfer assets within the same transaction, when making a contract call. By using `add_custom_asset()` you specify the asset ID, the amount, and the destination address:
<!-- transfer:example:end -->

```rust,ignore
        let amount = 1000;
        let _ = contract_instance
            .methods()
            .initialize_counter(42)
            .add_custom_asset(AssetId::zeroed(), amount, Some(some_addr))
            .call()
            .await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/custom-inputs-outputs.md

# Custom inputs and outputs

If you need to add specific inputs and outputs to contract calls, you can use the `with_inputs` and `with_outputs` methods.

```rust,ignore
        let _ = contract_instance
            .methods()
            .initialize_counter(42)
            .with_inputs(custom_inputs)
            .with_outputs(custom_outputs)
            .add_signer(wallet_2.signer().clone())
            .call()
            .await?;
```

> **Note:** if custom inputs include coins that need to be signed, use the `add_signer` method to add the appropriate signer.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/index.md

# Calling contracts

Once you've deployed your contract, as seen in the previous sections, you'll likely want to:

1. Call contract methods;
2. Configure call parameters and transaction policies;
3. Forward coins and gas in your contract calls;
4. Read and interpret returned values and logs.

Here's an example. Suppose your Sway contract has two ABI methods called `initialize_counter(u64)` and `increment_counter(u64)`. Once you've deployed it the contract, you can call these methods like this:

```rust,ignore
        // This will generate your contract's methods onto `MyContract`.
        // This means an instance of `MyContract` will have access to all
        // your contract's methods that are running on-chain!
        // ANCHOR: abigen_example
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        // ANCHOR_END: abigen_example

        // This is an instance of your contract which you can use to make calls to your functions
        let contract_instance = MyContract::new(contract_id_2, wallet);

        let response = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .call() // Perform the network call
            .await?;

        assert_eq!(42, response.value);

        let response = contract_instance
            .methods()
            .increment_counter(10)
            .call()
            .await?;

        assert_eq!(52, response.value);
```

The example above uses all the default configurations and performs a simple contract call.

Furthermore, if you need to separate submission from value retrieval for any reason, you can do so as follows:

```rust,ignore
        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .submit()
            .await?;

        tokio::time::sleep(Duration::from_millis(500)).await;
        let value = response.response().await?.value;

```

Next, we'll see how we can further configure the many different parameters in a contract call.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/logs.md

# Logs

Whenever you log a value within a contract method, the resulting log entry is added to the log receipt and the variable type is recorded in the contract's ABI. The SDK lets you parse those values into Rust types.

Consider the following contract method:

```rust,ignore
    fn produce_logs_variables() {
        let f: u64 = 64;
        let u: b256 = 0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a;
        let e: str[4] = __to_str_array("Fuel");
        let l: [u8; 3] = [1u8, 2u8, 3u8];

        log(f);
        log(u);
        log(e);
        log(l);
    }
```

You can access the logged values in Rust by calling `decode_logs_with_type::<T>` from a `CallResponse`, where `T` is the type of the logged variables you want to retrieve. The result will be a `Vec<T>`:

```rust,ignore
    let contract_methods = contract_instance.methods();
    let response = contract_methods.produce_logs_variables().call().await?;

    let log_u64 = response.decode_logs_with_type::<u64>()?;
    let log_bits256 = response.decode_logs_with_type::<Bits256>()?;
    let log_string = response.decode_logs_with_type::<SizedAsciiString<4>>()?;
    let log_array = response.decode_logs_with_type::<[u8; 3]>()?;

    let expected_bits256 = Bits256([
        239, 134, 175, 169, 105, 108, 240, 220, 99, 133, 226, 196, 7, 166, 225, 89, 161, 16, 60,
        239, 183, 226, 174, 6, 54, 251, 51, 211, 203, 42, 158, 74,
    ]);

    assert_eq!(log_u64, vec![64]);
    assert_eq!(log_bits256, vec![expected_bits256]);
    assert_eq!(log_string, vec!["Fuel"]);
    assert_eq!(log_array, vec![[1, 2, 3]]);
```

You can use the `decode_logs()` function to retrieve a `LogResult` struct containing a `results` field that is a vector of `Result<String>` values representing the success or failure of decoding each log.

```rust, ignore
    let contract_methods = contract_instance.methods();
    let response = contract_methods.produce_multiple_logs().call().await?;
    let logs = response.decode_logs();
```

Due to possible performance hits, it is not recommended to use `decode_logs()` outside of a debugging scenario.

> **Note:** String slices cannot be logged directly. Use the `__to_str_array()` function to convert it to a `str[N]` first.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/low-level-calls.md

# Low-level calls

<!-- This section should explain what low-level calls are and how to do them -->
With low-level calls, you can specify the parameters of your calls at runtime and make indirect calls through other contracts.

Your caller contract should call `std::low_level_call::call_with_function_selector`, providing:

- target contract ID
- function selector encoded as `Bytes`
- calldata encoded as `Bytes`
- whether the calldata contains only a single value argument (e.g. a `u64`)
- `std::low_level_call::CallParams`

```rust,ignore
    fn call_low_level_call(
        target: ContractId,
        function_selector: Bytes,
        calldata: Bytes,
    ) {
        let call_params = CallParams {
            coins: 0,
            asset_id: AssetId::from(ZERO_B256),
            gas: 10_000,
        };

        call_with_function_selector(target, function_selector, calldata, call_params);
    }
```

On the SDK side, you can construct an encoded function selector using `fuels::core::encode_fn_selector`, and encoded calldata using the `fuels::core::calldata!` macro.

E.g. to call the following function on the target contract:

```rust,ignore
    #[storage(write)]
    fn set_value_multiple_complex(a: MyStruct, b: str[4]);
```

you would construct the function selector and the calldata as such, and provide them to the caller contract (like the one above):

```rust,ignore
        let function_selector = encode_fn_selector("set_value_multiple_complex");
        let call_data = calldata!(
            MyStruct {
                a: true,
                b: [1, 2, 3],
            },
            SizedAsciiString::<4>::try_from("fuel")?
        )?;

        caller_contract_instance
            .methods()
            .call_low_level_call(
                target_contract_instance.id(),
                Bytes(function_selector),
                Bytes(call_data),
            )
            .determine_missing_contracts()
            .await?
            .call()
            .await?;
```

> Note: the `calldata!` macro uses the default `EncoderConfig` configuration under the hood.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/multicalls.md

# Multiple contract calls

With `CallHandler`, you can execute multiple contract calls within a single transaction. To achieve this, you first prepare all the contract calls that you want to bundle:

```rust,ignore
        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();

        let call_handler_1 = contract_methods.initialize_counter(42);
        let call_handler_2 = contract_methods.get_array([42; 2]);
```

You can also set call parameters, variable outputs, or external contracts for every contract call, as long as you don't execute it with `call()` or `simulate()`.

> **Note:** if custom inputs or outputs have been added to the separate calls, the input and output order will follow the order how the calls are added to the multi-call.

Next, you provide the prepared calls to your `CallHandler` and optionally configure transaction policies:

```rust,ignore
        let multi_call_handler = CallHandler::new_multi_call(wallet.clone())
            .add_call(call_handler_1)
            .add_call(call_handler_2)
            .with_tx_policies(TxPolicies::default());
```

> **Note:** any transaction policies configured on separate contract calls are disregarded in favor of the parameters provided to the multi-call `CallHandler`.

Furthermore, if you need to separate submission from value retrieval for any reason, you can do so as follows:

```rust,ignore
        let submitted_tx = multi_call_handler.submit().await?;
        tokio::time::sleep(Duration::from_millis(500)).await;
        let (counter, array): (u64, [u64; 2]) = submitted_tx.response().await?.value;
```

## Output values

To get the output values of the bundled calls, you need to provide explicit type annotations when saving the result of `call()` or `simulate()` to a variable:

```rust,ignore
        let (counter, array): (u64, [u64; 2]) = multi_call_handler.call().await?.value;
```

You can also interact with the `CallResponse` by moving the type annotation to the invoked method:

```rust,ignore
        let response = multi_call_handler.call::<(u64, [u64; 2])>().await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/other-contracts.md

# Calling other contracts

If your contract method is calling other contracts you will have to add the appropriate `Inputs` and `Outputs` to your transaction. For your convenience, the `CallHandler` provides methods that prepare those inputs and outputs for you. You have two methods that you can use: `with_contracts(&[&contract_instance, ...])` and `with_contract_ids(&[&contract_id, ...])`.

`with_contracts(&[&contract_instance, ...])` requires contract instances that were created using the `abigen` macro. When setting the external contracts with this method, logs and require revert errors originating from the external contract can be propagated and decoded by the calling contract.

```rust,ignore
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contracts(&[&lib_contract_instance])
        .call()
        .await?;
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contract_ids(&[lib_contract_id])
        .call()
        .await?;
```

 If however, you do not need to decode logs or you do not have a contract instance that was generated using the `abigen` macro you can use `with_contract_ids(&[&contract_id, ...])` and provide the required contract ids.

```rust,ignore
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contract_ids(&[lib_contract_id])
        .call()
        .await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/simulation.md

# Simulating calls

Sometimes you want to simulate a call to a contract without changing the state of the blockchain. This can be achieved by calling `.simulate` instead of `.call` and passing in the desired execution context:

* `.simulate(Execution::realistic())` simulates the transaction in a manner that closely resembles a real call. You need a wallet with base assets to cover the transaction cost, even though no funds will be consumed. This is useful for validating that a real call would succeed if made at that moment. It allows you to debug issues with your contract without spending gas.

```rust,ignore
        // you would mint 100 coins if the transaction wasn't simulated
        let counter = contract_methods
            .mint_coins(100)
            .simulate(Execution::realistic())
            .await?;
            // you don't need any funds to read state
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only())
                .await?
                .value;
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only().at_height(block_height))
                .await?
                .value;
```

* `.simulate(Execution::state_read_only())` disables many validations, adds fake gas, extra variable outputs, blank witnesses, etc., enabling you to read state even with an account that has no funds.

```rust,ignore
            // you don't need any funds to read state
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only())
                .await?
                .value;
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only().at_height(block_height))
                .await?
                .value;
```

If the node supports historical execution (the node is using `rocksdb` and the `historical_execution` flag has been set), then both execution types can be chained with `at_height` to simulate the call at a specific block height.

```rust,ignore
            let balance = contract_methods
                .get_balance(contract_id, AssetId::zeroed())
                .simulate(Execution::state_read_only().at_height(block_height))
                .await?
                .value;
```


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/tx-dependency-estimation.md

# Transaction dependency estimation

Previously, we mentioned that a contract call might require you to manually specify external contracts, variable outputs, or output messages. The SDK can also attempt to estimate and set these dependencies for you at the cost of running multiple simulated calls in the background.

The following example uses a contract call that calls an external contract and later mints assets to a specified address. Calling it without including the dependencies will result in a revert:

```rust,ignore
        let address = wallet.address();
        let amount = 100;

        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .call()
            .await;

        assert!(matches!(
            response,
            Err(Error::Transaction(Reason::Failure { .. }))
        ));
```

As mentioned in previous chapters, you can specify the external contract and add an output variable to resolve this:

```rust,ignore
        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .with_contract_ids(&[called_contract_id])
            .call()
            .await?;
```

But this requires you to know the contract ID of the external contract and the needed number of output variables. Alternatively, by chaining

- `.with_variable_output_policy(VariableOutputPolicy::EstimateMinimum)` and
- `.determine_missing_contracts()`

the dependencies will be estimated by the SDK and set automatically.

```rust,ignore
        let address = wallet.address();
        let amount = 100;

        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .call()
            .await;

        assert!(matches!(
            response,
            Err(Error::Transaction(Reason::Failure { .. }))
        ));
        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .with_contract_ids(&[called_contract_id])
            .call()
            .await?;
        let response = contract_methods
            .mint_then_increment_from_contract(called_contract_id, amount, address.into())
            .with_variable_output_policy(VariableOutputPolicy::EstimateMinimum)
            .determine_missing_contracts()
            .await?
            .call()
            .await?;
```

> **Note:** Both `with_variable_output_policy` and `determine_missing_contracts` can also be used when working with script calls or multi calls. `determine_missing_contracts()` will not enable logging from an external contract. For more information, see [here](./other-contracts.md).


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/tx-policies.md

# Transaction policies

<!-- This section should explain what tx policies are and how to configure them -->
<!-- tx_policies:example:start -->
Transaction policies are defined as follows:

```rust,ignore
pub struct TxPolicies {
    tip: Option<u64>,
    witness_limit: Option<u64>,
    maturity: Option<u64>,
    expiration: Option<u64>,
    max_fee: Option<u64>,
    script_gas_limit: Option<u64>,
}
```

Where:

1. **Tip** - amount to pay the block producer to prioritize the transaction.
2. **Witness Limit** - The maximum amount of witness data allowed for the transaction.
3. **Maturity** - Block until which the transaction cannot be included.
4. **Expiration** - Block after which the transaction cannot be included.
5. **Max Fee** - The maximum fee payable by this transaction.
6. **Script Gas Limit** - The maximum amount of gas the transaction may consume for executing its script code.

When the **Script Gas Limit** is not set, the Rust SDK will estimate the consumed gas in the background and set it as the limit.

If the **Witness Limit** is not set, the SDK will set it to the size of all witnesses and signatures defined in the transaction builder.

You can configure these parameters by creating an instance of `TxPolicies` and passing it to a chain method called `with_tx_policies`:
<!-- tx_policies:example:end-->

```rust,ignore
        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();

        let tx_policies = TxPolicies::default()
            .with_tip(1)
            .with_script_gas_limit(1_000_000)
            .with_maturity(0)
            .with_expiration(10_000);

        let response = contract_methods
            .initialize_counter(42) // Our contract method
            .with_tx_policies(tx_policies) // Chain the tx policies
            .call() // Perform the contract call
            .await?; // This is an async call, `.await` it.
        let response = contract_methods
            .initialize_counter(42)
            .with_tx_policies(TxPolicies::default())
            .call()
            .await?;
```

<!-- This section should explain how to use the default tx policy -->
<!-- tx_policies_default:example:start -->
You can also use `TxPolicies::default()` to use the default values.
<!-- tx_policies_default:example:end -->

This way:

```rust,ignore
        let response = contract_methods
            .initialize_counter(42)
            .with_tx_policies(TxPolicies::default())
            .call()
            .await?;
```

As you might have noticed, `TxPolicies` can also be specified when deploying contracts or transferring assets by passing it to the respective methods.


---

### File: docs/nightly/fuels-rs/docs/src/calling-contracts/variable-outputs.md

# Output variables

<!-- This section should explain variable outputs  -->
<!-- variable_outputs:example:start -->
Sometimes, the contract you call might transfer funds to a specific address, depending on its execution. The underlying transaction for such a contract call has to have the appropriate number of [variable outputs](https://docs.fuel.network/docs/specs/tx-format/output/#outputvariable) to succeed.
<!-- variable_outputs:example:end -->

Let's say you deployed a contract with the following method:

```rust,ignore
    fn transfer(coins: u64, asset_id: AssetId, recipient: Identity) {
        transfer(recipient, asset_id, coins);
    }
```

When calling `transfer_coins_to_output` with the SDK, you can specify the number of variable outputs:

```rust,ignore
        let address = wallet.address();
        let asset_id = contract_id.asset_id(&SubAssetId::zeroed());

        // withdraw some tokens to wallet
        let response = contract_methods
            .transfer(1_000_000, asset_id, address.into())
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .call()
            .await?;
```

<!-- This section should explain what the `with_variable_output_policy` method does -->
<!-- with_variable_output_policy:example:start -->
`with_variable_output_policy` sets the policy regarding variable outputs. You can either set the number of variable outputs yourself by providing `VariableOutputPolicy::Exactly(n)` or let the SDK estimate it for you with `VariableOutputPolicy::EstimateMinimum`. A variable output indicates that the amount and the owner may vary based on transaction execution.
<!-- with_variable_output_policy:example:end -->

> **Note:** that the Sway `lib-std` function `mint_to_address` calls `transfer_to_address` under the hood, so you need to call `with_variable_output_policy` in the Rust SDK tests like you would for `transfer_to_address`.


---

### File: docs/nightly/fuels-rs/docs/src/cli/fuels-abi-cli.md

# `fuels-abi-cli`

Simple CLI program to encode Sway function calls and decode their output. The ABI being encoded and decoded is specified [here](https://docs.fuel.network/docs/specs/abi/).

## Usage

```plaintext
sway-abi-cli 0.1.0
FuelVM ABI coder

USAGE:
    sway-abi-cli <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    codegen   Output Rust types file
    decode    Decode ABI call result
    encode    Encode ABI call
    help      Prints this message or the help of the given subcommand(s)
```

## Examples

You can choose to encode only the given params or you can go a step further and have a full JSON ABI file and encode the whole input to a certain function call defined in the JSON file.

### Encoding params only

```console
$ cargo run -- encode params -v bool true
0000000000000001
```

```console
$ cargo run -- encode params -v bool true -v u32 42 -v u32 100
0000000000000001000000000000002a0000000000000064
```

Note that for every parameter you want to encode, you must pass a `-v` flag followed by the type, and then the value: `-v <type_1> <value_1> -v <type_2> <value_2> -v <type_n> <value_n>`

### Encoding function call

`example/simple.json`:

```json
[
  {
    "type":"function",
    "inputs":[
      {
        "name":"arg",
        "type":"u32"
      }
    ],
    "name":"takes_u32_returns_bool",
    "outputs":[
      {
        "name":"",
        "type":"bool"
      }
    ]
  }
]
```

```console
$ cargo run -- encode function examples/simple.json takes_u32_returns_bool -p 4
000000006355e6ee0000000000000004
```

`example/array.json`

```json
[
  {
    "type":"function",
    "inputs":[
      {
        "name":"arg",
        "type":"u16[3]"
      }
    ],
    "name":"takes_array",
    "outputs":[
      {
        "name":"",
        "type":"u16[2]"
      }
    ]
  }
]
```

```console
$ cargo run -- encode function examples/array.json takes_array -p '[1,2]'
00000000f0b8786400000000000000010000000000000002
```

Note that the first word (8 bytes) of the output is reserved for the function selector, which is captured in the last 4 bytes, which is simply the 256hash of the function signature.

Example with nested struct:

```json
[
  {
    "type":"contract",
    "inputs":[
      {
        "name":"MyNestedStruct",
        "type":"struct",
        "components":[
          {
            "name":"x",
            "type":"u16"
          },
          {
            "name":"y",
            "type":"struct",
            "components":[
              {
                "name":"a",
                "type":"bool"
              },
              {
                "name":"b",
                "type":"u8[2]"
              }
            ]
          }
        ]
      }
    ],
    "name":"takes_nested_struct",
    "outputs":[

    ]
  }
]
```

```console
$ cargo run -- encode function examples/nested_struct.json takes_nested_struct -p '(10, (true, [1,2]))'
00000000e8a04d9c000000000000000a000000000000000100000000000000010000000000000002
```

### Decoding params only

Similar to encoding parameters only:

```console
$ cargo run -- decode params -t bool -t u32 -t u32 0000000000000001000000000000002a0000000000000064
Bool(true)
U32(42)
U32(100)
```

### Decoding function output

```console
$ cargo run -- decode function examples/simple.json takes_u32_returns_bool 0000000000000001
Bool(true)
```


---

### File: docs/nightly/fuels-rs/docs/src/cli/index.md

# `fuels-rs` Rust Workspaces

This section gives you a little overview of the role and function of every workspace in the `fuels-rs` repository.

- [`fuels-abi-cli`](./fuels-abi-cli.md)


---

### File: docs/nightly/fuels-rs/docs/src/codec/decoding.md

# Decoding

Be sure to read the [prerequisites](./index.md#prerequisites-for-decodingencoding) to decoding.

Decoding is done via the [`ABIDecoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIDecoder.html):

```rust,ignore
        use fuels::{
            core::{
                codec::ABIDecoder,
                traits::{Parameterize, Tokenizable},
            },
            macros::{Parameterize, Tokenizable},
            types::Token,
        };

        #[derive(Parameterize, Tokenizable)]
        struct MyStruct {
            field: u64,
        }

        let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];

        let token: Token = ABIDecoder::default().decode(&MyStruct::param_type(), bytes)?;

        let _: MyStruct = MyStruct::from_token(token)?;
        use fuels::macros::{Parameterize, Tokenizable, TryFrom};

        #[derive(Parameterize, Tokenizable, TryFrom)]
        struct MyStruct {
            field: u64,
        }

        let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];

        let _: MyStruct = bytes.try_into()?;
```

First into a [`Token`](https://docs.rs/fuels/latest/fuels/types/enum.Token.html), then via the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) trait, into the desired type.

If the type came from [`abigen!`](../abigen/index.md) (or uses the [`::fuels::macros::TryFrom`](https://docs.rs/fuels/latest/fuels/macros/derive.TryFrom.html) derivation) then you can also use `try_into` to convert bytes into a type that implements both [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) and [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html):

```rust,ignore
        use fuels::macros::{Parameterize, Tokenizable, TryFrom};

        #[derive(Parameterize, Tokenizable, TryFrom)]
        struct MyStruct {
            field: u64,
        }

        let bytes: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 101];

        let _: MyStruct = bytes.try_into()?;
```

Under the hood, [`try_from_bytes`](https://docs.rs/fuels/latest/fuels/core/codec/fn.try_from_bytes.html) is being called, which does what the preceding example did.

## Configuring the decoder

The decoder can be configured to limit its resource expenditure:

```rust,ignore

        use fuels::core::codec::ABIDecoder;

        ABIDecoder::new(DecoderConfig {
            max_depth: 5,
            max_tokens: 100,
        });
```

<!-- TODO: Add a link once a release is made -->
<!-- https://docs.rs/fuels/latest/fuels/core/codec/struct.DecoderConfig.html -->
For an explanation of each configuration value visit the `DecoderConfig`.

<!-- TODO: add a link once a release is made -->
<!-- https://docs.rs/fuels/latest/fuels/core/codec/struct.DecoderConfig.html -->
The default values for the `DecoderConfig` are:

```rust,ignore
impl Default for DecoderConfig {
    fn default() -> Self {
        Self {
            max_depth: 45,
            max_tokens: 10_000,
        }
    }
}
```

## Configuring the decoder for contract/script calls

You can also configure the decoder used to decode the return value of the contract method:

```rust,ignore
        let _ = contract_instance
            .methods()
            .initialize_counter(42)
            .with_decoder_config(DecoderConfig {
                max_depth: 10,
                max_tokens: 2_000,
            })
            .call()
            .await?;
```

The same method is available for script calls.


---

### File: docs/nightly/fuels-rs/docs/src/codec/encoding.md

# Encoding

Be sure to read the [prerequisites](./index.md#prerequisites-for-decodingencoding) to encoding.

Encoding is done via the [`ABIEncoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIEncoder.html):

```rust,ignore
        use fuels::{
            core::{codec::ABIEncoder, traits::Tokenizable},
            macros::Tokenizable,
        };

        #[derive(Tokenizable)]
        struct MyStruct {
            field: u64,
        }

        let instance = MyStruct { field: 101 };
        let _encoded: Vec<u8> = ABIEncoder::default().encode(&[instance.into_token()])?;
        use fuels::{core::codec::calldata, macros::Tokenizable};

        #[derive(Tokenizable)]
        struct MyStruct {
            field: u64,
        }
        let _: Vec<u8> = calldata!(MyStruct { field: 101 }, MyStruct { field: 102 })?;
```

There is also a shortcut-macro that can encode multiple types which implement [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html):

```rust,ignore
        use fuels::{core::codec::calldata, macros::Tokenizable};

        #[derive(Tokenizable)]
        struct MyStruct {
            field: u64,
        }
        let _: Vec<u8> = calldata!(MyStruct { field: 101 }, MyStruct { field: 102 })?;
```

## Configuring the encoder

The encoder can be configured to limit its resource expenditure:

```rust,ignore
        use fuels::core::codec::ABIEncoder;

        ABIEncoder::new(EncoderConfig {
            max_depth: 5,
            max_tokens: 100,
        });
```

The default values for the `EncoderConfig` are:

```rust,ignore
impl Default for EncoderConfig {
    fn default() -> Self {
        Self {
            max_depth: 45,
            max_tokens: 10_000,
        }
    }
}
```

## Configuring the encoder for contract/script calls

You can also configure the encoder used to encode the arguments of the contract method:

```rust,ignore
        let _ = contract_instance
            .with_encoder_config(EncoderConfig {
                max_depth: 10,
                max_tokens: 2_000,
            })
            .methods()
            .initialize_counter(42)
            .call()
            .await?;
```

The same method is available for script calls.


---

### File: docs/nightly/fuels-rs/docs/src/codec/index.md

# Codec

Encoding and decoding are done as per [the fuel spec](https://docs.fuel.network/docs/specs/abi/argument-encoding/). To this end, `fuels` makes use of the [`ABIEncoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIEncoder.html) and the [`ABIDecoder`](https://docs.rs/fuels/latest/fuels/core/codec/struct.ABIDecoder.html).

## Prerequisites for decoding/encoding

To encode a type, you must first convert it into a [`Token`](https://docs.rs/fuels/latest/fuels/types/enum.Token.html). This is commonly done by implementing the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) trait.

To decode, you also need to provide a [`ParamType`](https://docs.rs/fuels/latest/fuels/types/param_types/enum.ParamType.html) describing the schema of the type in question. This is commonly done by implementing the [Parameterize](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) trait.

All types generated by the [`abigen!`](../abigen/index.md) macro implement both the [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) and [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) traits.

`fuels` also contains implementations for:

- [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) for the `fuels`-owned types listed [here](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html#implementers) as well as [for some foreign types](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html#foreign-impls) (such as `u8`, `u16`, `std::vec::Vec<T: Tokenizable>`, etc.).
- [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) for the `fuels`-owned types listed [here](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html#implementers) as well as [for some foreign types](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html#foreign-impls) (such as `u8`, `u16`, `std::vec::Vec<T: Parameterize>`, etc.).

## Deriving the traits

Both [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) and [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html) can be derived for `struct`s and `enum`s if all inner types implement the derived traits:

```rust,ignore
        use fuels::macros::{Parameterize, Tokenizable};

        #[derive(Parameterize, Tokenizable)]
        struct MyStruct {
            field_a: u8,
        }

        #[derive(Parameterize, Tokenizable)]
        enum SomeEnum {
            A(MyStruct),
            B(Vec<u64>),
        }
            #[derive(Parameterize, Tokenizable)]
            #[FuelsCorePath = "fuels_core_elsewhere"]
            #[FuelsTypesPath = "fuels_types_elsewhere"]
            pub struct SomeStruct {
                field_a: u64,
            }
            use fuels::macros::{Parameterize, Tokenizable};
            #[derive(Parameterize, Tokenizable)]
            #[NoStd]
            pub struct SomeStruct {
                field_a: u64,
            }
```

> Note:
> Deriving [`Tokenizable`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Tokenizable.html) on `enum`s requires that all variants also implement [`Parameterize`](https://docs.rs/fuels/latest/fuels/core/traits/trait.Parameterize.html).

### Tweaking the derivation

#### Changing the location of imports

The derived code expects that the `fuels` package is accessible through `::fuels`. If this is not the case then the derivation macro needs to be given the locations of `fuels::types` and `fuels::core`.

```rust,ignore
            #[derive(Parameterize, Tokenizable)]
            #[FuelsCorePath = "fuels_core_elsewhere"]
            #[FuelsTypesPath = "fuels_types_elsewhere"]
            pub struct SomeStruct {
                field_a: u64,
            }
```

#### Generating no-std code

If you want `no-std` generated code:

```rust,ignore
            use fuels::macros::{Parameterize, Tokenizable};
            #[derive(Parameterize, Tokenizable)]
            #[NoStd]
            pub struct SomeStruct {
                field_a: u64,
            }
```


---

### File: docs/nightly/fuels-rs/docs/src/connecting/external-node.md

# Connecting to the Testnet or an external node

We can interact with the `Testnet` node by using the following example.

```rust,ignore
        use std::str::FromStr;

        use fuels::{crypto::SecretKey, prelude::*};

        // Create a provider pointing to the testnet.
        let provider = Provider::connect("testnet.fuel.network").await.unwrap();

        // Setup a private key
        let secret = SecretKey::from_str(
            "a1447cd75accc6b71a976fd3401a1f6ce318d27ba660b0315ee6ac347bf39568",
        )?;

        // Create the wallet
        let wallet = Wallet::new(PrivateKeySigner::new(secret), provider);

        // Get the wallet address. Used later with the faucet
        dbg!(wallet.address().to_string());
```
>
> For detailed information about various testnet networks and their optimal toolchain configurations for your project, please visit the following link:
>
> [networks](https://fuelbook.fuel.network/master/networks/networks.html)

In the code example, we connected a new provider to the Testnet node and created a new wallet from a private key.

> **Note:** New wallets on the Testnet will not have any assets! They can be obtained by providing the wallet address to the faucet at
>
>[faucet-testnet.fuel.network](https://faucet-testnet.fuel.network)
>
> Once the assets have been transferred to the wallet, you can reuse it in other tests by providing the private key!
>
> In addition to the faucet, there is a block explorer for the Testnet at
>
> [block-explorer](https://fuellabs.github.io/block-explorer-v2)

If you want to connect to another node just change the URL or IP and port. For example, to connect to a local node that was created with `fuel-core` you can use:

```rust,ignore
        let _provider = Provider::connect(format!("127.0.0.1:{port}")).await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/connecting/index.md

# Connecting to a Fuel node

<!-- This section should explain at a high level the main ways to connect to a node with the Rust SDK and when they are appropriate to use-->
<!-- rs_node:example:start -->
At a high level, you can use the Fuel Rust SDK to build Rust-based applications that can run computations on the Fuel Virtual Machine through interactions with smart contracts written in Sway.

For this interaction to work, the SDK must be able to communicate with a `fuel-core` node; you have two options at your disposal:

1. Use the testnet or run a Fuel node (using `fuel-core`) and instantiate a provider that points to that node's IP and port.
2. Use the SDK's native `launch_provider_and_get_wallet()` that runs a short-lived test Fuel node;

The second option is ideal for smart contract testing, as you can quickly spin up and tear down nodes between specific test cases.

For application building, you should use the first option.
<!-- rs_node:example:end -->


---

### File: docs/nightly/fuels-rs/docs/src/connecting/querying.md

# Querying the blockchain

Once you set up a provider, you can interact with the Fuel blockchain. Here are a few examples of what you can do with a provider; for a more in-depth overview of the API, check the [official provider API documentation](https://docs.rs/fuels/latest/fuels/accounts/provider/struct.Provider.html).

- [Set up](#set-up)
- [Get all coins from an address](#get-all-coins-from-an-address)
- [Get spendable resources owned by an address](#get-spendable-resources-owned-by-an-address)
- [Get balances from an address](#get-balances-from-an-address)

## Set up

You might need to set up a test blockchain first. You can skip this step if you're connecting to an external blockchain.

```rust,ignore
        use fuels::prelude::*;

        // Set up our test blockchain.

        // Create a random signer
        // ANCHOR: setup_single_asset
        let wallet_signer = PrivateKeySigner::random(&mut rand::thread_rng());

        // How many coins in our wallet.
        let number_of_coins = 1;

        // The amount/value in each coin in our wallet.
        let amount_per_coin = 3;

        let coins = setup_single_asset_coins(
            wallet_signer.address(),
            AssetId::zeroed(),
            number_of_coins,
            amount_per_coin,
        );
        // ANCHOR_END: setup_single_asset

        // ANCHOR: configure_retry
        let retry_config = RetryConfig::new(3, Backoff::Fixed(Duration::from_secs(2)))?;
        let provider = setup_test_provider(coins.clone(), vec![], None, None)
            .await?
            .with_retry_config(retry_config);
        // ANCHOR_END: configure_retry
```

## Get all coins from an address

This method returns all unspent coins (of a given asset ID) from a wallet.

```rust,ignore
        let consensus_parameters = provider.consensus_parameters().await?;
        let coins = provider
            .get_coins(
                &wallet_signer.address(),
                *consensus_parameters.base_asset_id(),
            )
            .await?;
        assert_eq!(coins.len(), 1);
```

## Get spendable resources owned by an address

The following example shows how to fetch resources owned by an address. First, you create a  `ResourceFilter` which specifies the target address, asset ID, and amount. You can also define UTXO IDs and message IDs that should be excluded when retrieving the resources:

```rust,ignore
pub struct ResourceFilter {
    pub from: Address,
    pub asset_id: Option<AssetId>,
    pub amount: u128,
    pub excluded_utxos: Vec<UtxoId>,
    pub excluded_message_nonces: Vec<Nonce>,
}
```

The example uses default values for the asset ID and the exclusion lists. This resolves to the base asset ID and empty vectors for the ID lists respectively:

```rust,ignore
        let filter = ResourceFilter {
            from: wallet_signer.address(),
            amount: 1,
            ..Default::default()
        };
        let spendable_resources = provider.get_spendable_resources(filter).await?;
        assert_eq!(spendable_resources.len(), 1);
```

## Get balances from an address

Get all the spendable balances of all assets for an address. This is different from getting the coins because we only return the numbers (the sum of UTXOs coins amount for each asset ID) and not the UTXOs coins themselves.

```rust,ignore
        let _balances = provider.get_balances(&wallet_signer.address()).await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/connecting/retrying.md

# Retrying requests

The [`Provider`](https://docs.rs/fuels/0.62.0/fuels/accounts/provider/struct.Provider.html) can be configured to retry a request upon receiving a `io::Error`.

> Note: Currently all node errors are received as `io::Error`s. So, if configured, a retry will happen even if, for example, a transaction failed to verify.

We can configure the number of retry attempts and the retry strategy as detailed below.

## `RetryConfig`

The retry behavior can be altered by giving a custom `RetryConfig`. It allows for configuring the maximum number of attempts and the interval strategy used.

```rust, ignore
#[derive(Clone, Debug)]
pub struct RetryConfig {
    max_attempts: NonZeroU32,
    interval: Backoff,
}
```

```rust, ignore
        let retry_config = RetryConfig::new(3, Backoff::Fixed(Duration::from_secs(2)))?;
        let provider = setup_test_provider(coins.clone(), vec![], None, None)
            .await?
            .with_retry_config(retry_config);
```

## Interval strategy - `Backoff`

`Backoff` defines different strategies for managing intervals between retry attempts.
Each strategy allows you to customize the waiting time before a new attempt based on the number of attempts made.

### Variants

- `Linear(Duration)`: `Default` Increases the waiting time linearly with each attempt.
- `Exponential(Duration)`: Doubles the waiting time with each attempt.
- `Fixed(Duration)`: Uses a constant waiting time between attempts.

```rust, ignore
#[derive(Debug, Clone)]
pub enum Backoff {
    Linear(Duration),
    Exponential(Duration),
    Fixed(Duration),
}
```


---

### File: docs/nightly/fuels-rs/docs/src/connecting/rocksdb.md

# RocksDB

RocksDB enables the preservation of the blockchain's state locally, facilitating its future utilization.

To create or use a local database, follow these instructions:

```rust,ignore
        let provider_config = NodeConfig {
            database_type: DbType::RocksDb(Some(PathBuf::from("/tmp/.spider/db"))),
            ..NodeConfig::default()
        };
```

> Note: If the specified database does not exist, a new database will be created at that path. To utilize the code snippets above, either the `fuel-core` binary must be present, or both the `fuel-core-lib` and `rocksdb` features need to be enabled.


---

### File: docs/nightly/fuels-rs/docs/src/connecting/short-lived.md

# Running a short-lived Fuel node with the SDK

You can use the SDK to spin up a local, ideally short-lived Fuel node. Then, you can instantiate a Fuel client, pointing to this node.

```rust,ignore
        use fuels::prelude::{FuelService, Provider};

        // Run the fuel node.
        let server = FuelService::start(
            NodeConfig::default(),
            ChainConfig::default(),
            StateConfig::default(),
        )
        .await?;

        // Create a client that will talk to the node created above.
        let client = Provider::from(server.bound_address()).await?;
        assert!(client.healthy().await?);
```

This approach is ideal for contract testing.

You can also use the test helper `setup_test_provider()` for this:

```rust,ignore
        use fuels::prelude::*;

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Create the wallet.
        let _wallet = Wallet::random(&mut thread_rng(), provider);
```

You can also use `launch_provider_and_get_wallet()`, which abstracts away the `setup_test_provider()` and the wallet creation, all in one single method:

```rust,ignore
let wallet = launch_provider_and_get_wallet().await?;
```

## Features

### Fuel-core lib

The `fuel-core-lib` feature allows us to run a `fuel-core` node without installing the `fuel-core` binary on the local machine. Using the `fuel-core-lib` feature flag entails downloading all the dependencies needed to run the fuel-core node.

```rust,ignore
fuels = { version = "0.75.0", features = ["fuel-core-lib"] }
```

### RocksDB

The `rocksdb` is an additional feature that, when combined with `fuel-core-lib`, provides persistent storage capabilities while using `fuel-core` as a library.

```rust,ignore
fuels = { version = "0.75.0", features = ["rocksdb"] }
```


---

### File: docs/nightly/fuels-rs/docs/src/contributing/CONTRIBUTING.md

# Contributing to the Fuel Rust SDK

Thanks for your interest in contributing to the Fuel Rust SDK!

This document outlines the process for installing dependencies, setting up for development, and conventions for contributing.`

If you run into any difficulties getting started, you can always ask questions on our [Discourse](https://forum.fuel.network/).

## Finding something to work on

You may contribute to the project in many ways, some of which involve coding knowledge and some which do not. A few examples include:

- Reporting bugs
- Adding new features or bug fixes for which there is already an open issue
- Making feature requests

Check out our [Help Wanted](https://github.com/FuelLabs/fuels-rs/labels/help%20wanted) or [Good First Issues](https://github.com/FuelLabs/fuels-rs/labels/good%20first%20issue) to find a suitable task.

If you are planning something big, for example, changes related to multiple components or changes to current behaviors, make sure to [open an issue](https://github.com/FuelLabs/fuels-rs/issues/new) to discuss with us before starting on the implementation.

## Contribution flow

This is a rough outline of what a contributor's workflow looks like:

- Make sure what you want to contribute is already tracked as an issue.
  - We may discuss the problem and solution in the issue.
- Create a Git branch from where you want to base your work. This is usually master.
- Write code, add test cases, and commit your work.
- Run tests and make sure all tests pass.
- Add the breaking label to your PR if the PR contains any breaking changes.
- Push your changes to a branch in your fork of the repository and submit a pull request.
  - Make sure to mention the issue created in step 1 in the commit message.
- Your PR will be reviewed, and some changes may be requested.
  - Your PR must be re-reviewed and approved once you've made changes.
  - Use GitHub's 'update branch' button if the PR becomes outdated.
  - If there are conflicts, you can merge and resolve them locally. Then push to your PR branch. Any changes to the branch will require a re-review.
- Our CI system (Github Actions) automatically tests all authorized pull requests.
- Use GitHub to merge the PR once approved.

Thanks for your contributions!

## Linking issues

Pull requests should be linked to at least one issue in the same repo.

If the pull request resolves the relevant issues, and you want GitHub to close these issues automatically after it merged into the default branch, you can use the syntax (`KEYWORD #ISSUE-NUMBER`) like this:

```sh
close #123
```

If the pull request links an issue but does not close it, you can use the keyword `ref` like this:

```sh
ref #456
```

Multiple issues should use full syntax for each issue and be separated by a comma, like:

```sh
close #123, ref #456
```


---

### File: docs/nightly/fuels-rs/docs/src/contributing/tests-structure.md

# Integration tests structure in `fuels-rs`

The integration tests of `fuels-rs` cover almost all aspects of the SDK and have grown significantly as more functionality was added. To make the tests and associated `Sway` projects more manageable they were split into several categories. A category consist of a `.rs` file for the tests and, if needed, a separate directory for the `Sway` projects.

Currently have the following structure:

```shell
  .
  ├─  bindings/
  ├─  contracts/
  ├─  logs/
  ├─  predicates/
  ├─  storage/
  ├─  types/
  ├─  bindings.rs
  ├─  contracts.rs
  ├─  from_token.rs
  ├─  logs.rs
  ├─  predicates.rs
  ├─  providers.rs
  ├─  scripts.rs
  ├─  storage.rs
  ├─  types.rs
  └─  wallets.rs
```

Even though test organization is subjective, please consider these guidelines before adding a new category:

- Add a new category when creating a new section in the `Fuels Rust SDK` book - e.g. `Types`
- Add a new category if there are more than 3 test and more than 100 lines of code and they form a group of tests - e.g. `storage.rs`

 Otherwise, we recommend putting the integration test inside the existing categories above.


---

### File: docs/nightly/fuels-rs/docs/src/cookbook/custom-chain.md

# Custom chain

This example demonstrates how to start a short-lived Fuel node with custom consensus parameters for the underlying chain.

First, we have to import `ConsensusParameters` and `ChainConfig`:

```rust,ignore
        use fuels::{
            prelude::*,
            tx::{ConsensusParameters, FeeParameters, TxParameters},
        };
```

Next, we can define some values for the consensus parameters:

```rust,ignore
        let tx_params = TxParameters::default()
            .with_max_gas_per_tx(1_000)
            .with_max_inputs(2);
        let fee_params = FeeParameters::default().with_gas_price_factor(10);

        let mut consensus_parameters = ConsensusParameters::default();
        consensus_parameters.set_tx_params(tx_params);
        consensus_parameters.set_fee_params(fee_params);

        let chain_config = ChainConfig {
            consensus_parameters,
            ..ChainConfig::default()
        };
```

Before we can start a node, we probably also want to define some genesis coins and assign them to an address:

```rust,ignore
        let signer = PrivateKeySigner::random(&mut thread_rng());
        let coins = setup_single_asset_coins(
            signer.address(),
            Default::default(),
            DEFAULT_NUM_COINS,
            DEFAULT_COIN_AMOUNT,
        );
```

Finally, we call `setup_test_provider()`, which starts a node with the given configurations and returns a
provider attached to that node:

```rust,ignore
        let node_config = NodeConfig::default();
        let _provider =
            setup_test_provider(coins, vec![], Some(node_config), Some(chain_config)).await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/cookbook/deposit-and-withdraw.md

# Deposit and withdraw

Consider the following contract:

```rust,ignore
contract;

use std::{asset::{mint_to, transfer}, call_frames::msg_asset_id, context::msg_amount};
abi LiquidityPool {
    #[payable]
    fn deposit(recipient: Identity);
    #[payable]
    fn withdraw(recipient: Identity);
}
const BASE_TOKEN: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);
impl LiquidityPool for Contract {
    #[payable]
    fn deposit(recipient: Identity) {
        assert(BASE_TOKEN == msg_asset_id());
        assert(0 < msg_amount());
        // Mint two times the amount.
        let amount_to_mint = msg_amount() * 2;
        // Mint some LP token based upon the amount of the base token.
        mint_to(recipient, b256::zero(), amount_to_mint);
    }
    #[payable]
    fn withdraw(recipient: Identity) {
        assert(0 < msg_amount());
        // Amount to withdraw.
        let amount_to_transfer = msg_amount() / 2;
        // Transfer base token to recipient.
        transfer(recipient, BASE_TOKEN, amount_to_transfer);
    }
}

```

As its name suggests, it represents a simplified example of a liquidity pool contract. The method `deposit()` expects you to supply an arbitrary amount of the `BASE_TOKEN`. As a result, it mints double the amount of the liquidity asset to the calling address. Analogously, if you call `withdraw()` supplying it with the liquidity asset, it will transfer half that amount of the `BASE_TOKEN` back to the calling address except for deducting it from the contract balance instead of minting it.

The first step towards interacting with any contract in the Rust SDK is calling the `abigen!` macro to generate type-safe Rust bindings for the contract methods:

```rust,ignore
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/liquidity_pool/out/release/liquidity_pool-abi.json"
        ));
```

Next, we set up a wallet with custom-defined assets. We give our wallet some of the contracts `BASE_TOKEN` and the default asset (required for contract deployment):

```rust,ignore
        let base_asset_id: AssetId =
            "0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c".parse()?;

        let asset_ids = [AssetId::zeroed(), base_asset_id];
        let asset_configs = asset_ids
            .map(|id| AssetConfig {
                id,
                num_coins: 1,
                coin_amount: 1_000_000,
            })
            .into();

        let wallet_config = WalletsConfig::new_multiple_assets(1, asset_configs);
        let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?;
        let wallet = &wallets[0];
```

Having launched a provider and created the wallet, we can deploy our contract and create an instance of its methods:

```rust,ignore
        let contract_id = Contract::load_from(
            "../../e2e/sway/contracts/liquidity_pool/out/release/liquidity_pool.bin",
            LoadConfiguration::default(),
        )?
        .deploy(wallet, TxPolicies::default())
        .await?
        .contract_id;

        let contract_methods = MyContract::new(contract_id, wallet.clone()).methods();
```

With the preparations out of the way, we can finally deposit to the liquidity pool by calling `deposit()` via the contract instance. Since we have to transfer assets to the contract, we create the appropriate `CallParameters` and chain them to the method call. To receive the minted liquidity pool asset, we have to append a variable output to our contract call.

```rust,ignore
        let deposit_amount = 1_000_000;
        let call_params = CallParameters::default()
            .with_amount(deposit_amount)
            .with_asset_id(base_asset_id);

        contract_methods
            .deposit(wallet.address().into())
            .call_params(call_params)?
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .call()
            .await?;
```

As a final demonstration, let's use all our liquidity asset balance to withdraw from the pool and confirm we retrieved the initial amount. For this, we get our liquidity asset balance and supply it to the `withdraw()` call via `CallParameters`.

```rust,ignore
        let lp_asset_id = contract_id.asset_id(&SubAssetId::zeroed());
        let lp_token_balance = wallet.get_asset_balance(&lp_asset_id).await?;

        let call_params = CallParameters::default()
            .with_amount(lp_token_balance.try_into().unwrap())
            .with_asset_id(lp_asset_id);

        contract_methods
            .withdraw(wallet.address().into())
            .call_params(call_params)?
            .with_variable_output_policy(VariableOutputPolicy::Exactly(1))
            .call()
            .await?;

        let base_balance = wallet.get_asset_balance(&base_asset_id).await?;
        assert_eq!(base_balance, deposit_amount as u128);
```


---

### File: docs/nightly/fuels-rs/docs/src/cookbook/index.md

# Cookbook

This section covers more advanced use cases that can be satisfied by combining various features of the Rust SDK. As such, it assumes that you have already made yourself familiar with the previous chapters of this book.

> **Note** This section is still a work in progress and more recipes may be added in the future.


---

### File: docs/nightly/fuels-rs/docs/src/cookbook/transfer-all-assets.md

# Transfer all assets

The `transfer()` method lets you transfer a single asset, but what if you needed to move all of your assets to a different wallet? You could repeatably call `transfer()`, initiating a transaction each time, or you bundle all the transfers into a single transaction. This chapter guides you through crafting your custom transaction for transferring all assets owned by a wallet.

Lets quickly go over the setup:

```rust,ignore
        let wallet_1_signer = PrivateKeySigner::random(&mut thread_rng());

        const NUM_ASSETS: u64 = 5;
        const AMOUNT: u64 = 100_000;
        const NUM_COINS: u64 = 1;
        let (coins, _) =
            setup_multiple_assets_coins(wallet_1_signer.address(), NUM_ASSETS, NUM_COINS, AMOUNT);

        let provider = setup_test_provider(coins, vec![], None, None).await?;

        let wallet_1 = Wallet::new(wallet_1_signer, provider.clone());
        let wallet_2 = Wallet::random(&mut thread_rng(), provider.clone());
```

We prepare two wallets with randomized addresses. Next, we want one of our wallets to have some random assets, so we set them up with `setup_multiple_assets_coins()`.

Transactions require us to define input and output coins. Let's assume we do not know the assets owned by `wallet_1`. We retrieve its balances, i.e. tuples consisting of a string representing the asset ID and the respective amount. This lets us use the helpers `get_asset_inputs_for_amount()`, `get_asset_outputs_for_amount()` to create the appropriate inputs and outputs.

We transfer only a part of the base asset balance so that the rest can cover transaction fees:

```rust,ignore
        let balances = wallet_1.get_balances().await?;

        let consensus_parameters = provider.consensus_parameters().await?;
        let mut inputs = vec![];
        let mut outputs = vec![];
        for (id_string, amount) in balances {
            let id = AssetId::from_str(&id_string)?;

            let input = wallet_1
                .get_asset_inputs_for_amount(id, amount, None)
                .await?;
            inputs.extend(input);

            // we don't transfer the full base asset so we can cover fees
            let output = if id == *consensus_parameters.base_asset_id() {
                wallet_1.get_asset_outputs_for_amount(wallet_2.address(), id, (amount / 2) as u64)
            } else {
                wallet_1.get_asset_outputs_for_amount(wallet_2.address(), id, amount as u64)
            };

            outputs.extend(output);
        }
```

All that is left is to build the transaction via `ScriptTransactionBuilder`, have `wallet_1` add a witness to it and we can send it. We confirm this by checking the number of balances present in the receiving wallet and their amount:

```rust,ignore
        let mut tb =
            ScriptTransactionBuilder::prepare_transfer(inputs, outputs, TxPolicies::default());
        wallet_1.add_witnesses(&mut tb)?;

        let tx = tb.build(&provider).await?;

        provider.send_transaction_and_await_commit(tx).await?;

        let balances = wallet_2.get_balances().await?;

        assert_eq!(balances.len(), NUM_ASSETS as usize);
        for (id, balance) in balances {
            if id == *consensus_parameters.base_asset_id().to_string() {
                assert_eq!(balance, (AMOUNT / 2) as u128);
            } else {
                assert_eq!(balance, AMOUNT as u128);
            }
        }
```


---

### File: docs/nightly/fuels-rs/docs/src/custom-transactions/custom-calls.md

# Custom contract and script calls

When preparing a contract call via `CallHandler`, the Rust SDK uses a transaction builder in the background. You can fetch this builder and customize it before submitting it to the network. After the transaction is executed successfully, you can use the corresponding `CallHandler` to generate a [call response](../calling-contracts/call-response.md). The call response can be used to decode return values and logs. Below are examples for both contract and script calls.

## Custom contract call

```rust,ignore
        let call_handler = contract_instance.methods().initialize_counter(counter);

        let mut tb = call_handler.transaction_builder().await?;

        // customize the builder...

        wallet.adjust_for_fee(&mut tb, 0).await?;
        wallet.add_witnesses(&mut tb)?;

        let tx = tb.build(provider).await?;

        let tx_id = provider.send_transaction(tx).await?;
        tokio::time::sleep(Duration::from_millis(500)).await;

        let tx_status = provider.tx_status(&tx_id).await?;

        let response = call_handler.get_response(tx_status)?;

        assert_eq!(counter, response.value);
```

## Custom script call

```rust,ignore
    let script_call_handler = script_instance.main(1, 2);

    let mut tb = script_call_handler.transaction_builder().await?;

    // customize the builder...

    wallet.adjust_for_fee(&mut tb, 0).await?;
    wallet.add_witnesses(&mut tb)?;

    let tx = tb.build(provider).await?;

    let tx_id = provider.send_transaction(tx).await?;
    tokio::time::sleep(Duration::from_millis(500)).await;
    let tx_status = provider.tx_status(&tx_id).await?;

    let response = script_call_handler.get_response(tx_status)?;

    assert_eq!(response.value, "hello");
```


---

### File: docs/nightly/fuels-rs/docs/src/custom-transactions/index.md

# Custom transactions

Until now, we have used helpers to create transactions, send them with a provider, and parse the results. However, sometimes we must make custom transactions with specific inputs, outputs, witnesses, etc. In the next chapter, we will show how to use the Rust SDKs transaction builders to accomplish this.


---

### File: docs/nightly/fuels-rs/docs/src/custom-transactions/transaction-builders.md

# Transaction Builders

The Rust SDK simplifies the creation of **Create** and **Script** transactions through two handy builder structs `CreateTransactionBuilder`, `ScriptTransactionBuilder`, and the `TransactionBuilder` trait.

Calling `build(&provider)` on a builder will result in the corresponding `CreateTransaction` or `ScriptTransaction` that can be submitted to the network.

## Role of the transaction builders

> **Note** This section contains additional information about the inner workings of the builders. If you are just interested in how to use them, you can skip to the next section.

The builders take on the heavy lifting behind the scenes, offering two standout advantages: handling predicate data offsets and managing witness indexing.

When your transaction involves predicates with dynamic data as inputs, like vectors, the dynamic data contains a pointer pointing to the beginning of the raw data. This pointer's validity hinges on the order of transaction inputs, and any shifting could render it invalid. However, the transaction builders conveniently postpone the resolution of these pointers until you finalize the build process.

Similarly, adding signatures for signed coins requires the signed coin input to hold an index corresponding to the signature in the witnesses array. These indexes can also become invalid if the witness order changes. The Rust SDK again defers the resolution of these indexes until the transaction is finalized. It handles the assignment of correct index witnesses behind the scenes, sparing you the hassle of dealing with indexing intricacies during input definition.

Another added benefit of the builder pattern is that it guards against changes once the transaction is finalized. The transactions resulting from a builder don't permit any changes to the struct that could cause the transaction ID to be modified. This eliminates the headache of calculating and storing a transaction ID for future use, only to accidentally modify the transaction later, resulting in a different transaction ID.

## Creating a custom transaction

Here is an example outlining some of the features of the transaction builders.

In this scenario, we have a predicate that holds some bridged asset with ID **bridged_asset_id**. It releases it's locked assets if the transaction sends **ask_amount** of the base asset to the **receiver** address:

```rust,ignore
        let ask_amount = 100;
        let locked_amount = 500;
        let bridged_asset_id = AssetId::from([1u8; 32]);
        let receiver =
            Address::from_str("09c0b2d1a486c439a87bcba6b46a7a1a23f3897cc83a94521a96da5c23bc58db")?;
```

Our goal is to create a transaction that will use our hot wallet to transfer the **ask_amount** to the **receiver** and then send the unlocked predicate assets to a second wallet that acts as our cold storage.

Let's start by instantiating a builder. Since we don't plan to deploy a contract, the `ScriptTransactionBuilder` is the appropriate choice:

```rust,ignore
        let ask_amount = 100;
        let locked_amount = 500;
        let bridged_asset_id = AssetId::from([1u8; 32]);
        let receiver =
            Address::from_str("09c0b2d1a486c439a87bcba6b46a7a1a23f3897cc83a94521a96da5c23bc58db")?;
        let tb = ScriptTransactionBuilder::default();
        let consensus_parameters = provider.consensus_parameters().await?;
        let base_inputs = hot_wallet
            .get_asset_inputs_for_amount(*consensus_parameters.base_asset_id(), ask_amount, None)
            .await?;
        let base_outputs = hot_wallet.get_asset_outputs_for_amount(
            receiver,
            *consensus_parameters.base_asset_id(),
            ask_amount as u64,
        );
        let other_asset_inputs = predicate
            .get_asset_inputs_for_amount(bridged_asset_id, locked_amount, None)
            .await?;
        let other_asset_outputs =
            predicate.get_asset_outputs_for_amount(cold_wallet.address(), bridged_asset_id, 500);
        let inputs = base_inputs
            .into_iter()
            .chain(other_asset_inputs.into_iter())
            .collect();
        let outputs = base_outputs
            .into_iter()
            .chain(other_asset_outputs.into_iter())
            .collect();

        let mut tb = tb.with_inputs(inputs).with_outputs(outputs);
        tb.add_signer(hot_wallet.signer().clone())?;
        hot_wallet.adjust_for_fee(&mut tb, 100).await?;
        let tx_policies = TxPolicies::default().with_maturity(64).with_expiration(128);
        let tb = tb.with_tx_policies(tx_policies);
        let tx = tb.build(&provider).await?;
        let tx_id = provider.send_transaction(tx).await?;
        let status = provider.tx_status(&tx_id).await?;
        assert!(matches!(status, TxStatus::Success { .. }));

        let balance: u128 = cold_wallet.get_asset_balance(&bridged_asset_id).await?;
        assert_eq!(balance, locked_amount);
```

Next, we need to define transaction inputs of the base asset that sum up to **ask_amount**. We also need transaction outputs that will assign those assets to the predicate address and thereby unlock it. The methods `get_asset_inputs_for_amount` and `get_asset_outputs_for_amount` can help with that. We need to specify the asset ID, the target amount, and the target address:

```rust,ignore
        let consensus_parameters = provider.consensus_parameters().await?;
        let base_inputs = hot_wallet
            .get_asset_inputs_for_amount(*consensus_parameters.base_asset_id(), ask_amount, None)
            .await?;
        let base_outputs = hot_wallet.get_asset_outputs_for_amount(
            receiver,
            *consensus_parameters.base_asset_id(),
            ask_amount as u64,
        );
```

Let's repeat the same process but this time for transferring the assets held by the predicate to our cold storage:

```rust,ignore
        let other_asset_inputs = predicate
            .get_asset_inputs_for_amount(bridged_asset_id, locked_amount, None)
            .await?;
        let other_asset_outputs =
            predicate.get_asset_outputs_for_amount(cold_wallet.address(), bridged_asset_id, 500);
```

We combine all of the inputs and outputs and set them on the builder:

```rust,ignore
        let consensus_parameters = provider.consensus_parameters().await?;
        let base_inputs = hot_wallet
            .get_asset_inputs_for_amount(*consensus_parameters.base_asset_id(), ask_amount, None)
            .await?;
        let base_outputs = hot_wallet.get_asset_outputs_for_amount(
            receiver,
            *consensus_parameters.base_asset_id(),
            ask_amount as u64,
        );
        let other_asset_inputs = predicate
            .get_asset_inputs_for_amount(bridged_asset_id, locked_amount, None)
            .await?;
        let other_asset_outputs =
            predicate.get_asset_outputs_for_amount(cold_wallet.address(), bridged_asset_id, 500);
        let inputs = base_inputs
            .into_iter()
            .chain(other_asset_inputs.into_iter())
            .collect();
        let outputs = base_outputs
            .into_iter()
            .chain(other_asset_outputs.into_iter())
            .collect();

        let mut tb = tb.with_inputs(inputs).with_outputs(outputs);
```

As we have used coins that require a signature, we have to add the signer to the transaction builder with:

```rust,ignore
        tb.add_signer(hot_wallet.signer().clone())?;
```

> **Note** The signature is not created until the transaction is finalized with `build(&provider)`

We need to do one more thing before we stop thinking about transaction inputs. Executing the transaction also incurs a fee that is paid with the base asset. Our base asset inputs need to be large enough so that the total amount covers the transaction fee and any other operations we are doing. The `ViewOnlyAccount` trait lets us use `adjust_for_fee()` for adjusting the transaction inputs if needed to cover the fee. The second argument to `adjust_for_fee()` is the total amount of the base asset that we expect our transaction to spend regardless of fees. In our case, this is the **ask_amount** we are transferring to the predicate.

```rust,ignore
        hot_wallet.adjust_for_fee(&mut tb, 100).await?;
```

> **Note** It is recommended to add signers before calling `adjust_for_fee()` as the estimation will include the size of the witnesses.

We can also define transaction policies. For example, we can set the maturity and expiration with:

```rust,ignore
        let tx_policies = TxPolicies::default().with_maturity(64).with_expiration(128);
        let tb = tb.with_tx_policies(tx_policies);
```

Our builder needs a signature from the hot wallet to unlock its coins before we call `build()` and submit the resulting transaction through the provider:

```rust,ignore
        let tx = tb.build(&provider).await?;
        let tx_id = provider.send_transaction(tx).await?;
```

Finally, we verify the transaction succeeded and that the cold storage indeed holds the bridged asset now:

```rust,ignore
        let status = provider.tx_status(&tx_id).await?;
        assert!(matches!(status, TxStatus::Success { .. }));

        let balance: u128 = cold_wallet.get_asset_balance(&bridged_asset_id).await?;
        assert_eq!(balance, locked_amount);
```

## Building a transaction without signatures

If you need to build the transaction without signatures, which is useful when estimating transaction costs or simulations, you can change the build strategy used:

```rust,ignore
    let mut tx = tb
        .with_build_strategy(ScriptBuildStrategy::NoSignatures)
        .build(provider)
        .await?;
    // ANCHOR: tx_sign_with
    tx.sign_with(wallet.signer(), consensus_parameters.chain_id())
        .await?;
    // ANCHOR_END: tx_sign_with
```

> **Note** In contrast to adding signers to a transaction builder, when signing a built transaction, you must ensure that the order of signatures matches the order of signed inputs. Multiple signed inputs with the same owner will have the same witness index.


---

### File: docs/nightly/fuels-rs/docs/src/debugging/decoding-script-transactions.md

# Decoding script transactions

The SDK offers some tools that can help you make fuel script transactions more
human readable. You can determine whether the script transaction is:

* calling a contract method(s),
* is a loader script and you can see the blob id
* is neither of the above

In the case of contract call(s), if you have the ABI file, you can also decode
the arguments to the function by making use of the `AbiFormatter`:

```rust,ignore
        let TransactionType::Script(tx) = provider
            .get_transaction_by_id(&tx_id)
            .await?
            .unwrap()
            .transaction
        else {
            panic!("Transaction is not a script transaction");
        };

        let ScriptType::ContractCall(calls) = ScriptType::detect(tx.script(), tx.script_data())?
        else {
            panic!("Script is not a contract call");
        };

        let json_abi = std::fs::read_to_string(
            "../../e2e/sway/contracts/contract_test/out/release/contract_test-abi.json",
        )?;
        let abi_formatter = ABIFormatter::from_json_abi(json_abi)?;

        let call = &calls[0];
        let fn_selector = call.decode_fn_selector()?;
        let decoded_args =
            abi_formatter.decode_fn_args(&fn_selector, call.encoded_args.as_slice())?;

        eprintln!(
            "The script called: {fn_selector}({})",
            decoded_args.join(", ")
        );

```

prints:

```text
The script called: initialize_counter(42)
```

The `AbiFormatter` can also decode configurables, refer to the rust docs for
more information.


---

### File: docs/nightly/fuels-rs/docs/src/debugging/function-selector.md

# Function selector

Whenever you call a contract method the SDK will generate a function selector according to the fuel specs which will be
used by the node to identify which method we wish to execute.

If, for whatever reason, you wish to generate the function selector yourself you can do so:

```rust,ignore
        // fn some_fn_name(arg1: Vec<str[3]>, arg2: u8)
        let fn_name = "some_fn_name";

        let selector = encode_fn_selector(fn_name);

        assert_eq!(
            selector,
            [
                0, 0, 0, 0, 0, 0, 0, 12, 115, 111, 109, 101, 95, 102, 110, 95, 110, 97, 109, 101
            ]
        );
```


---

### File: docs/nightly/fuels-rs/docs/src/debugging/index.md

# Debugging

> **note** This section is still a work in progress.

- [The Function Selector](./function-selector.md)


---

### File: docs/nightly/fuels-rs/docs/src/deploying/configurable-constants.md

# Configurable constants

In Sway, you can define `configurable` constants which can be changed during the contract deployment in the SDK. Here is an example how the constants are defined.

```rust,ignore
contract;

#[allow(dead_code)]
enum EnumWithGeneric<D> {
    VariantOne: D,
    VariantTwo: (),
}

struct StructWithGeneric<D> {
    field_1: D,
    field_2: u64,
}

configurable {
    BOOL: bool = true,
    U8: u8 = 8,
    U16: u16 = 16,
    U32: u32 = 32,
    U64: u64 = 63,
    U256: u256 = 0x0000000000000000000000000000000000000000000000000000000000000008u256,
    B256: b256 = 0x0101010101010101010101010101010101010101010101010101010101010101,
    STR_4: str[4] = __to_str_array("fuel"),
    TUPLE: (u8, bool) = (8, true),
    ARRAY: [u32; 3] = [253, 254, 255],
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}
//U128: u128 = 128, //TODO: add once https://github.com/FuelLabs/sway/issues/5356 is done

abi TestContract {
    fn return_configurables() -> (bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric<u8>, EnumWithGeneric<bool>);
}

impl TestContract for Contract {
    fn return_configurables() -> (bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric<u8>, EnumWithGeneric<bool>) {
        (BOOL, U8, U16, U32, U64, U256, B256, STR_4, TUPLE, ARRAY, STRUCT, ENUM)
    }
}

```

Each of the configurable constants will get a dedicated `with` method in the SDK. For example, the constant `STR_4` will get the `with_STR_4` method which accepts the same type as defined in the contract code. Below is an example where we chain several `with` methods and deploy the contract with the new constants.

```rust,ignore
    abigen!(Contract(
        name = "MyContract",
        abi = "e2e/sway/contracts/configurables/out/release/configurables-abi.json"
    ));

    let wallet = launch_provider_and_get_wallet().await?;

    let str_4: SizedAsciiString<4> = "FUEL".try_into()?;
    let new_struct = StructWithGeneric {
        field_1: 16u8,
        field_2: 32,
    };
    let new_enum = EnumWithGeneric::VariantTwo;

    let configurables = MyContractConfigurables::default()
        .with_BOOL(false)?
        .with_U8(7)?
        .with_U16(15)?
        .with_U32(31)?
        .with_U64(63)?
        .with_U256(U256::from(8))?
        .with_B256(Bits256([2; 32]))?
        .with_STR_4(str_4.clone())?
        .with_TUPLE((7, false))?
        .with_ARRAY([252, 253, 254])?
        .with_STRUCT(new_struct.clone())?
        .with_ENUM(new_enum.clone())?;

    let contract_id = Contract::load_from(
        "sway/contracts/configurables/out/release/configurables.bin",
        LoadConfiguration::default().with_configurables(configurables),
    )?
    .deploy_if_not_exists(&wallet, TxPolicies::default())
    .await?
    .contract_id;

    let contract_instance = MyContract::new(contract_id, wallet.clone());
```


---

### File: docs/nightly/fuels-rs/docs/src/deploying/index.md

# Deploying contracts

There are two main ways of working with contracts in the SDK: deploying a contract with SDK or using the SDK to interact with existing contracts.

## Deploying a contract binary

<!-- This section should explain the artifacts produced by `forc build`  -->
<!-- build:example:start -->
Once you've written a contract in Sway and compiled it with `forc build`, you'll have in your hands two important artifacts: the compiled binary file and the JSON ABI file.
<!-- build:example:end -->
> Note: Read [here](https://docs.fuel.network/guides/quickstart/) for more on how to work with Sway.

Below is how you can deploy your contracts using the SDK. For more details about each component in this process, read [The abigen macro](../abigen/the-abigen-macro.md), [The FuelVM binary file](./the-fuelvm-binary-file.md), and [The JSON ABI file](../abigen/the-json-abi-file.md).

<!-- This section should explain how to load and deploy a contract  -->
<!-- deploy:example:start -->
First, the `Contract::load_from` function is used to load a contract binary with a `LoadConfiguration`. If you are only interested in a single instance of your contract, use the default configuration: `LoadConfiguration::default()`. After the contract binary is loaded, you can use the `deploy()` method to deploy the contract to the blockchain.
<!-- deploy:example:end -->

```rust,ignore
        // This helper will launch a local node and provide a test wallet linked to it
        let wallet = launch_provider_and_get_wallet().await?;

        // This will load and deploy your contract binary to the chain so that its ID can
        // be used to initialize the instance
        let contract_id = Contract::load_from(
            "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin",
            LoadConfiguration::default(),
        )?
        .deploy(&wallet, TxPolicies::default())
        .await?
        .contract_id;

        println!("Contract deployed @ {contract_id}");
        setup_program_test!(
            Wallets("wallet"),
            Abigen(Contract(
                name = "TestContract",
                project = "e2e/sway/contracts/contract_test"
            )),
            Deploy(
                name = "contract_instance",
                contract = "TestContract",
                wallet = "wallet"
            ),
        );

        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .call()
            .await?;

        assert_eq!(42, response.value);
```

Alternatively, you can use `LoadConfiguration` to configure how the contract is loaded. `LoadConfiguration` let's you:

- Load the same contract binary with `Salt` to get a new `contract_id`
- Change the contract's storage slots
- Update the contract's configurables

> Note: The next section will give more information on how `configurables` can be used.

Additionally, you can set custom `TxParameters` when deploying the loaded contract.

```rust,ignore
        // Optional: Add `Salt`
        let rng = &mut StdRng::seed_from_u64(2322u64);
        let salt: [u8; 32] = rng.r#gen();

        // Optional: Configure storage
        let key = Bytes32::from([1u8; 32]);
        let value = Bytes32::from([2u8; 32]);
        let storage_slot = StorageSlot::new(key, value);
        let storage_configuration =
            StorageConfiguration::default().add_slot_overrides([storage_slot]);
        let configuration = LoadConfiguration::default()
            .with_storage_configuration(storage_configuration)
            .with_salt(salt);

        // Optional: Configure deployment parameters
        let tx_policies = TxPolicies::default()
            .with_tip(1)
            .with_script_gas_limit(1_000_000)
            .with_maturity(0)
            .with_expiration(10_000);

        let contract_id_2 = Contract::load_from(
            "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin",
            configuration,
        )?
        .deploy(&wallet, tx_policies)
        .await?
        .contract_id;

        println!("Contract deployed @ {contract_id_2}");
```

After the contract is deployed, you can use the contract's methods like this:

```rust,ignore
        // This will generate your contract's methods onto `MyContract`.
        // This means an instance of `MyContract` will have access to all
        // your contract's methods that are running on-chain!
        // ANCHOR: abigen_example
        abigen!(Contract(
            name = "MyContract",
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        // ANCHOR_END: abigen_example

        // This is an instance of your contract which you can use to make calls to your functions
        let contract_instance = MyContract::new(contract_id_2, wallet);

        let response = contract_instance
            .methods()
            .initialize_counter(42) // Build the ABI call
            .call() // Perform the network call
            .await?;

        assert_eq!(42, response.value);

        let response = contract_instance
            .methods()
            .increment_counter(10)
            .call()
            .await?;

        assert_eq!(52, response.value);
```

> Note: When redeploying an existing `Contract`, ensure that you initialize it with a unique salt to prevent deployment failures caused by a contract ID collision. To accomplish this, utilize the `with_salt` method to clone the existing `Contract` with a new salt.


---

### File: docs/nightly/fuels-rs/docs/src/deploying/interacting-with-contracts.md

# Interacting with contracts

If you already have a deployed contract and want to call its methods using the SDK, but without deploying it again, all you need is the contract ID of your deployed contract. You can skip the whole deployment setup and call `::new(contract_id, wallet)` directly. For example:

```rust,ignore
        abigen!(Contract(
            name = "MyContract",
            // Replace with your contract ABI.json path
            abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json"
        ));
        let wallet_original = launch_provider_and_get_wallet().await?;

        let wallet = wallet_original.clone();
        let contract_id: ContractId =
            "0x65b6a3d081966040bbccbb7f79ac91b48c635729c59a4c02f15ae7da999b32d3".parse()?;

        let connected_contract_instance = MyContract::new(contract_id, wallet);
```


---

### File: docs/nightly/fuels-rs/docs/src/deploying/large_contracts.md

# Deploying Large Contracts

If your contract exceeds the size limit for a single deployment:

```rust,ignore
        let contract = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?;
        let max_allowed = provider
            .consensus_parameters()
            .await?
            .contract_params()
            .contract_max_size();

        assert!(contract.code().len() as u64 > max_allowed);
```

you can deploy it in segments using a partitioned approach:

```rust,ignore
        let max_words_per_blob = 10_000;
        let contract_id = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .convert_to_loader(max_words_per_blob)?
        .deploy(&wallet, TxPolicies::default())
        .await?
        .contract_id;
```

When you convert a standard contract into a loader contract, the following changes occur:

* The original contract code is replaced with the loader contract code.
* The original contract code is split into blobs, which will be deployed via blob transactions before deploying the contract itself.
* The new loader code, when invoked, loads these blobs into memory and executes your original contract.

After deploying the loader contract, you can interact with it just as you would with a standard contract:

```rust,ignore
        let contract_instance = MyContract::new(contract_id, wallet);
        let response = contract_instance.methods().something().call().await?.value;
        assert_eq!(response, 1001);
```

A helper function is available to deploy your contract normally if it is within the size limit, or as a loader contract if it exceeds the limit:

```rust,ignore
        let max_words_per_blob = 10_000;
        let contract_id = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .smart_deploy(&wallet, TxPolicies::default(), max_words_per_blob)
        .await?
        .contract_id;
```

You also have the option to separate the blob upload from the contract deployment for more granular control:

```rust,ignore
        let contract_id = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .convert_to_loader(max_words_per_blob)?
        .upload_blobs(&wallet, TxPolicies::default())
        .await?
        .deploy(&wallet, TxPolicies::default())
        .await?
        .contract_id;
```

Alternatively, you can manually split your contract code into blobs and then create and deploy a loader:

```rust,ignore
        let chunk_size = 100_000;
        assert!(
            chunk_size % 8 == 0,
            "all chunks, except the last, must be word-aligned"
        );
        let blobs = contract
            .code()
            .chunks(chunk_size)
            .map(|chunk| Blob::new(chunk.to_vec()))
            .collect();

        let contract_id = Contract::loader_from_blobs(blobs, random_salt(), vec![])?
            .deploy(&wallet, TxPolicies::default())
            .await?
            .contract_id;
```

Or you can upload the blobs yourself and proceed with just the loader deployment:

```rust,ignore
        let max_words_per_blob = 10_000;
        let blobs = Contract::load_from(
            contract_binary,
            LoadConfiguration::default().with_salt(random_salt()),
        )?
        .convert_to_loader(max_words_per_blob)?
        .blobs()
        .to_vec();

        let mut all_blob_ids = vec![];
        let mut already_uploaded_blobs = HashSet::new();
        for blob in blobs {
            let blob_id = blob.id();
            all_blob_ids.push(blob_id);

            // uploading the same blob twice is not allowed
            if already_uploaded_blobs.contains(&blob_id) {
                continue;
            }

            let mut tb = BlobTransactionBuilder::default().with_blob(blob);
            wallet.adjust_for_fee(&mut tb, 0).await?;
            wallet.add_witnesses(&mut tb)?;

            let tx = tb.build(&provider).await?;
            provider
                .send_transaction_and_await_commit(tx)
                .await?
                .check(None)?;

            already_uploaded_blobs.insert(blob_id);
        }

        let contract_id = Contract::loader_from_blob_ids(all_blob_ids, random_salt(), vec![])?
            .deploy(&wallet, TxPolicies::default())
            .await?
            .contract_id;
```

## Blob Size Considerations

The size of a Blob transaction is constrained by three factors:

<!--Needed to disable lints because the multiline ordered list is messing with the linter. It keeps suggesting that each item is a start of a new list.-->
<!-- markdownlint-disable -->
1. The maximum size of a single transaction:

```rust,ignore
        provider
            .consensus_parameters()
            .await?
            .tx_params()
            .max_size();
```

2. The maximum gas usage for a single transaction:

```rust,ignore
        provider
            .consensus_parameters()
            .await?
            .tx_params()
            .max_gas_per_tx();
```

3. The maximum HTTP body size accepted by the Fuel node.

To estimate an appropriate size for your blobs, you can run:

```rust,ignore
        let max_blob_size = BlobTransactionBuilder::default()
            .estimate_max_blob_size(&provider)
            .await?;
```
<!-- markdownlint-restore -->

However, keep in mind the following limitations:

* The estimation only considers the maximum transaction size, not the max gas usage or HTTP body limit.
* It does not account for any size increase that may occur after the transaction is funded.

Therefore, it is advisable to make your blobs a few percent smaller than the estimated maximum size.


---

### File: docs/nightly/fuels-rs/docs/src/deploying/storage-slots.md

# Overriding storage slots

If you use storage in your contract, the default storage values will be generated in a JSON file (e.g. `my_contract-storage_slots.json`) by the Sway compiler. These are loaded automatically for you when you load a contract binary. If you wish to override some of the defaults, you need to provide the corresponding storage slots manually:

```rust,ignore
            use fuels::{programs::contract::Contract, tx::StorageSlot};
            let slot_override = StorageSlot::new([1; 32].into(), [2; 32].into());
            let storage_config =
                StorageConfiguration::default().add_slot_overrides([slot_override]);

            let load_config =
                LoadConfiguration::default().with_storage_configuration(storage_config);
            let _: Result<_> = Contract::load_from("...", load_config);
```

If you don't have the slot storage file (`my_contract-storage_slots.json` example from above) for some reason, or you don't wish to load any of the default values, you can disable the auto-loading of storage slots:

```rust,ignore
            use fuels::programs::contract::Contract;
            let storage_config = StorageConfiguration::default().with_autoload(false);

            let load_config =
                LoadConfiguration::default().with_storage_configuration(storage_config);
            let _: Result<_> = Contract::load_from("...", load_config);
```


---

### File: docs/nightly/fuels-rs/docs/src/deploying/the-fuelvm-binary-file.md

# The FuelVM binary file

The command `forc build` compiles your Sway code and generates the bytecode: the binary code that the Fuel Virtual Machine will interpret. For instance, the smart contract below:

```Rust
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

After `forc build`, will have a binary file that contains:

```terminal
$ cat out/release/my-test.bin
G4]�]D`I]C�As@
           6]C�$@!QK%
```

This seems very unreadable! But, `forc` has a nice interpreter for this bytecode: `forc parse-bytecode`, which will interpret that binary data and output the equivalent FuelVM assembly:

```terminal
$ forc parse-bytecode out/release/my-test.bin
half-word   byte   op                raw           notes
        0   0      JI(4)             90 00 00 04   jump to byte 16
        1   4      NOOP              47 00 00 00
        2   8      Undefined         00 00 00 00   data section offset lo (0)
        3   12     Undefined         00 00 00 34   data section offset hi (52)
        4   16     LW(63, 12, 1)     5d fc c0 01
        5   20     ADD(63, 63, 12)   10 ff f3 00
        6   24     LW(17, 6, 73)     5d 44 60 49
        7   28     LW(16, 63, 1)     5d 43 f0 01
        8   32     EQ(16, 17, 16)    13 41 14 00
        9   36     JNZI(16, 11)      73 40 00 0b   conditionally jump to byte 44
       10   40     RVRT(0)           36 00 00 00
       11   44     LW(16, 63, 0)     5d 43 f0 00
       12   48     RET(16)           24 40 00 00
       13   52     Undefined         00 00 00 00
       14   56     Undefined         00 00 00 01
       15   60     Undefined         00 00 00 00
       16   64     XOR(20, 27, 53)   21 51 bd 4b
```

If you want to deploy your smart contract using the SDK, this binary file is important; it's what we'll be sending to the FuelVM in a transaction.


---

### File: docs/nightly/fuels-rs/docs/src/getting-started.md

# Getting Started

## Installation Guide

Please visit the Fuel [installation guide](https://docs.fuel.network/guides/installation) to install the Fuel toolchain binaries and prerequisites.

`forc` is Sway equivalent of Rust's `cargo`. `fuel-core` is a Fuel full node implementation.

There are two main ways you can use the Fuel Rust SDK:

1. Creating a new Sway project with `forc` and running the tests
2. Creating a standalone project and importing the `fuels-rs` crate

## Creating a new project with Forc

You can create a new Sway project with

```shell
forc new <Project name>
```

Or you can initialize a project within an existing folder with

```shell
forc init
```

### Adding a Rust integration test to the Sway project

Now that we have a new project, we can add a Rust integration test using a `cargo generate` template.
If `cargo generate` is not already installed, you can install it with:

<!-- This section should have the command to install cargo generate -->
<!-- cargo_gen_install:example:start -->
```shell
cargo install cargo-generate
```
<!-- cargo_gen_install:example:end -->

> **Note** You can learn more about cargo generate by visiting its [repository](https://github.com/cargo-generate/cargo-generate).

Let's generate the default test harness with the following command:

<!-- This section should have the command to cargo generate a test harness -->
<!-- cargo_gen:example:start -->
```shell
cargo generate --init fuellabs/sway templates/sway-test-rs --name <Project name> --force
```
<!-- cargo_gen:example:end -->

<!-- This section should explain the `--force` flag -->
<!-- force_flag:example:start -->
`--force` forces your `--name` input to retain your desired casing for the `{{project-name}}` placeholder in the template. Otherwise, `cargo-generate` automatically converts it to kebab-case. With `--force`, this means that both `my_fuel_project` and `my-fuel-project` are valid project names, depending on your needs.
<!-- force_flag:example:end -->

Before running test, we need to build the Sway project with:

```shell
forc build
```

Afterwards, we can run the test with:

<!-- This section should have the command to run a test -->
<!-- run_test:example:start -->
```shell
cargo test
```
<!-- run_test:example:end -->

> **Note** If you need to capture output from the tests, use one of the following commands:

<!-- This section should have the command to run a test with no capture -->
<!-- run_test_nocap:example:start -->
```shell
cargo test -- --nocapture
```
<!-- run_test_nocap:example:end -->

## Importing the Fuel Rust SDK

Add these dependencies on your `Cargo.toml`:

```toml
fuels = "0.66.0"
```

> **Note** We're using version `0.66.0` of the SDK, which is the latest version at the time of this writing.

And then, in your Rust file that's going to make use of the SDK:

```rust,ignore
use fuels::prelude::*;
```

## The Fuel Rust SDK source code

Another way to experience the SDK is to look at the source code. The `e2e/tests/` folder is full of integration tests that go through almost all aspects of the SDK.

> **Note** Before running the tests, we need to build all the Sway test projects. The file `packages/fuels/Forc.toml` contains a `[workspace], which members are the paths to all integration tests.
> To build these tests, run the following command:

```shell
forc build --release --path e2e
```

> `forc` can also be used to clean and format the test projects. Check the `help` output for more info.

After building the projects, we can run the tests with

```shell
cargo test
```

If you need all targets and all features, you can run

```shell
cargo test --all-targets --all-features
```

> **Note** If you need to capture output from the tests, you can run

```shell
cargo test -- --nocapture
```

## More in-depth Fuel and Sway knowledge

Read [The Sway Book](https://docs.fuel.network/docs/sway/) for more in-depth knowledge about Sway, the official smart contract language for the Fuel Virtual Machine.


---

### File: docs/nightly/fuels-rs/docs/src/glossary.md

# Glossary

## Contract

<!-- This section should define a contract -->
<!-- rs_contract:example:start -->

A contract, in the SDK, is an abstraction that represents a connection to a specific smart contract deployed on the Fuel Network. This contract instance can be used as a regular Rust object, with methods attached to it that reflect those in its smart contract equivalent.

<!-- rs_contract:example:end -->

## Provider

<!-- This section should define a provider -->
<!-- rs_provider:example:start -->

A Provider is a struct that provides an abstraction for a connection to a Fuel node. It provides read-only access to the node. You can use this provider as-is or through the wallet.

<!-- rs_provider:example:end -->


---

### File: docs/nightly/fuels-rs/docs/src/index.md

# The Fuel Rust SDK

<!-- This section should explain what the Fuel Rust SDK can be used for -->
<!-- fuels_rs:example:start -->
The Fuel Rust SDK can be used for a variety of things, including:

- Compiling, deploying, and testing [Sway](https://github.com/FuelLabs/sway) contracts
- Using the testnet or running a local Fuel node
- Crafting and signing transactions with hand-crafted scripts or contract calls
- Generating type-safe Rust bindings of contract ABI methods
<!-- fuels_rs:example:end -->

This book is an overview of the different things one can achieve using the Rust SDK, and how to implement them. Keep in mind that both the SDK and the documentation are works-in-progress!


---

### File: docs/nightly/fuels-rs/docs/src/predicates/index.md

# Predicates

Predicates, in Sway, are programs that return a Boolean value and do not have any side effects (they are pure). A predicate address can own assets. The predicate address is generated from the compiled byte code and is the same as the `P2SH` address used in Bitcoin. Users can seamlessly send assets to the predicate address as they do for any other address. To spend the predicate funds, the user has to provide the original `byte code` of the predicate together with the `predicate data`. The `predicate data` will be used when executing the `byte code`, and the funds can be transferred if the predicate is validated successfully.

## Instantiating predicates

Let's consider the following predicate example:

```rust,ignore
predicate;

fn main(a: u32, b: u64) -> bool {
    b == a.as_u64()
}

```

We will look at a complete example of using the SDK to send and receive funds from a predicate.

First, we set up the wallets and a node instance. The call to the `abigen!` macro will generate all the types specified in the predicate plus two custom structs:

- an encoder with an `encode_data`  function that will conveniently encode all the arguments of the main function for us.
- a configurables struct which holds methods for setting all the configurables mentioned in the predicate

> Note: The `abigen!` macro will append `Encoder` and `Configurables` to the predicate's `name` field. Fox example, `name="MyPredicate"` will result in two structs called `MyPredicateEncoder` and `MyPredicateConfigurables`.

```rust,ignore
        let asset_id = AssetId::zeroed();
        let wallets_config = WalletsConfig::new_multiple_assets(
            2,
            vec![AssetConfig {
                id: asset_id,
                num_coins: 1,
                coin_amount: 1_000,
            }],
        );

        let wallets = &launch_custom_provider_and_get_wallets(wallets_config, None, None).await?;

        let first_wallet = &wallets[0];
        let second_wallet = &wallets[1];

        abigen!(Predicate(
            name = "MyPredicate",
            abi = "e2e/sway/predicates/basic_predicate/out/release/basic_predicate-abi.json"
        ));
```

Once we've compiled our predicate with `forc build`, we can create a `Predicate` instance via `Predicate::load_from`. The resulting data from `encode_data` can then be set on the loaded predicate.

```rust,ignore
        let predicate_data = MyPredicateEncoder::default().encode_data(4096, 4096)?;
        let code_path = "../../e2e/sway/predicates/basic_predicate/out/release/basic_predicate.bin";

        let predicate: Predicate = Predicate::load_from(code_path)?
            .with_provider(first_wallet.provider().clone())
            .with_data(predicate_data);
```

Next, we lock some assets in this predicate using the first wallet:

```rust,ignore
        // First wallet transfers amount to predicate.
        first_wallet
            .transfer(predicate.address(), 500, asset_id, TxPolicies::default())
            .await?;

        // Check predicate balance.
        let balance = predicate.get_asset_balance(&AssetId::zeroed()).await?;

        assert_eq!(balance, 500);
```

Then we can transfer assets owned by the predicate via the [Account](../accounts.md) trait:

```rust,ignore
        let amount_to_unlock = 300;

        predicate
            .transfer(
                second_wallet.address(),
                amount_to_unlock,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        // Second wallet balance is updated.
        let balance = second_wallet.get_asset_balance(&AssetId::zeroed()).await?;
        assert_eq!(balance, 1300);
```

## Configurable constants

Same as contracts and scripts, you can define configurable constants in `predicates`, which can be changed during the predicate execution. Here is an example of how the constants are defined.

```rust,ignore
#[allow(dead_code)]
enum EnumWithGeneric<D> {
    VariantOne: D,
    VariantTwo: (),
}

struct StructWithGeneric<D> {
    field_1: D,
    field_2: u64,
}

configurable {
    BOOL: bool = true,
    U8: u8 = 8,
    TUPLE: (u8, bool) = (8, true),
    ARRAY: [u32; 3] = [253, 254, 255],
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}

fn main(
    switch: bool,
    u_8: u8,
    some_tuple: (u8, bool),
    some_array: [u32; 3],
    some_struct: StructWithGeneric<u8>,
    some_enum: EnumWithGeneric<bool>,
) -> bool {
    switch == BOOL && u_8 == U8 && some_tuple.0 == TUPLE.0 && some_tuple.1 == TUPLE.1 && some_array[0] == ARRAY[0] && some_array[1] == ARRAY[1] && some_array[2] == ARRAY[2] && some_struct == STRUCT && some_enum == ENUM
}
```

Each configurable constant will get a dedicated `with` method in the SDK. For example, the constant `U8` will get the `with_U8` method which accepts the same type defined in sway. Below is an example where we chain several `with` methods and update the predicate with the new constants.

```rust,ignore
    abigen!(Predicate(
        name = "MyPredicate",
        abi = "e2e/sway/predicates/predicate_configurables/out/release/predicate_configurables-abi.json"
    ));

    let new_tuple = (16, false);
    let new_array = [123, 124, 125];
    let new_struct = StructWithGeneric {
        field_1: 32u8,
        field_2: 64,
    };
    let new_enum = EnumWithGeneric::VariantTwo;

    let configurables = MyPredicateConfigurables::default()
        .with_U8(8)?
        .with_TUPLE(new_tuple)?
        .with_ARRAY(new_array)?
        .with_STRUCT(new_struct.clone())?
        .with_ENUM(new_enum.clone())?;

    let predicate_data = MyPredicateEncoder::default()
        .encode_data(true, 8u8, new_tuple, new_array, new_struct, new_enum)?;

    let mut predicate: Predicate = Predicate::load_from(
        "sway/predicates/predicate_configurables/out/release/predicate_configurables.bin",
    )?
    .with_data(predicate_data)
    .with_configurables(configurables);
```


---

### File: docs/nightly/fuels-rs/docs/src/predicates/send-spend-predicate.md

# Signatures in predicates example

This is a more involved example where the predicate accepts three signatures and matches them to three predefined public keys. The `ec_recover_address` function is used to recover the public key from the signatures. If two of the three extracted public keys match the predefined public keys, the funds can be spent. Note that the signature order has to match the order of the predefined public keys.

```rust,ignore
predicate;

use std::{
    b512::B512,
    crypto::{
        message::Message,
        secp256k1::Secp256k1,
    },
    inputs::input_predicate_data,
};

fn extract_public_key_and_match(signature: B512, expected_public_key: b256) -> u64 {
    let signature = Secp256k1::from(signature);

    if let Result::Ok(pub_key_sig) = signature.address(Message::from(b256::zero()))
    {
        if pub_key_sig == Address::from(expected_public_key) {
            return 1;
        }
    }

    0
}

fn main(signatures: [B512; 3]) -> bool {
    let public_keys = [
        0xd58573593432a30a800f97ad32f877425c223a9e427ab557aab5d5bb89156db0,
        0x14df7c7e4e662db31fe2763b1734a3d680e7b743516319a49baaa22b2032a857,
        0x3ff494fb136978c3125844625dad6baf6e87cdb1328c8a51f35bda5afe72425c,
    ];

    let mut matched_keys = 0;

    matched_keys = extract_public_key_and_match(signatures[0], public_keys[0]);
    matched_keys = matched_keys + extract_public_key_and_match(signatures[1], public_keys[1]);
    matched_keys = matched_keys + extract_public_key_and_match(signatures[2], public_keys[2]);

    matched_keys > 1
}

```

Let's use the SDK to interact with the predicate. First, let's create three signers with specific keys. Their hashed public keys are already hard-coded in the predicate. Then we create the receiver signer, which we will use to spend the predicate funds.

```rust,ignore
        let wallet_signer = PrivateKeySigner::new(
            "0x862512a2363db2b3a375c0d4bbbd27172180d89f23f2e259bac850ab02619301".parse()?,
        );
        let wallet2_signer = PrivateKeySigner::new(
            "0x37fa81c84ccd547c30c176b118d5cb892bdb113e8e80141f266519422ef9eefd".parse()?,
        );
        let wallet3_signer = PrivateKeySigner::new(
            "0x976e5c3fa620092c718d852ca703b6da9e3075b9f2ecb8ed42d9f746bf26aafb".parse()?,
        );
        let receiver_signer = PrivateKeySigner::random(&mut thread_rng());
```

Next, let's add some coins, start a provider and create the wallets.

```rust,ignore
        let asset_id = AssetId::zeroed();
        let num_coins = 32;
        let amount = 64;
        let initial_balance = amount * num_coins;
        let all_coins = [
            &wallet_signer,
            &wallet2_signer,
            &wallet3_signer,
            &receiver_signer,
        ]
        .iter()
        .flat_map(|signer| setup_single_asset_coins(signer.address(), asset_id, num_coins, amount))
        .collect::<Vec<_>>();

        let provider = setup_test_provider(all_coins, vec![], None, None).await?;

        let wallet = Wallet::new(wallet_signer, provider.clone());
        let wallet2 = Wallet::new(wallet2_signer, provider.clone());
        let wallet3 = Wallet::new(wallet3_signer, provider.clone());
        let receiver = Wallet::new(receiver_signer, provider.clone());
```

Now we can use the predicate abigen to create a predicate encoder instance for us. To spend the funds now locked in the predicate, we must provide two out of three signatures whose public keys match the ones we defined in the predicate. In this example, the signatures are generated from an array of zeros.

```rust,ignore
        abigen!(Predicate(
            name = "MyPredicate",
            abi = "e2e/sway/predicates/signatures/out/release/signatures-abi.json"
        ));

        let predicate_data = MyPredicateEncoder::default().encode_data(signatures)?;
        let code_path = "../../e2e/sway/predicates/signatures/out/release/signatures.bin";

        let predicate: Predicate = Predicate::load_from(code_path)?
            .with_provider(provider)
            .with_data(predicate_data);
```

Next, we transfer some assets from a wallet to the created predicate. We also confirm that the funds are indeed transferred.

```rust,ignore
        let amount_to_predicate = 500;

        wallet
            .transfer(
                predicate.address(),
                amount_to_predicate,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        let predicate_balance = predicate.get_asset_balance(&asset_id).await?;
        assert_eq!(predicate_balance, amount_to_predicate as u128);
```

We can use the `transfer` method from the [Account](../accounts.md) trait to transfer the assets. If the predicate data is correct, the `receiver` wallet will get the funds, and we will verify that the amount is correct.

```rust,ignore
        let amount_to_receiver = 300;
        predicate
            .transfer(
                receiver.address(),
                amount_to_receiver,
                asset_id,
                TxPolicies::default(),
            )
            .await?;

        let receiver_balance_after = receiver.get_asset_balance(&asset_id).await?;
        assert_eq!(
            (initial_balance + amount_to_receiver) as u128,
            receiver_balance_after
        );
```


---

### File: docs/nightly/fuels-rs/docs/src/preuploading-code.md

# Pre-uploading code

If you have a script or predicate that is larger than normal or which you plan
on calling often, you can pre-upload its code as a blob to the network and run a
loader script/predicate instead. The loader can be configured with the
script/predicate configurables, so you can change how the script/predicate is
configured on each run without having large transactions due to the code
duplication.

## Scripts

A high level pre-upload:

```rust,ignore
    my_script.convert_into_loader().await?.main().call().await?;
```

The upload of the blob is handled inside of the `convert_into_loader` method. If you
want more fine-grained control over it, you can create the script transaction
manually:

```rust,ignore
    let regular = Executable::load_from(binary_path)?;

    let configurables = MyScriptConfigurables::default().with_SECRET_NUMBER(10001)?;
    let loader = regular
        .convert_to_loader()?
        .with_configurables(configurables);

    // The Blob must be uploaded manually, otherwise the script code will revert.
    loader.upload_blob(wallet.clone()).await?;

    let encoder = fuels::core::codec::ABIEncoder::default();
    let token = MyStruct {
        field_a: MyEnum::B(99),
        field_b: Bits256([17; 32]),
    }
    .into_token();
    let data = encoder.encode(&[token])?;

    let mut tb = ScriptTransactionBuilder::default()
        .with_script(loader.code())
        .with_script_data(data);

    wallet.adjust_for_fee(&mut tb, 0).await?;

    wallet.add_witnesses(&mut tb)?;

    let tx = tb.build(&provider).await?;

    let response = provider.send_transaction_and_await_commit(tx).await?;

    response.check(None)?;
```

## Predicates

You can prepare a predicate for pre-uploading without doing network requests:

```rust,ignore
    let configurables = MyPredicateConfigurables::default().with_SECRET_NUMBER(10001)?;

    let predicate_data = MyPredicateEncoder::default().encode_data(1, 19)?;

    let executable =
        Executable::load_from("sway/predicates/predicate_blobs/out/release/predicate_blobs.bin")?;

    let loader = executable
        .convert_to_loader()?
        .with_configurables(configurables);

    let mut predicate: Predicate = Predicate::from_code(loader.code()).with_data(predicate_data);
```

Once you want to execute the predicate, you must beforehand upload the blob
containing its code:

```rust,ignore
    loader.upload_blob(extra_wallet).await?;
    predicate.set_provider(provider.clone());

    let amount_to_send = 42;
    let response = predicate
        .transfer(
            receiver.address(),
            amount_to_send,
            asset_id,
            TxPolicies::default(),
        )
        .await?;
```

By pre-uploading the predicate code, you allow for cheaper calls to the predicate
from subsequent callers.


---

### File: docs/nightly/fuels-rs/docs/src/reference.md

# API Reference

For a more in-depth look at the APIs provided by the Fuel Rust SDK, head over to the [official documentation](https://docs.rs/fuels/latest/fuels/). In the actual Rust docs, you can see the most up-to-date information about the API, which is synced with the code as it changes.


---

### File: docs/nightly/fuels-rs/docs/src/running-scripts.md

# Running scripts

You can run a script using its JSON-ABI and the path to its binary file. You can run the scripts with arguments. For this, you have to use the `abigen!` macro seen [previously](./abigen/the-abigen-macro.md).

```rust,ignore
    // The abigen is used for the same purpose as with contracts (Rust bindings)
    abigen!(Script(
        name = "MyScript",
        abi = "e2e/sway/scripts/arguments/out/release/arguments-abi.json"
    ));
    let wallet = launch_provider_and_get_wallet().await?;
    let bin_path = "sway/scripts/arguments/out/release/arguments.bin";
    let script_instance = MyScript::new(wallet, bin_path);

    let bim = Bimbam { val: 90 };
    let bam = SugarySnack {
        twix: 100,
        mars: 1000,
    };

    let result = script_instance.main(bim, bam).call().await?;

    let expected = Bimbam { val: 2190 };
    assert_eq!(result.value, expected);
```

Furthermore, if you need to separate submission from value retrieval for any reason, you can do so as follows:

```rust,ignore
    let submitted_tx = script_instance.main(my_struct).submit().await?;
    tokio::time::sleep(Duration::from_millis(500)).await;
    let value = submitted_tx.response().await?.value;
```

## Running scripts with transaction policies

The method for passing transaction policies is the same as [with contracts](./calling-contracts/tx-policies.md). As a reminder, the workflow would look like this:

```rust,ignore
    let tx_policies = TxPolicies::default().with_script_gas_limit(1_000_000);
    let result = script_instance
        .main(a, b)
        .with_tx_policies(tx_policies)
        .call()
        .await?;
```

## Custom inputs and outputs

If you need to add specific inputs and outputs to script calls, you can use the `with_inputs` and `with_outputs` methods.

```rust,ignore
        let _ = script_instance
            .main(0, 0)
            .with_inputs(custom_inputs)
            .with_outputs(custom_output)
            .add_signer(wallet_1.signer().clone())
            .call()
            .await?;
```

> **Note:** if custom inputs include coins that need to be signed, use the `add_signer` method to add the appropriate signer.

## Logs

Script calls provide the same logging functions, `decode_logs()` and `decode_logs_with_type<T>()`, as contract calls. As a reminder, the workflow looks like this:

```rust,ignore
    abigen!(Script(
        name = "LogScript",
        abi = "e2e/sway/logs/script_logs/out/release/script_logs-abi.json"
    ));

    let wallet = launch_provider_and_get_wallet().await?;
    let bin_path = "sway/logs/script_logs/out/release/script_logs.bin";
    let instance = LogScript::new(wallet.clone(), bin_path);

    let response = instance.main().call().await?;

    let logs = response.decode_logs();
    let log_u64 = response.decode_logs_with_type::<u64>()?;
```

## Calling contracts from scripts

Scripts use the same interfaces for setting external contracts as [contract methods](./calling-contracts/other-contracts.md).

Below is an example that uses `with_contracts(&[&contract_instance, ...])`.

```rust,ignore
    let response = script_instance
        .main(contract_id, MatchEnum::Logs)
        .with_contract_ids(&[contract_id])
        .call()
        .await?;
    let response = script_instance
        .main(contract_id, MatchEnum::Logs)
        .with_contracts(&[&contract_instance])
        .call()
        .await?;
```

And this is an example that uses `with_contract_ids(&[&contract_id, ...])`.

```rust,ignore
    let response = script_instance
        .main(contract_id, MatchEnum::Logs)
        .with_contract_ids(&[contract_id])
        .call()
        .await?;
```

## Configurable constants

Same as contracts, you can define `configurable` constants in `scripts` which can be changed during the script execution. Here is an example how the constants are defined.

```rust,ignore
script;

#[allow(dead_code)]
enum EnumWithGeneric<D> {
    VariantOne: D,
    VariantTwo: (),
}

struct StructWithGeneric<D> {
    field_1: D,
    field_2: u64,
}

configurable {
    BOOL: bool = true,
    U8: u8 = 8,
    U16: u16 = 16,
    U32: u32 = 32,
    U64: u64 = 63,
    U256: u256 = 0x0000000000000000000000000000000000000000000000000000000000000008u256,
    B256: b256 = 0x0101010101010101010101010101010101010101010101010101010101010101,
    STR_4: str[4] = __to_str_array("fuel"),
    TUPLE: (u8, bool) = (8, true),
    ARRAY: [u32; 3] = [253, 254, 255],
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}
//U128: u128 = 128, //TODO: add once https://github.com/FuelLabs/sway/issues/5356 is done

fn main() -> (bool, u8, u16, u32, u64, u256, b256, str[4], (u8, bool), [u32; 3], StructWithGeneric<u8>, EnumWithGeneric<bool>) {
    (BOOL, U8, U16, U32, U64, U256, B256, STR_4, TUPLE, ARRAY, STRUCT, ENUM)
}

```

Each configurable constant will get a dedicated `with` method in the SDK. For example, the constant `STR_4` will get the `with_STR_4` method which accepts the same type defined in sway. Below is an example where we chain several `with` methods and execute the script with the new constants.

```rust,ignore
    abigen!(Script(
        name = "MyScript",
        abi = "e2e/sway/scripts/script_configurables/out/release/script_configurables-abi.json"
    ));

    let wallet = launch_provider_and_get_wallet().await?;
    let bin_path = "sway/scripts/script_configurables/out/release/script_configurables.bin";
    let instance = MyScript::new(wallet, bin_path);

    let str_4: SizedAsciiString<4> = "FUEL".try_into()?;
    let new_struct = StructWithGeneric {
        field_1: 16u8,
        field_2: 32,
    };
    let new_enum = EnumWithGeneric::VariantTwo;

    let configurables = MyScriptConfigurables::new(EncoderConfig {
        max_tokens: 5,
        ..Default::default()
    })
    .with_BOOL(false)?
    .with_U8(7)?
    .with_U16(15)?
    .with_U32(31)?
    .with_U64(63)?
    .with_U256(U256::from(8))?
    .with_B256(Bits256([2; 32]))?
    .with_STR_4(str_4.clone())?
    .with_TUPLE((7, false))?
    .with_ARRAY([252, 253, 254])?
    .with_STRUCT(new_struct.clone())?
    .with_ENUM(new_enum.clone())?;

    let response = instance
        .with_configurables(configurables)
        .main()
        .call()
        .await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/testing/basics.md

# Testing Basics

If you're new to Rust, you'll want to review these important tools to help you build tests.

## The `assert!` macro

<!-- This section should explain the `assert!` macro -->
<!-- assert:example:start -->

You can use the `assert!` macro to assert certain conditions in your test. This macro invokes `panic!()` and fails the test if the expression inside evaluates to `false`.

<!-- assert:example:end -->

<!-- This section should show an example of the `assert!` macro -->
<!-- assert_code:example:start -->

```rust, ignore
assert!(value == 5);
```

<!-- assert_code:example:end -->

## The `assert_eq!` macro

<!-- This section should show an example of the `assert_eq!` macro -->
<!-- assert_eq:example:start -->

The `assert_eq!` macro works a lot like the `assert` macro, however instead it accepts two values, and panics if those values are not equal.

<!-- assert_eq:example:end -->

<!-- This section should show an example of the `assert_eq!` macro -->
<!-- assert_eq_code:example:start -->

```rust, ignore
assert_eq!(balance, 100);
```

<!-- assert_eq_code:example:end -->

## The `assert_ne!` macro

<!-- This section should show an example of the `assert_ne!` macro -->
<!-- assert_ne:example:start -->

The `assert_ne!` macro works just like the `assert_eq!` macro, but it will panic if the two values are equal.

<!-- assert_ne:example:end -->

<!-- This section should show an example of the `assert_ne!` macro -->
<!-- assert_ne_code:example:start -->

```rust, ignore
assert_ne!(address, 0);
```

<!-- assert_ne_code:example:end -->

## The `println!` macro

<!-- This section should explain how the `println!` macro can be used in tests -->
<!--print_ln:example:start -->

You can use the `println!` macro to print values to the console.

<!--print_ln:example:end -->

<!-- This section should show an example of the `println!` macro -->
<!--print_ln_code:example:start -->

```rust, ignore
println!("WALLET 1 ADDRESS {}", wallet_1.address());
println!("WALLET 1 ADDRESS {:?}", wallet_1.address());
```

<!--print_ln_code:example:end -->

<!-- This section should explain how `{}` and `{:?}` are used in the `println!` macro -->
<!--print_ln_2:example:start -->

Using `{}` will print the value, and using `{:?}` will print the value plus its type.

Using `{:?}` will also allow you to print values that do not have the `Display` trait implemented but do have the `Debug` trait. Alternatively you can use the `dbg!` macro to print these types of variables.

<!--print_ln_2:example:end -->

<!-- This section should show an example of the `println!` and `dbg` macros -->
<!--print_ln_dbg_code:example:start -->

```rust, ignore
println!("WALLET 1 PROVIDER {:?}", wallet_1.provider());
dbg!("WALLET 1 PROVIDER {}", wallet_1.provider());
```

<!--print_ln_dbg_code:example:end -->

<!-- This section should explain how implement custom fmt -->
<!--fmt:example:start -->

To print more complex types that don't have it already, you can implement your own formatted display method with the `fmt` module from the Rust standard library.

<!--fmt:example:end -->

<!-- This section should show a code example of how implement custom fmt -->
<!--fmt_code:example:start -->

```rust, ignore
use std::fmt;

struct Point {
    x: u64,
    y: u64,
}

// add print functionality with the fmt module
impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "value of x: {}, value of y: {}", self.x, self.y)
    }
}

let p = Point {x: 1, y: 2};
println!("POINT: {}", p);
```

<!--fmt_code:example:end -->

## Run Commands

You can run your tests to see if they pass or fail with

```shell
cargo test
```

<!-- This section should when outputs are hidden and what the `nocapture` flag does -->
<!--outputs:example:start -->

Outputs will be hidden if the test passes. If you want to see outputs printed from your tests regardless of whether they pass or fail, use the `nocapture` flag.

<!--outputs:example:end -->

```shell
cargo test -- --nocapture
```


---

### File: docs/nightly/fuels-rs/docs/src/testing/chains.md

# Increasing the block height

You can use `produce_blocks` to help achieve an arbitrary block height; this is useful when you want to do any testing regarding transaction maturity.

> **Note**: For the `produce_blocks` API to work, it is imperative to have `manual_blocks_enabled = true` in the config for the running node. See example below.

```rust,ignore
    let wallets =
        launch_custom_provider_and_get_wallets(WalletsConfig::default(), None, None).await?;
    let wallet = &wallets[0];
    let provider = wallet.provider();

    assert_eq!(provider.latest_block_height().await?, 0u32);

    provider.produce_blocks(3, None).await?;

    assert_eq!(provider.latest_block_height().await?, 3u32);
```

You can also set a custom block time as the second, optional argument. Here is an example:

```rust,ignore
    let block_time = 20u32; // seconds
    let config = NodeConfig {
        // This is how you specify the time between blocks
        block_production: Trigger::Interval {
            block_time: std::time::Duration::from_secs(block_time.into()),
        },
        ..NodeConfig::default()
    };
    let wallets =
        launch_custom_provider_and_get_wallets(WalletsConfig::default(), Some(config), None)
            .await?;
    let wallet = &wallets[0];
    let provider = wallet.provider();

    assert_eq!(provider.latest_block_height().await?, 0u32);
    let origin_block_time = provider.latest_block_time().await?.unwrap();
    let blocks_to_produce = 3;

    provider.produce_blocks(blocks_to_produce, None).await?;
    assert_eq!(provider.latest_block_height().await?, blocks_to_produce);
    let expected_latest_block_time = origin_block_time
        .checked_add_signed(Duration::try_seconds((blocks_to_produce * block_time) as i64).unwrap())
        .unwrap();
    assert_eq!(
        provider.latest_block_time().await?.unwrap(),
        expected_latest_block_time
    );
```


---

### File: docs/nightly/fuels-rs/docs/src/testing/index.md

# `fuels-rs` Testing

> **note** This section is still a work in progress.

- [Testing Basics](./basics.md)
- [`setup_program_test!` Macro](./the-setup-program-test-macro.md)
- [Tweaking the Blockchain](./chains.md)


---

### File: docs/nightly/fuels-rs/docs/src/testing/the-setup-program-test-macro.md

# The setup_program_test! macro

When deploying contracts with the `abigen!` macro, as shown in the previous sections, the user can:

- change the default configuration parameters
- launch several providers
- create multiple wallets
- create specific assets, etc.

However, it is often the case that we want to quickly set up a test with default values and work directly with contract or script instances. The `setup_program_test!` can do exactly that.

---

Used to reduce boilerplate in integration tests. Accepts input in the form
of `COMMAND(ARG...)...`

`COMMAND` is either `Wallets`, `Abigen`, `LoadScript` or `Deploy`.

`ARG` is either a:

- name-value (e.g. `name="MyContract"`), or,
- a literal (e.g. `"some_str_literal"`, `true`, `5`, ...)
- a sub-command (e.g. `Abigen(Contract(name="MyContract", project="some_project"))`)

Available `COMMAND`s:

## Options

Example: `Options(profile="debug")`

Description: Sets options from `ARG`s to be used by other `COMMAND`s.

Available options:

- `profile`: sets the `cargo` build profile. Variants: `"release"` (default),  `"debug"`

Cardinality: 0 or 1.

## Wallets

Example: `Wallets("a_wallet", "another_wallet"...)`

Description: Launches a local provider and generates wallets with names taken from the provided `ARG`s.

Cardinality: 0 or 1.

## Abigen

Example:

```rust,ignore
Abigen(
    Contract(
        name = "MyContract",
        project = "some_folder"
    ),
    Script(
        name = "MyScript",
        project = "some_folder"
    ),
    Predicate(
        name = "MyPredicate",
        project = "some_folder"
    ),
)
```

Description: Generates the program bindings under the name `name`. `project` should point to root of the `forc` project. The project must be compiled in `release` mode (`--release` flag) for `Abigen` command to work.

Cardinality: 0 or N.

## Deploy

Example: `Deploy(name="instance_name", contract="MyContract", wallet="a_wallet")`

Description: Deploys the `contract` (with salt) using `wallet`. Will create a contract instance accessible via `name`. Due to salt usage, the same contract can be deployed multiple times. Requires that an `Abigen` command be present with `name` equal to `contract`. `wallet` can either be one of the wallets in the `Wallets` `COMMAND` or the name of a wallet you've previously generated yourself.

Cardinality: 0 or N.

## `LoadScript`

Example: `LoadScript(name = "script_instance", script = "MyScript", wallet = "wallet")`

Description: Creates a script instance of `script` under `name` using `wallet`.

Cardinality: 0 or N.

---

The setup code that you have seen in previous sections gets reduced to:

```rust,ignore
        setup_program_test!(
            Wallets("wallet"),
            Abigen(Contract(
                name = "TestContract",
                project = "e2e/sway/contracts/contract_test"
            )),
            Deploy(
                name = "contract_instance",
                contract = "TestContract",
                wallet = "wallet"
            ),
        );

        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .call()
            .await?;

        assert_eq!(42, response.value);
```

> **Note** The same contract can be deployed several times as the macro deploys the contracts with salt. You can also deploy different contracts to the same provider by referencing the same wallet in the `Deploy` command.

```rust,ignore
    setup_program_test!(
        Wallets("wallet"),
        Abigen(
            Contract(
                name = "LibContract",
                project = "e2e/sway/contracts/lib_contract"
            ),
            Contract(
                name = "LibContractCaller",
                project = "e2e/sway/contracts/lib_contract_caller"
            ),
        ),
        Deploy(
            name = "lib_contract_instance",
            contract = "LibContract",
            wallet = "wallet",
            random_salt = false,
        ),
        Deploy(
            name = "contract_caller_instance",
            contract = "LibContractCaller",
            wallet = "wallet",
        ),
        Deploy(
            name = "contract_caller_instance2",
            contract = "LibContractCaller",
            wallet = "wallet",
        ),
    );
    let lib_contract_id = lib_contract_instance.contract_id();

    let contract_caller_id = contract_caller_instance.contract_id();

    let contract_caller_id2 = contract_caller_instance2.contract_id();

    // Because we deploy with salt, we can deploy the same contract multiple times
    assert_ne!(contract_caller_id, contract_caller_id2);

    // The first contract can be called because they were deployed on the same provider
    let response = contract_caller_instance
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contracts(&[&lib_contract_instance])
        .call()
        .await?;

    assert_eq!(43, response.value);

    let response = contract_caller_instance2
        .methods()
        .increment_from_contract(lib_contract_id, 42)
        .with_contracts(&[&lib_contract_instance])
        .call()
        .await?;

    assert_eq!(43, response.value);
```

In this example, three contracts are deployed on the same provider using the `wallet` generated by the `Wallets` command. The second and third macros use the same contract but have different IDs because of the deployment with salt. Both of them can call the first contract by using their ID.

In addition, you can manually create the `wallet` variable and then use it inside the macro. This is useful if you want to create custom wallets or providers but still want to use the macro to reduce boilerplate code. Below is an example of this approach.

```rust,ignore
    let config = WalletsConfig::new(Some(2), Some(1), Some(DEFAULT_COIN_AMOUNT));

    let mut wallets = launch_custom_provider_and_get_wallets(config, None, None).await?;
    let wallet = wallets.pop().unwrap();
    let wallet_2 = wallets.pop().unwrap();

    setup_program_test!(
        Abigen(Contract(
            name = "TestContract",
            project = "e2e/sway/contracts/contract_test"
        )),
        Deploy(
            name = "contract_instance",
            contract = "TestContract",
            wallet = "wallet",
            random_salt = false,
        ),
    );
```


---

### File: docs/nightly/fuels-rs/docs/src/types/B512.md

# `B512`

In the Rust SDK, the `B512` definition matches the Sway standard library type with the same name and will be converted accordingly when interacting with contracts:

```rust,ignore
pub struct B512 {
    pub bytes: [Bits256; 2],
}
```

Here's an example:

```rust,ignore
    let hi_bits = Bits256::from_hex_str(
        "0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c",
    )?;
    let lo_bits = Bits256::from_hex_str(
        "0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d",
    )?;
    let b512 = B512::from((hi_bits, lo_bits));
```


---

### File: docs/nightly/fuels-rs/docs/src/types/address.md

# `Address`

Like `Bytes32`, `Address` is a wrapper on `[u8; 32]` with similar methods and implements the same traits (see [fuel-types documentation](https://docs.rs/fuel-types/latest/fuel_types/struct.Address.html)).

These are the main ways of creating an `Address`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::Address;

        // Zeroed Bytes32
        let address = Address::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *address);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_address
        let my_slice = [1u8; 32];
        let address = Address::new(my_slice);
        // ANCHOR_END: array_to_address
        assert_eq!([1u8; 32], *address);

        // From a string.
        // ANCHOR: hex_string_to_address
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let address = Address::from_str(hex_str)?;
        // ANCHOR_END: hex_string_to_address
        assert_eq!([0u8; 32], *address);
        let _identity_from_address = Identity::Address(address);
        let _str_from_address: &str = address.to_string().as_str();
        let bits_256 = Bits256(address.into());
```


---

### File: docs/nightly/fuels-rs/docs/src/types/asset-id.md

# `AssetId`

Like `Bytes32`, `AssetId` is a wrapper on `[u8; 32]` with similar methods and implements the same traits (see [fuel-types documentation](https://docs.rs/fuel-types/0.49.0/fuel_types/struct.AssetId.html)).

These are the main ways of creating an `AssetId`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::AssetId;

        // Zeroed Bytes32
        let asset_id = AssetId::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *asset_id);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_asset_id
        let my_slice = [1u8; 32];
        let asset_id = AssetId::new(my_slice);
        // ANCHOR_END: array_to_asset_id
        assert_eq!([1u8; 32], *asset_id);

        // From a string.
        // ANCHOR: string_to_asset_id
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let asset_id = AssetId::from_str(hex_str)?;
        // ANCHOR_END: string_to_asset_id
        assert_eq!([0u8; 32], *asset_id);
        let _str_from_asset_id: &str = asset_id.to_string().as_str();
        let _asset_id_to_bits_256 = Bits256(asset_id.into());
```


---

### File: docs/nightly/fuels-rs/docs/src/types/bits256.md

# `Bits256`

In Fuel, a type called `b256` represents hashes and holds a 256-bit value. The Rust SDK represents `b256` as `Bits256(value)` where `value` is a `[u8; 32]`. If your contract method takes a `b256` as input, you must pass a `Bits256([u8; 32])` when calling it from the SDK.

Here's an example:

```rust,ignore
        let b256 = Bits256([1; 32]);

        let call_handler = contract_instance.methods().b256_as_input(b256);
```

If you have a hexadecimal value as a string and wish to convert it to `Bits256`, you may do so with `from_hex_str`:

```rust,ignore
        let hex_str = "0101010101010101010101010101010101010101010101010101010101010101";

        let bits256 = Bits256::from_hex_str(hex_str)?;

        assert_eq!(bits256.0, [1u8; 32]);

        // With the `0x0` prefix
        // ANCHOR: hex_str_to_bits256
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bits256 = Bits256::from_hex_str(hex_str)?;
        // ANCHOR_END: hex_str_to_bits256

        assert_eq!(bits256.0, [1u8; 32]);
```


---

### File: docs/nightly/fuels-rs/docs/src/types/bytes.md

# `Bytes`

In Fuel, a type called `Bytes` represents a collection of tightly-packed bytes. The Rust SDK represents `Bytes` as `Bytes(Vec<u8>)`. Here's an example of using `Bytes` in a contract call:

```rust,ignore
        let bytes = Bytes(vec![40, 41, 42]);

        contract_methods.accept_bytes(bytes).call().await?;
```

If you have a hexadecimal value as a string and wish to convert it to `Bytes`, you may do so with `from_hex_str`:

```rust,ignore
        let hex_str = "0101010101010101010101010101010101010101010101010101010101010101";

        let bytes = Bytes::from_hex_str(hex_str)?;

        assert_eq!(bytes.0, vec![1u8; 32]);

        // With the `0x0` prefix
        // ANCHOR: hex_string_to_bytes32
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bytes = Bytes::from_hex_str(hex_str)?;
        // ANCHOR_END: hex_string_to_bytes32

        assert_eq!(bytes.0, vec![1u8; 32]);
```


---

### File: docs/nightly/fuels-rs/docs/src/types/bytes32.md

# `Bytes32`

In Sway and the FuelVM, `Bytes32` represents hashes. They hold a 256-bit (32-byte) value. `Bytes32` is a wrapper on a 32-sized slice of `u8`: `pub struct Bytes32([u8; 32]);`.

These are the main ways of creating a `Bytes32`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::Bytes32;

        // Zeroed Bytes32
        let b256 = Bytes32::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *b256);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_bytes32
        let my_slice = [1u8; 32];
        let b256 = Bytes32::new(my_slice);
        // ANCHOR_END: array_to_bytes32
        assert_eq!([1u8; 32], *b256);

        // From a hex string.
        // ANCHOR: hex_string_to_bytes32
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let b256 = Bytes32::from_str(hex_str)?;
        // ANCHOR_END: hex_string_to_bytes32
        assert_eq!([0u8; 32], *b256);
        let b256_string = b256.to_string();
        let b256_hex_string = format!("{b256:#x}");
        let _str_from_bytes32: &str = b256.to_string().as_str();
```

`Bytes32` also implements the `fmt` module's `Debug`, `Display`, `LowerHex` and `UpperHex` traits. For example, you can get the display and hex representations with:

```rust,ignore
        let b256_string = b256.to_string();
        let b256_hex_string = format!("{b256:#x}");
```

For a full list of implemented methods and traits, see the [fuel-types documentation](https://docs.rs/fuel-types/latest/fuel_types/struct.Bytes32.html).

> **Note:** In Fuel, there's a special type called `b256`, which is similar to `Bytes32`; also used to represent hashes, and it holds a 256-bit value. In Rust, through the SDK, this is represented as `Bits256(value)` where `value` is a `[u8; 32]`. If your contract method takes a `b256` as input, all you need to do is pass a `Bits256([u8; 32])` when calling it from the SDK.


---

### File: docs/nightly/fuels-rs/docs/src/types/contract-id.md

# `ContractId`

Like `Bytes32`, `ContractId` is a wrapper on `[u8; 32]` with similar methods and implements the same traits (see [fuel-types documentation](https://docs.rs/fuel-types/0.49.0/fuel_types/struct.ContractId.html)).

These are the main ways of creating a `ContractId`:

```rust,ignore
        use std::str::FromStr;

        use fuels::types::ContractId;

        // Zeroed Bytes32
        let contract_id = ContractId::zeroed();

        // Grab the inner `[u8; 32]` from
        // `Bytes32` by dereferencing (i.e. `*`) it.
        assert_eq!([0u8; 32], *contract_id);

        // From a `[u8; 32]`.
        // ANCHOR: array_to_contract_id
        let my_slice = [1u8; 32];
        let contract_id = ContractId::new(my_slice);
        // ANCHOR_END: array_to_contract_id
        assert_eq!([1u8; 32], *contract_id);

        // From a string.
        // ANCHOR: string_to_contract_id
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let contract_id = ContractId::from_str(hex_str)?;
        // ANCHOR_END: string_to_contract_id
        assert_eq!([0u8; 32], *contract_id);
        let _identity_from_contract_id = Identity::ContractId(contract_id);
        let _str_from_contract_id: &str = contract_id.to_string().as_str();
        let _contract_id_to_bits_256 = Bits256(contract_id.into());
```


---

### File: docs/nightly/fuels-rs/docs/src/types/conversion.md

# Converting Types

Below you can find examples for common type conversions:

- [Convert Between Native Types](#convert-between-native-types)
- [Convert to `Bytes32`](#convert-to-bytes32)
- [Convert to `Address`](#convert-to-address)
- [Convert to `ContractId`](#convert-to-contractid)
- [Convert to `Identity`](#convert-to-identity)
- [Convert to `AssetId`](#convert-to-assetid)
- [Convert to `str`](#convert-to-str)
- [Convert to `Bits256`](#convert-to-bits256)
- [Convert to `Bytes`](#convert-to-bytes)
- [Convert to `B512`](#convert-to-b512)
- [Convert to `EvmAddress`](#convert-to-evmaddress)

## Convert Between Native Types

You might want to convert between the native types (`Bytes32`, `Address`, `ContractId`, and `AssetId`). Because these types are wrappers on `[u8; 32]`, converting is a matter of dereferencing one and instantiating the other using the dereferenced value. Here's an example:

```rust,ignore
        use fuels::types::{AssetId, ContractId};

        let contract_id = ContractId::new([1u8; 32]);

        let asset_id: AssetId = AssetId::new(*contract_id);

        assert_eq!([1u8; 32], *asset_id);
```

## Convert to `Bytes32`

Convert a `[u8; 32]` array to `Bytes32`:

```rust,ignore
        let my_slice = [1u8; 32];
        let b256 = Bytes32::new(my_slice);
```

Convert a hex string to `Bytes32`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let b256 = Bytes32::from_str(hex_str)?;
```

## Convert to `Address`

Convert a `[u8; 32]` array to an `Address`:

```rust,ignore
        let my_slice = [1u8; 32];
        let address = Address::new(my_slice);
```

Convert a wallet to an `Address`:

```rust,ignore
        let wallet = Wallet::random(&mut rng, provider);
        let address: Address = wallet.address();
```

Convert a hex string to an `Address`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let address = Address::from_str(hex_str)?;
```

## Convert to `ContractId`

Convert a `[u8; 32]` array to `ContractId`:

```rust,ignore
        let my_slice = [1u8; 32];
        let contract_id = ContractId::new(my_slice);
```

Convert a hex string to a `ContractId`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let contract_id = ContractId::from_str(hex_str)?;
```

Convert a contract instance to a `ContractId`:

```rust,ignore
    let contract_id: ContractId = contract_instance.contract_id();
```

## Convert to `Identity`

Convert an `Address` to an `Identity`:

```rust,ignore
        let _identity_from_address = Identity::Address(address);
```

Convert a `ContractId` to an `Identity`:

```rust,ignore
        let _identity_from_contract_id = Identity::ContractId(contract_id);
```

## Convert to `AssetId`

Convert a `[u8; 32]` array to an `AssetId`:

```rust,ignore
        let my_slice = [1u8; 32];
        let asset_id = AssetId::new(my_slice);
```

Convert a hex string to an `AssetId`:

```rust,ignore
        let hex_str = "0x0000000000000000000000000000000000000000000000000000000000000000";
        let asset_id = AssetId::from_str(hex_str)?;
```

## Convert to `str`

Convert a `ContractId` to a `str`:

```rust,ignore
        let _str_from_contract_id: &str = contract_id.to_string().as_str();
```

Convert an `Address` to a `str`:

```rust,ignore
        let _str_from_address: &str = address.to_string().as_str();
```

Convert an `AssetId` to a `str`:

```rust,ignore
        let _str_from_asset_id: &str = asset_id.to_string().as_str();
```

Convert `Bytes32` to a `str`:

```rust,ignore
        let _str_from_bytes32: &str = b256.to_string().as_str();
```

## Convert to `Bits256`

Convert a hex string to `Bits256`:

```rust,ignore
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bits256 = Bits256::from_hex_str(hex_str)?;
```

Convert a `ContractId` to `Bits256`:

```rust,ignore
        let _contract_id_to_bits_256 = Bits256(contract_id.into());
```

Convert an `Address` to `Bits256`:

```rust,ignore
        let bits_256 = Bits256(address.into());
```

Convert an `AssetId` to `Bits256`:

```rust,ignore
        let _asset_id_to_bits_256 = Bits256(asset_id.into());
```

## Convert to `Bytes`

Convert a string to `Bytes`:

```rust,ignore
        let hex_str = "0x0101010101010101010101010101010101010101010101010101010101010101";

        let bytes = Bytes::from_hex_str(hex_str)?;
```

## Convert to `B512`

Convert two hex strings to `B512`:

```rust,ignore
    let hi_bits = Bits256::from_hex_str(
        "0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c",
    )?;
    let lo_bits = Bits256::from_hex_str(
        "0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d",
    )?;
    let b512 = B512::from((hi_bits, lo_bits));
```

## Convert to `EvmAddress`

Convert a `Bits256` address to an `EvmAddress`:

```rust,ignore
        let _evm_address = EvmAddress::from(bits_256);
```


---

### File: docs/nightly/fuels-rs/docs/src/types/custom_types.md

# Structs and enums

<!-- This section should explain how to get the custom types from a Sway program -->
<!-- custom_types:example:start -->
The structs and enums you define in your Sway code have equivalents automatically generated by the SDK's `abigen!` macro.
<!-- custom_types:example:end -->

For instance, if in your Sway code you have a struct called `CounterConfig` that looks like this:

```rust,ignore
struct CounterConfig {
  dummy: bool,
  initial_value: u64,
}
```

After using the `abigen!` macro, `CounterConfig` will be accessible in your Rust file! Here's an example:

```rust,ignore
    abigen!(Contract(
        name = "MyContract",
        abi = "e2e/sway/types/contracts/complex_types_contract/out/release/complex_types_contract-abi.json"
    ));

    // Here we can use `CounterConfig`, a struct originally
    // defined in the contract.
    let counter_config = CounterConfig {
        dummy: true,
        initial_value: 42,
    };
```

You can freely use your custom types (structs or enums) within this scope. That also means passing custom types to functions and receiving custom types from function calls.

## Generics

The Fuel Rust SDK supports both generic enums and generic structs. If you're already familiar with Rust, it's your typical `struct MyStruct<T>` type of generics support.

For instance, your Sway contract could look like this:

```Rust
contract;

use std::hash::sha256;

struct SimpleGeneric<T> {
    single_generic_param: T,
}

abi MyContract {
  fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64>;
}

impl MyContract for Contract {
    fn struct_w_generic(arg1: SimpleGeneric<u64>) -> SimpleGeneric<u64> {
        let expected = SimpleGeneric {
            single_generic_param: 123u64,
        };

        assert(arg1.single_generic_param == expected.single_generic_param);

        expected
    }
}
```

Your Rust code would look like this:

```rust,ignore
        // simple struct with a single generic param
        let arg1 = SimpleGeneric {
            single_generic_param: 123u64,
        };

        let result = contract_methods
            .struct_w_generic(arg1.clone())
            .call()
            .await?
            .value;

        assert_eq!(result, arg1);
```

### Unused generic type parameters

Sway supports unused generic type parameters when declaring structs/enums:

```Rust
struct SomeStruct<T, K> {
  field: u64
}

enum SomeEnum<T, K> {
  One: u64
}

```

If you tried the same in Rust you'd get complaints that `T` and `K` must be used or removed. When generating Rust bindings for such types we make use of the [`PhantomData`](https://doc.rust-lang.org/std/marker/struct.PhantomData.html#unused-type-parameters) type. The generated bindings for the above example would look something like this:

```Rust
struct SomeStruct<T, K> {
   pub field: u64,
   pub _unused_generic_0: PhantomData<T>
   pub _unused_generic_1: PhantomData<K>
}

enum SomeEnum<T, K> {
  One(u64),
  IgnoreMe(PhantomData<T>, PhantomData<K>)
}
```

To lessen the impact to developer experience you may use the `new` method to initialize a structure without bothering with the `PhantomData`s.:

```rust,ignore
        assert_eq!(
            <StructUnusedGeneric<u16, u32>>::new(15),
            StructUnusedGeneric {
                field: 15,
                _unused_generic_0: std::marker::PhantomData,
                _unused_generic_1: std::marker::PhantomData
            }
        );
```

If your struct doesn't have any fields we'll also derive `Default`. As for enums all `PhantomData`s are placed inside a new variant called `IgnoreMe` which you'll need to ignore in your matches:

```rust,ignore
        match my_enum {
            EnumUnusedGeneric::One(_value) => {}
            EnumUnusedGeneric::IgnoreMe(..) => panic!("Will never receive this variant"),
        }
```


---

### File: docs/nightly/fuels-rs/docs/src/types/evm_address.md

# `EvmAddress`

In the Rust SDK, Ethereum Virtual Machine (EVM) addresses can be represented with the `EvmAddress` type. Its definition matches with the Sway standard library type with the same name and will be converted accordingly when interacting with contracts:

```rust,ignore
pub struct EvmAddress {
    // An evm address is only 20 bytes, the first 12 bytes should be set to 0
    value: Bits256,
}
```

Here's an example:

```rust,ignore
        let b256 = Bits256::from_hex_str(
            "0x1616060606060606060606060606060606060606060606060606060606060606",
        )?;
        let evm_address = EvmAddress::from(b256);

        let call_handler = contract_instance
            .methods()
            .evm_address_as_input(evm_address);
```

> **Note:** when creating an `EvmAddress` from `Bits256`, the first 12 bytes will be cleared because an EVM address is only 20 bytes long.


---

### File: docs/nightly/fuels-rs/docs/src/types/index.md

# Types

The FuelVM and Sway have many internal types. These types have equivalents in the SDK. This section discusses these types, how to use them, and how to convert them.


---

### File: docs/nightly/fuels-rs/docs/src/types/string.md

# `String`

The Rust SDK represents Fuel's `String`s as `SizedAsciiString<LEN>`, where the generic parameter `LEN` is the length of a given string. This abstraction is necessary because all strings in Fuel and Sway are statically-sized, i.e., you must know the size of the string beforehand.

Here's how you can create a simple string using `SizedAsciiString`:

```rust,ignore
        let ascii_data = "abc".to_string();

        SizedAsciiString::<3>::new(ascii_data)
            .expect("should have succeeded since we gave ascii data of correct length!");
```

To make working with `SizedAsciiString`s easier, you can use `try_into()` to convert from Rust's `String` to `SizedAsciiString`, and you can use `into()` to convert from `SizedAsciiString` to Rust's `String`. Here are a few examples:

```rust,ignore
    #[test]
    fn can_be_constructed_from_str_ref() {
        let _: SizedAsciiString<3> = "abc".try_into().expect("should have succeeded");
    }

    #[test]
    fn can_be_constructed_from_string() {
        let _: SizedAsciiString<3> = "abc".to_string().try_into().expect("should have succeeded");
    }

    #[test]
    fn can_be_converted_into_string() {
        let sized_str = SizedAsciiString::<3>::new("abc".to_string()).unwrap();

        let str: String = sized_str.into();

        assert_eq!(str, "abc");
    }
```

If your contract's method takes and returns, for instance, a Sway's `str[23]`. When using the SDK, this method will take and return a `SizedAsciiString<23>`.


---

### File: docs/nightly/fuels-rs/docs/src/types/vectors.md

# Vectors

## Passing in vectors

You can pass a Rust `std::vec::Vec` into your contract method transparently. The following code calls a Sway contract method which accepts a `Vec<SomeStruct<u32>>`.

```rust,ignore
        let arg = vec![SomeStruct { a: 0 }, SomeStruct { a: 1 }];
        methods.struct_in_vec(arg.clone()).call().await?;
```

You can use a vector just like you would use any other type -- e.g. a `[Vec<u32>; 2]` or a `SomeStruct<Vec<Bits256>>` etc.

## Returning vectors

Returning vectors from contract methods is supported transparently, with the caveat that you cannot have them nested inside another type. This limitation is temporary.

```rust,ignore
    let response = contract_methods.u8_in_vec(10).call().await?;
    assert_eq!(response.value, (0..10).collect::<Vec<_>>());
```

> **Note: you can still interact with contracts containing methods that return vectors nested inside another type, just not interact with the methods themselves**


---

### File: docs/nightly/fuels-rs/docs/src/wallets/access.md

# Wallet Access

The kinds of operations we can perform with a `Wallet` instance depend on
whether or not the wallet has a signer attached to it.

In order to differentiate between `Wallet` instances that have a signer
and those that do not, we use the `Wallet<Unlocked<S>>` and `Wallet<Locked>` types
respectively.

## Wallet States

The `Wallet<Unlocked<S>>` type represents a wallet that has a signer. A wallet must be of type `Wallet<Unlocked<S>>` in order to perform operations that involve signing messages or transactions.

You can learn more about signing [here](./signing.md).

The `Wallet<Locked>` type represents a wallet without a signer. Instead, `Wallet<Locked>` only knows its public address. A `Wallet<Locked>` cannot be used to sign transactions, however it may still perform a whole suite of useful operations including listing transactions, assets, querying balances, and so on.

## Transitioning States

A `Wallet<Unlocked<S>>` instance can be locked using the `lock` method:

```rust,ignore
let wallet_locked = wallet_unlocked.lock();
```

## Design Guidelines

When designing APIs that accept a wallet as an input, we should think carefully
about the kind of access that we require. API developers should aim to minimise
their usage of `Wallet<Unlocked<S>>` in order to ensure signers are stored in
memory no longer than necessary to reduce the surface area for attacks and
vulnerabilities in downstream libraries and applications.


---

### File: docs/nightly/fuels-rs/docs/src/wallets/checking-balances-and-coins.md

# Checking balances and coins

<!-- This section should explain getting the balance of a wallet -->
<!-- balance:example:start -->
In the Fuel network, each UTXO corresponds to a unique _coin_, and said _coin_ has a corresponding _amount_ (the same way a dollar bill has either 10$ or 5$ face value). So, when you want to query the balance for a given asset ID, you want to query the sum of the amount in each unspent coin. This querying is done very easily with a wallet:
<!-- balance:example:end -->

```rust,ignore
        let asset_id = AssetId::zeroed();
        let balance: u128 = wallet.get_asset_balance(&asset_id).await?;
```

<!-- This section should explain getting all of the balances of a wallet -->
<!-- balances:example:start -->
If you want to query all the balances (i.e., get the balance for each asset ID in that wallet), you can use the `get_balances` method:
<!-- balances:example:end -->

```rust,ignore
        let balances: HashMap<String, u128> = wallet.get_balances().await?;
```

<!-- This section should explain the return type for `get_balances` -->
<!-- balances_return:example:start -->
The return type is a `HashMap`, where the key is the _asset ID's_ hex string, and the value is the corresponding balance. For example, we can get the base asset balance with:
<!-- balances_return:example:end -->

```rust,ignore
        let asset_balance = balances.get(&asset_id.to_string()).unwrap();
```


---

### File: docs/nightly/fuels-rs/docs/src/wallets/fake_signer.md

# Fake signer (impersonating another account)

To facilitate account impersonation, the Rust SDK provides the `FakeSigner`. We can use it to simulate ownership of assets held by an account with a given address. This also implies that we can impersonate contract calls from that address. A wallet with a `FakeSigner` will only succeed in unlocking assets if the network is set up with `utxo_validation = false`.

```rust,ignore
        let node_config = NodeConfig {
            utxo_validation: false,
            ..Default::default()
        };
        let provider = setup_test_provider(coins, vec![], Some(node_config), None).await?;
```

```rust,ignore
        let provider = setup_test_provider(coins, vec![], Some(node_config), None).await?;
```

```rust,ignore
        // create impersonator for an address
        let fake_signer = FakeSigner::new(some_address);
        let impersonator = Wallet::new(fake_signer, provider.clone());

        let contract_instance = MyContract::new(contract_id, impersonator.clone());

        let response = contract_instance
            .methods()
            .initialize_counter(42)
            .call()
            .await?;

        assert_eq!(42, response.value);
```


---

### File: docs/nightly/fuels-rs/docs/src/wallets/index.md

# Wallets

Wallets serve as a centralized interface for all account-related behaviors. They allow you to:

- **Inspect UTXOs:** Check available coins for spending.
- **Prepare and send transactions:** Build, sign, and submit transfers.
- **Manage network fees:** Pay for transaction execution and contract deployment.

Every wallet requires a **provider** to communicate with the network.

---

## Types of Wallets

There are two primary types of wallets available in the SDK:

### [Locked Wallets](./access.md)

- **Purpose:** Used for read-only operations.
- **Interface:** Implements the [`ViewOnlyAccount`](../accounts.md) trait.
- **Use Cases:** Checking balances, viewing UTXOs, and monitoring transactions without the ability to sign or submit transactions.

### [Unlocked Wallets](./access.md)

- **Purpose:** Supports full account functionality.
- **Interface:** Implements the [`ViewOnlyAccount`](../accounts.md) and [`Account`](../accounts.md) traits.
- **Additional Requirement:** In addition to a provider, an unlocked wallet must include a **signer**.
- **Use Cases:** Transferring funds, signing messages, submitting transactions, and performing state-changing operations.

---

## Signer Options

The SDK offers multiple signing methods to suit different scenarios:

- [**Private Key Signer:**](./private_key_signer.md)  
  Use when you have direct access to your account’s private key.
- [**AWS KMS Signer:**](./kms.md)
  Delegate signing operations to AWS Key Management Service, enhancing key security by offloading cryptographic operations.

- [**Google KMS Signer:**](./kms.md)  
  Similar to AWS KMS, this option delegates signing to Google’s Key Management Service.

- [**Fake Signer:**](./fake_signer.md)  
  Generates dummy signatures, which is useful for impersonation while testing. Only possible when using a network that does not enforce signature validation.

---


---

### File: docs/nightly/fuels-rs/docs/src/wallets/keystore.md

# Encrypting and Storing Keys

The code below shows how to:

- Encrypt and store your key using a master password.
- Ensure that the key can be retrieved later with the proper credentials.

```rust,ignore
        let dir = std::env::temp_dir();
        let keystore = Keystore::new(&dir);

        let phrase =
            "oblige salon price punch saddle immune slogan rare snap desert retire surprise";

        // Create a key from the mnemonic phrase using the default derivation path.
        let key = SecretKey::new_from_mnemonic_phrase_with_path(phrase, DEFAULT_DERIVATION_PATH)?;
        let password = "my_master_password";

        // Encrypt and store the key on disk. It can be recovered using `Keystore::load_key`.
        let uuid = keystore.save_key(key, password, thread_rng())?;

        // Recover key from disk
        let recovered_key = keystore.load_key(&uuid, password)?;
```


---

### File: docs/nightly/fuels-rs/docs/src/wallets/kms.md

# Using KMS Wallets

Key Management Service (KMS) is a robust and secure solution for managing cryptographic keys for your Fuel wallets. Instead of keeping private keys on your local system, KMS Wallets leverage secure infrastructure to handle both key storage and signing operations.

The SDK provides signers for AWS and Google KMS.

Below is an example of how to initialize a wallet with a AWS KMS signer:

```rust,ignore
        let kms_signer = AwsKmsSigner::new(your_kms_key_id, aws_client).await?;
        let wallet = Wallet::new(kms_signer, provider);
```


---

### File: docs/nightly/fuels-rs/docs/src/wallets/private_key_signer.md

# Using private keys to create wallets

## Directly from a private key

An example of how to create a wallet that uses a private key signer:

```rust,ignore
        use std::str::FromStr;

        use fuels::{crypto::SecretKey, prelude::*};

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Setup the private key.
        let secret = SecretKey::from_str(
            "5f70feeff1f229e4a95e1056e8b4d80d0b24b565674860cc213bdb07127ce1b1",
        )?;

        // Create the wallet.
        let _wallet = Wallet::new(PrivateKeySigner::new(secret), provider);
```

There is also a helper for generating a wallet with a random private key signer:

```rust,ignore
        use fuels::prelude::*;

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Create the wallet.
        let _wallet = Wallet::random(&mut thread_rng(), provider);
```

## From a mnemonic phrase

A mnemonic phrase is a cryptographically generated sequence of words used to create a master seed. This master seed, when combined with a [derivation path](https://thebitcoinmanual.com/articles/btc-derivation-path/), enables the generation of one or more specific private keys. The derivation path acts as a roadmap within the [hierarchical deterministic (HD) wallet structure](https://www.ledger.com/academy/crypto/what-are-hierarchical-deterministic-hd-wallets), determining which branch of the key tree produces the desired private key.

```rust,ignore
        use fuels::prelude::*;

        let phrase =
            "oblige salon price punch saddle immune slogan rare snap desert retire surprise";

        // Use the test helper to setup a test provider.
        let provider = setup_test_provider(vec![], vec![], None, None).await?;

        // Create first account from mnemonic phrase.
        let key =
            SecretKey::new_from_mnemonic_phrase_with_path(phrase, "m/44'/1179993420'/0'/0/0")?;
        let signer = PrivateKeySigner::new(key);
        let _wallet = Wallet::new(signer, provider.clone());

        // Or with the default derivation path.
        let key = SecretKey::new_from_mnemonic_phrase_with_path(phrase, DEFAULT_DERIVATION_PATH)?;
        let signer = PrivateKeySigner::new(key);
        let wallet = Wallet::new(signer, provider);

        let expected_address = "f18b6446deb8135544ba60333e5b7522685cd2cf64aa4e4c75df725149850b65";

        assert_eq!(wallet.address().to_string(), expected_address);
```

## Security Best Practices

- **Never Share Sensitive Information:**
  Do not disclose your private key or mnemonic phrase to anyone.

- **Secure Storage:**
  When storing keys on disk, **always encrypt** them (the SDK provides a [`Keystore`](./keystore.md). This applies to both plain private/secret keys and mnemonic phrases.


---

### File: docs/nightly/fuels-rs/docs/src/wallets/signing.md

# Signing

An example of how you might sign a message using any of the SDK signers (or your
own, custom ones, that implement `Signer`):

```rust,ignore
        let mut rng = StdRng::seed_from_u64(2322u64);
        let mut secret_seed = [0u8; 32];
        rng.fill_bytes(&mut secret_seed);

        let secret = secret_seed.as_slice().try_into()?;

        // Create a signer using the private key created above.
        let signer = PrivateKeySigner::new(secret);

        let message = Message::new("my message".as_bytes());
        let signature = signer.sign(message).await?;

        // Check if signature is what we expect it to be
        assert_eq!(
            signature,
            Signature::from_str(
                "0x8eeb238db1adea4152644f1cd827b552dfa9ab3f4939718bb45ca476d167c6512a656f4d4c7356bfb9561b14448c230c6e7e4bd781df5ee9e5999faa6495163d"
            )?
        );

        // Recover the public key that signed the message
        let recovered_pub_key: PublicKey = signature.recover(&message)?;

        assert_eq!(*signer.address, *recovered_pub_key.hash());

        // Verify signature
        signature.verify(&recovered_pub_key, &message)?;
```

## Adding `Signers` to a transaction builder

Every signed resource in the inputs needs to have a witness index that points to a valid witness. Changing the witness index inside an input will change the transaction ID. This means that we need to set all witness indexes before finally signing the transaction. We have to make sure that the witness indexes and the order of the witnesses are correct. To automate this process, the SDK will keep track of the signers in the transaction builder and resolve the final transaction automatically. This is done by storing signers until the final transaction is built.

Below is a full example of how to create a transaction builder and add signers to it.

> Note: When you add a `Signer` to a transaction builder, the signer is stored inside it and the transaction will not be resolved until you call `build()`!

```rust,ignore
        let secret = SecretKey::from_str(
            "5f70feeff1f229e4a95e1056e8b4d80d0b24b565674860cc213bdb07127ce1b1",
        )?;
        let signer = PrivateKeySigner::new(secret);

        // Set up a transaction
        let mut tb = {
            let input_coin = Input::ResourceSigned {
                resource: CoinType::Coin(Coin {
                    amount: 10000000,
                    owner: signer.address(),
                    ..Default::default()
                }),
            };

            let output_coin = Output::coin(
                Address::from_str(
                    "0xc7862855b418ba8f58878db434b21053a61a2025209889cc115989e8040ff077",
                )?,
                1,
                Default::default(),
            );
            let change = Output::change(signer.address(), 0, Default::default());

            ScriptTransactionBuilder::prepare_transfer(
                vec![input_coin],
                vec![output_coin, change],
                Default::default(),
            )
        };

        // Add `Signer` to the transaction builder
        tb.add_signer(signer.clone())?;
```

## Signing a built transaction

If you have a built transaction and want to add a signature, you can use the `sign_with` method.

```rust,ignore
    tx.sign_with(wallet.signer(), consensus_parameters.chain_id())
        .await?;
```


---

### File: docs/nightly/fuels-rs/docs/src/wallets/test-wallets.md

# Setting up test wallets

You'll often want to create one or more test wallets when testing your contracts. Here's how to do it.

## Setting up multiple test wallets

<!-- This section should explain setting up multiple test wallets -->
<!-- test_wallets:example:start -->
If you need multiple test wallets, they can be set up using the `launch_custom_provider_and_get_wallets` method.
<!-- test_wallets:example:end -->

```rust,ignore
        use fuels::prelude::*;
        // This helper launches a local node and provides 10 test wallets linked to it.
        // The initial balance defaults to 1 coin per wallet with an amount of 1_000_000_000.
        let wallets =
            launch_custom_provider_and_get_wallets(WalletsConfig::default(), None, None).await?;
```

<!-- This section should explain how to customize test wallets -->
<!-- custom_test_wallets:example:start -->
You can customize your test wallets via `WalletsConfig`.
<!-- custom_test_wallets:example:end -->

```rust,ignore
        let num_wallets = 5;
        let coins_per_wallet = 3;
        let amount_per_coin = 100;
        let config = WalletsConfig::new(
            Some(num_wallets),
            Some(coins_per_wallet),
            Some(amount_per_coin),
        );
        // Launches a local node and provides test wallets as specified by the config.
        let wallets = launch_custom_provider_and_get_wallets(config, None, None).await?;
```

<!-- This section should explain that test wallets are deterministic -->
<!-- deterministic:example:start -->
>**Note** Wallets generated with `launch_provider_and_get_wallet` or `launch_custom_provider_and_get_wallets`
will have deterministic addresses.
<!-- deterministic:example:end -->

## Setting up a test wallet with multiple random assets

You can create a test wallet containing multiple assets (including the base asset to pay for gas).

```rust,ignore
        // ANCHOR: multiple_assets_coins
        use fuels::prelude::*;
        let signer = PrivateKeySigner::random(&mut thread_rng());
        let num_assets = 5;
        let coins_per_asset = 10;
        let amount_per_coin = 15;

        let (coins, asset_ids) = setup_multiple_assets_coins(
            signer.address(),
            num_assets,
            coins_per_asset,
            amount_per_coin,
        );
        // ANCHOR_END: multiple_assets_coins
        let provider = setup_test_provider(coins.clone(), vec![], None, None).await?;
        let wallet = Wallet::new(signer, provider);
```

- coins: `Vec<(UtxoId, Coin)>` has `num_assets` * `coins_per_assets` coins (UTXOs)
- asset_ids: `Vec<AssetId>` contains the `num_assets` randomly generated `AssetId`s (always includes the base asset)

## Setting up a test wallet with multiple custom assets

You can also create assets with specific `AssetId`s, coin amounts, and number of coins.

```rust,ignore
        use fuels::prelude::*;
        use rand::Fill;

        let mut rng = rand::thread_rng();
        let signer = PrivateKeySigner::random(&mut rng);

        let asset_base = AssetConfig {
            id: AssetId::zeroed(),
            num_coins: 2,
            coin_amount: 4,
        };

        let mut asset_id_1 = AssetId::zeroed();
        asset_id_1.try_fill(&mut rng)?;
        let asset_1 = AssetConfig {
            id: asset_id_1,
            num_coins: 6,
            coin_amount: 8,
        };

        let mut asset_id_2 = AssetId::zeroed();
        asset_id_2.try_fill(&mut rng)?;
        let asset_2 = AssetConfig {
            id: asset_id_2,
            num_coins: 10,
            coin_amount: 12,
        };

        let assets = vec![asset_base, asset_1, asset_2];
        let coins = setup_custom_assets_coins(signer.address(), &assets);
        let provider = setup_test_provider(coins, vec![], None, None).await?;
        let wallet = Wallet::new(signer, provider.clone());
        let num_wallets = 1;
        let wallet_config = WalletsConfig::new_multiple_assets(num_wallets, assets);
        let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?;
```

This can also be achieved directly with the `WalletsConfig`.

```rust,ignore
        let num_wallets = 1;
        let wallet_config = WalletsConfig::new_multiple_assets(num_wallets, assets);
        let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?;
```

>**Note** In this case, you need to manually add the base asset and the corresponding number of
>coins and coin amount

## Setting up assets

The Fuel blockchain holds many different assets; you can create your asset with its unique `AssetId` or create random assets for testing purposes.

You can use only one asset to pay for transaction fees and gas: the base asset, whose `AssetId` is `0x000...0`, a 32-byte zeroed value.

For testing purposes, you can configure coins and amounts for assets. You can use `setup_multiple_assets_coins`:

```rust,ignore
        use fuels::prelude::*;
        let signer = PrivateKeySigner::random(&mut thread_rng());
        let num_assets = 5;
        let coins_per_asset = 10;
        let amount_per_coin = 15;

        let (coins, asset_ids) = setup_multiple_assets_coins(
            signer.address(),
            num_assets,
            coins_per_asset,
            amount_per_coin,
        );
```

>**Note** If setting up multiple assets, one of these assets will always be the base asset.

If you want to create coins only with the base asset, then you can use:

```rust,ignore
        let wallet_signer = PrivateKeySigner::random(&mut rand::thread_rng());

        // How many coins in our wallet.
        let number_of_coins = 1;

        // The amount/value in each coin in our wallet.
        let amount_per_coin = 3;

        let coins = setup_single_asset_coins(
            wallet_signer.address(),
            AssetId::zeroed(),
            number_of_coins,
            amount_per_coin,
        );
```

>**Note** Choosing a large number of coins and assets for `setup_multiple_assets_coins` or `setup_single_asset_coins` can lead to considerable runtime for these methods. This will be improved in the future but for now, we recommend using up to **1_000_000** coins, or **1000** coins and assets simultaneously.


---

### File: docs/nightly/integration-docs/docs/src/index.md

# Integrations

This section provides help for developers using integrations with Fuel's tech stack.

## Wallets

### Fuelet

Fuelet is the leading account abstraction and non-custodial wallet on Fuel.

[More info](https://docs.fuelet.app/)

### Fuel

The official Fuel wallet. With the Fuel Wallet, you can explore DApps on Fuel and manage your crypto assets, all in one place.

[More info](https://docs.fuel.network/docs/wallet/install/)

## Indexers

### Envio

Envio is a modern, multi-chain EVM blockchain indexing framework speed-optimized for querying real-time and historical data.

[More info](https://docs.envio.dev/docs/HyperIndex/tutorial-indexing-fuel)

### SQD

SQD enables permissionless, cost-efficient access to petabytes of high-value Web3 data.

[More info](https://docs.sqd.dev/fuel-indexing/)

### Pangea

Pangea provides access to fine-grained real-time and historical data.

[More info](https://docs.pangea.foundation/chain-data/fuel/fuel.html)

## Oracles

### Pyth

Build apps with high-fidelity oracle feeds designed for mission-critical systems.

[More info](https://docs.pyth.network/price-feeds/use-real-time-data/fuel)

### ORAO

ORAO Network provides provably fair random data on Fuel.

[More info](https://orao.network/fuel-vrf)

### Redstone

Redstone provides modular oracles tailored to your decentralized applications.

[More info](https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/fuel-connector/README.md)

## RPCs

### QuickNode

QuickNode provides infrastructure that allows developers and services to interact with the Fuel network quickly and efficiently, without the need to manage their own nodes.

[More info](https://www.quicknode.com/chains/fuel)


---

### File: docs/nightly/migrations-and-disclosures/docs/src/breaking-changes-archive.md

# Beta 3-5 Testnet Breaking Change Guide (Archive)

## April 30, 2024

### Sway

Release: [Sway v0.56.0](https://github.com/FuelLabs/sway/releases/tag/v0.56.0)

The `std::call_frames::second_param` function now returns a `u64` instead of a generic type `T`.

`contract_id()` has been removed in favor of `ContractId::this()`.

```rust
/* BEFORE */
let contract_id = contract_id();

/* AFTER */
let contract_id = ContractId::this();
```

`call_with_function_selector_vec` has been removed in favor of `call_with_function_selector`.

```rust
/* BEFORE */
pub fn call_with_function_selector_vec(
  target: ContractId,
  function_selector: Vec<u8>,
  calldata: Vec<u8>,
  single_value_type_arg: bool,
  call_params: CallParams
) {...}

/* AFTER */
pub fn call_with_function_selector_vec(
  target: ContractId,
  function_selector: Bytes // new
  calldata: Bytes, // new
  call_params: CallParams
) {...}
```

The `BASE_ASSET_ID` constant has been removed, and `AssetId::base_asset_id()` is now `AssetId::base()`.

```rust
/* BEFORE */
let base_asset_id = BASE_ASSET_ID;
/* OR */
let base_asset_id = AssetId::base_asset_id();

/* AFTER */
let base_asset_id = AssetId:base();
```

You can no longer access the following:

- `force_transfer_to_contract()`
- `transfer_to_address()`
- `mint_to_contract()`
- `mint_to_address()`

Instead use the `transfer()`, `mint()`, and `mint_to()` functions accordingly.

```rust
/* BEFORE */
let user = Address:from(address);
mint_to_address(user, ZERO_B256, amount);

/* AFTER */
mint_to(Identity::Address(user), ZERO_B256, amount);
```

The new encoding (encoding v1) is now set by default.  If you would like to build your forc project without v1 encoding then run the following command:

```sh
forc build --no-encoding-v1
```

`run_external` in sway-lib-std has been removed until LDC is stabilized.

Release: [Sway v0.55.0](https://github.com/FuelLabs/sway/releases/tag/v0.55.0)

`GTF` constants along with the following functions have been removed to match the current Fuel VM instruction set:

- `input_maturity()`
- `tx_receipts_root()`

`tx_gas_price` has been renamed `tx_tip`

```rust
/* BEFORE */
let gas_price = tx_gas_price();

/* AFTER */
let tip = tx_tip();
```

Release: [Sway v0.54.0](https://github.com/FuelLabs/sway/releases/tag/v0.54.0)

The `forc-client` and `forc-tx` plugins now take `u16` instead of `u8` for witness index types.

### TS-SDK

Release [v0.83.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.83.0)

`BaseAssetId` is no longer exported by `fuels`. It can be fetched from a `Provider`.

```ts
/* BEFORE */
import { BasedAssetId } from "fuels";

/* AFTER */
const provider = await Provider.create(FUEL_NETWORK_URL);
const baseAssetId = provider.getBaseAssetId();
```

`TransactionRequest.addCoinOutput` and `TransactionRequest.addChangeOutput` now requires an `assetId`, it no longer defaults to the `BaseAssetId`.

`TransactionRequest.fundWithFakeUtxos` now requires passing the `baseAssetId` as a function parameter. This is the only function that is base asset aware, so that it can be used specifically to estimate the transaction cost.

`CoinQuantityLike` now requires an `AssetId`. Previously most of it's usages would default to the `BaseAssetId`, as this must now be fetched, so it must be passed to the type.

```ts
/* BEFORE */
let coin: CoinQuantityLike = [1000];
coin = { amount: 1000 };

/* AFTER */
const assetId = "0x..";
let coin: CoinQuantityLike = [1000, assetId];
coin = { amount: 1000, assetId };
```

`gasPrice` is calculated by the VM so we do not need use it anymore.

```ts
/* BEFORE */
await factory.deployContract({ gasPrice });

/* AFTER */
await factory.deployContract();
```

`PolicyType.GasPrice` is now `PolicyType.Tip`.

The `Account.fund` function parameters changed.  Also the information returned by `Provider.getTransactionCost` is useful here because it can be passed as the second parameter to `Account.fund`.

```ts
/* BEFORE */
async fund<T extends TransactionRequest>(
    request: T,
    coinQuantities: CoinQuantity[],
    fee: BN,
    inputsWithEstimatedPredicates: TransactionRequestInput[],
    addedSignatures?: number
): Promise<T>

/* AFTER */
export type EstimatedTxParams = {
  maxFee: BN;
  estimatedPredicates: TransactionRequestInput[];
  addedSignatures: number;
  requiredQuantities: CoinQuantity[];
}
async fund<T extends TransactionRequest>(request: T, params: EstimatedTxParams): Promise<T>
```

GraphQL URL now includes a versioning path: `http://127.0.0.1:4000/v1/graphql`.

`calculateTransactionFee` now requires `tip`, `maxGasPerTx`, and `gasPrice`. Also `gasUsed` is not used anymore.

```ts
/* BEFORE */
const { fee } = calculateTransactionFee({
  gasUsed,
  rawPayload,
  consensusParameters: {
    gasCosts,
    feeParams: {
      gasPerByte,
      gasPriceFactor,
    },
  },
});

/* AFTER */
const { fee } = calculateTransactionFee({
  gasPrice, // new
  tip, // new
  consensusParameters: {
    maxGasPerTx, // new
    gasCosts,
    feeParams: {
      gasPerByte,
      gasPriceFactor,
    },
  },
  rawPayload,
});
```

Due to `forc` upgrade [v0.52.0](https://github.com/FuelLabs/sway/releases/tag/v0.52.0) `AssetId` and `EvmAddress` property `value` was renamed to `bits`

```ts
/* BEFORE */
export type EvmAddress = {
  value: B256AddressEvm;
};
export type AssetId = {
  value: B256Address;
};

/* AFTER */
export type EvmAddress = {
  bits: B256AddressEvm;
};
export type AssetId = {
  bits: B256Address;
};
```

Release [v0.80.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.80.0)

Removed unused property `usedFee` from `Provider.getTransactionCost` response.

Renamed `getAssetId` to `getMintedAssetId`.

### Rust SDK

Release [v0.58.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.58.0)

The new encoding is now the default encoding. Use the following command if you would like to run your cargo tests with the legacy encoding.

```sh
cargo test --features legacy_encoding
```

Release [v0.57.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.57.0)

The `BASE_ASSET_ID` constant has been removed and replaced by a new `Provider` function.

```rust
/* BEFORE */
let base_asset_id = BASE_ASSET_ID;

/* AFTER */
let base_asset_id = provider.base_asset_id();
```

`Config` was renamed to `NodeConfig`

```rust
/* BEFORE */
let node_config = Config::default();

/* AFTER */
let node_config = NodeConfig::default();
```

`FuelService::start()` now accepts `NodeConfig`, `ChainConfig`, and `StateConfig` as arguments to startup a node.

```rust
/* BEFORE */
let server = FuelService::start(Config::default()).await?;

/* AFTER */
let server = FuelService::start(
  NodeConfig::default(),
  ChainConfig::default(),
  StateConfig::default(),
)
.await?;
```

When instantiating `ConsensusParameters` you must make use of setters.

```rust
/* BEFORE */
let consensus_parameters = ConsensusParameters {
    tx_params,
    fee_params,
    ..Default::default()
};

/* AFTER */
let mut consensus_parameters = ConsensusParameters::default();
consensus_parameters.set_tx_params(tx_params);
consensus_parameters.set_fee_params(fee_params);
```

Fields now need to be accessed via methods.

```rust
/* BEFORE */
let chain_id = consensus_parameters.chain_id;

/* AFTER */
let chain_id = consensus_parameters.chain_id();
```

The same applies to other parameter structs used when setting up a node, such as `TxParameters`, `ContractParameters`, `PredicateParameters` etc.

The `witness_index` parameters in `CreateTransactionBuilder::with_bytecode_witness_index` are now a `u16`.

`NodeInfo` no longer has `min_gas_price`.

`CreateTransaction` no longer has `bytecode_length()`.

`Header` no longer has `message_receipt_root`, but gains:

```rust
pub message_outbox_root: Bytes32,
pub event_inbox_root: Bytes32,
pub consensus_parameters_version: u32,
pub state_transition_bytecode_version: u32
```

## March 27, 2024

### Sway

Release [Sway v0.52.0](https://github.com/FuelLabs/sway/releases/tag/v0.52.0)

The `bytes` field on `B512` and the `value` field `EvmAddress` have been renamed `bits`, made private, and made accessible via `bits()`.

```rust
/* BEFORE */
let bytes = myB12.bytes;
let value = myEvmAddress.value;

/* AFTER */
let bits = myB512.bits();
let bits = myEvmAddress.bits();
```

The fields on `U128` have been made private.

```rust
/* BEFORE */
let zero_u128 = U128 { upper: 0, lower: 0 };
let upper = zero_u128.upper;

/* AFTER */
let zero_u128 = U128::from(0, 0);
let upper = zero_u128.upper();
```

The fields on `StorageKey` have been made private and are now accessed via:

- `new()`
- `slot()`
- `offset()`
- `field_id()`

The following heap types have been updated to have private struct variables:

- `Bytes`
- `RawBytes`
- `Vec`
- `RawVec`
- `String`

```rust
/* BEFORE */
let bytes_ptr = bytes.buf.ptr();

/* AFTER */
let bytes_ptr = bytes.ptr();
```

The `value` field on `AssetId`, `ContractId`, and `Address` is now private and renamed `bits`.

```rust
/* BEFORE */
let value = assetId.value;

/* AFTER */
let bits = assetId.bits();
```

`predicate_id()` has been renamed to `predicate_address()`.

```rust
/* BEFORE */
let predicate = predicate_id();

/* AFTER */
let predicate = predicate_address();
```

`U256` has been removed use the native `u256` type instead.

```rust
/* BEFORE */
let my_U256 = U256::max();

/* AFTER */
let my_u256 = u256::max();
```

### TS-SDK

Release [v0.79.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.79.0)

`externalLoggedTypes` has been removed from the `Interface` class.

Release [v0.77.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.77.0)

Predicate data is now accepted on the `Predicate` constructor.

```ts
/* BEFORE */
const predicate = new Predicate(bytecode, provider, abi, configurableConstants);

/* AFTER */
const predicate = new Predicate({
  bytecode,
  abi, // optional
  provider,
  inputData, // optional
  configurableConstants, // optional
});
```

The `setData` method has been removed from `Predicate`. If you want to pass in predicate data after instantiating the `Predicate` or if you want to use different data than what was passed to the constructor, then you will have to create a new `Predicate` instance.

### Rust SDK

Release [v0.56.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.56.0)

Experimental encoding for logs was added. Use the following command to run your tests with the experimental encoding

```sh
cargo test --features experimental
```

**_NOTE_** experimental encoding is now the default encoding in [v0.57.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.57.0)

`Configurables` structs now need to be instantiated through a `::new(encoder_config)` or `::default()` method.

```rust
/* BEFORE */
let configurables = MyContractConfigurables::new().with_STRUCT(my_struct);

/* AFTER */
let configurables = MyContractConfigurables::default().with_STRUCT(my_struct);
/* OR */
let configurables = MyContractConfigurables::new(encoder_config).with_STRUCT(my_struct);
```

`Configurables::with_some_string_config(some_string)` methods now return a `Result<Configurables>` instead of `Configurables`.

`Predicates::encode_data` now returns a `Result<UnresolvedBytes>` instead of `UnresolvedBytes`.

`AbiEncoder` structs must be instantiated through a `::new(encoder_config)` or `::default()` method.

```rust
/* BEFORE */
let encoded = ABIEncoder::encode(&args).resolve(0);

/* AFTER */
let encoded = ABIEncoder::default().encode(&args).resolve(0);
/* OR */
let encoded = ABIEncoder::new(config).encode(&args).resolve(0);
```

`EnumVariants` are now imported through `param_types::EnumVariants`.

```rust
/* BEFORE */
use fuels::types::enum_variants::EnumVariants;

/* AFTER */
use fuels::types::param_types::EnumVariants;
```

`TxPolicies` `gas_price` is replaced with `tip`

```rust
/* BEFORE */
let tx_policies = TXPolicies::default().with_gas_price(1);

/* AFTER */
let tx_policies = TXPolicies::default().with_tip(1);
```

`checked_dry_run` has been removed from `Provider`.

`dry_run` now returns `Result<TxStatus>` instead of `Result<Vec<Receipt>>`. The receipts can be taken with `tx_status.take_receipts()`.

`TransactionResponse`'s `block_id` is replaced with `block_height`.

`estimate_transaction_cost` has a new argument `block_horizon: Option<u32>`.

```rust
/* BEFORE */
let transaction_cost = contract_instance
  .methods()
  .my_contract_call()
  .estimate_transaction_cost(Some(tolerance))
  .await?;

/* AFTER */
let transaction_cost = contract_instance
  .methods()
  .my_contract_call()
  .estimate_transaction_cost(tolerance, block_horizon)
  .await?;
```

## February 22, 2024

### Sway

Release: [Sway v0.51.0](https://github.com/FuelLabs/sway/releases/tag/v0.51.0)

You can no longer access private fields in structs.

```rust
/* BEFORE */
let private = my_struct.private // just a warning

/* AFTER */
let private = my_struct.private // ERROR
let private = my_struct.private() // you must create a function to access private variables
```

The `Never` type is now `!`.

```rust
/* BEFORE */
let x: NEVER = { return 123 };

/* AFTER */
let x: ! = { return 123 };
```

Release: [Sway v0.50.0](https://github.com/FuelLabs/sway/releases/tag/v0.50.0)

Configurables are now forbidden in const expressions.

```rust
// Not allowed
script;

configurable {
    VALUE: u64 = 42,
}

fn main() {
    const CONSTANT: u64 = VALUE;
}
```

Struct fields are now private by default.  You must explicitly mark a field public.

```rust
/* BEFORE */
pub struct Struct {
  public_field: u8,
}

/* AFTER */
pub struct Struct {
  pub public_field: u8,
  private_field: u8,
}
```

The `From` trait has been redesigned into the `From`/`Into` rust-like trait pair.

```rust
/* BEFORE */
impl From<b256> for Address {
  fn from(bits: b256) -> Self {
    Self { value: bits }
  }

  fn into(self) -> b256 {
    self.value
  }
}

let address = Address::from(ZERO_B256);
let b256_data = address.into();

/* AFTER */
impl From<b256> for Address {
  fn from(bits: b256) -> Self {
    Self { value: bits }
  }
}

impl From<Address> for b256 {
  fn from(address: Address) -> b256 {
    address.value
  }
}

let address = Address::from(ZERO_B256);
let b256_data: b256 = address.into();
let address: Address = b256_data.into();
```

### TS-SDK

Release: [v0.74.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.74.0)

`Provider` has been removed from `WalletManager` types.

```ts
/* Before */
const vault = new MnemonicVault({
  secret: mnemonic,
  provider,
});

/* After */
const vault = new MnemonicVault({
  secret: mnemonic,
});
```

The Account and account related packages have been restructured. Anything imported from the following packages will now be imported from `@fuel-ts/account`

- `@fuel-ts/hdwallet`
- `@fuel-ts/mnemonic`
- `@fuel-ts/predicate`
- `@fuel-ts/providers`
- `@fuel-ts/signer`
- `@fuel-ts/wallet-manager`
- `@fuel-ts/wallet`
- `@fuel-ts/wordlists`

## February 5, 2024 (Beta 5)

### Sway

Release: [Sway v0.49.2](https://github.com/FuelLabs/sway/releases/tag/v0.49.2)

Numerous elements in the standard library have undergone changes. The `token.sw` file has been renamed to `asset.sw`, impacting the `transfer()` and `mint_to()` functions. This modification aims to bring about greater consistency across all functions related to asset management.

```sway
/* BEFORE - v0.46.0 */
use std::{
    token::transfer

};
/* AFTER - v0.49.2 */
use std::{
    asset::transfer
};
```

The instructions `LW` (Load Word) and `SW` (Store Word) are now replaced with `LB` (Load Byte) and `SB` (Store Byte), specifically for smaller data types like `u8`. This adjustment allows these types to be contained within a single byte, rather than occupying a full word. However, for other data types such as `u16`, the original instruction format remains unchanged.

```sway
/* BEFORE - v0.46.0 */
sw   output r1 i0;

/* AFTER - v0.49.2 */
sb   output r1 i0;
```

`DEFAULT_SUB_ID` has been introduced to improve UX. It is equivalent to the `ZERO_B256` constant.

```sway
/* BEFORE - v0.46.0 */
use std::call_frames::contract_id;

fn foo(other_contract: ContractId) {
     let other_asset = AssetId::default(other_contract);
     let my_asset = AssetId::default(contract_id());
}

/* AFTER - v0.49.2 */
fn foo(other_contract: ContractId) {
     let other_asset = AssetId::new(other_contract, DEFAULT_SUB_ID);
     let my_asset = AssetId::default();
}
```

The `Eq` trait now exists for `Option`.

```sway
/* BEFORE - v0.46.0 */
let option1: Option<u64> = Some(5);
let option2: Option<u64> = Some(5);

match (option1, option2) {
    (Some(a), Some(b)) => a == b,
    (None, None) => true,
    _ => false,
}

/* AFTER - v0.49.2 */
let option1: Option<u64> = Some(5);
let option2: Option<u64> = Some(5);

if option1 == option2 {
    return true
} else {
    return false
}
```

The standard library `tx` introduces several new functions including `tx_max_fee()`, `tx_witness_limit()`, `script_gas_limit()`, and `policies()`. `tx_gas_limit()` has been deprecated to support the new `TxPolicy`, replacing `TxParameters`.

```sway
/* BEFORE - v0.46.0 */
fn get_tx_gas_limit() -> u64;

/* AFTER - v0.49.2 */
fn get_script_gas_limit() -> u64;
```

The existing functions inside the standard library `tx`, including `tx_gas_price()` and `tx_maturity()`, now return `Option<u64>` and `Option<u32>` respectively, instead of just `u64` and `u32`.

```sway
/* BEFORE - v0.46.0 */
fn get_tx_maturity() -> u32 {
    tx_maturity()
}

/* AFTER - v0.49.2 */
fn get_tx_maturity() -> u32 {
    tx_maturity().unwrap()
}
```

Along with these changes, GTF opcodes have been updated in the following standard libraries.

1. [inputs.sw](https://github.com/FuelLabs/sway/pull/5281/files#diff-427b18b1692c5ee5541b43013d9859363da2c2fa6e940b25045d2514cac97428)
2. [outputs.sw](https://github.com/FuelLabs/sway/pull/5281/files#diff-0625712126eb9f0c821b18e48379ad1213d6cbe0d38ba4fe721260232fb48eca)
3. [tx.sw](https://github.com/FuelLabs/sway/pull/5281/files#diff-038f9ff7e5241cc345c0d460a0100ab88fbc72ac76db0e9af923bc8342b5c0c9)

Byte conversions and array conversions for u256, u64, u32, u16, and b256 have been introduced into the standard library.

1. [Byte conversions](https://github.com/FuelLabs/sway/tree/master/sway-lib-std/src/bytes_conversions)

```sway
/* AFTER - v0.49.2 */
fn foo() {
  let x: u16 = 513;
  let result = x.to_le_bytes();

  assert(result[0] == 1_u8);
  assert(result[1] == 2_u8);
}
```

<!-- markdownlint-disable md029 -->

2. [Array conversions](https://github.com/FuelLabs/sway/tree/master/sway-lib-std/src/array_conversions)

```sway
/* AFTER - v0.49.2 */
fn foo() {
  let x: u16 = 513;
  let result = x.to_le_bytes();

  assert(result.get(0).unwrap() == 1_u8);
  assert(result.get(1).unwrap() == 2_u8);
}
```

<!-- markdownlint-enable md029 -->

Power uses a `u32` instead of self

```sway
/* BEFORE - v0.46.0 */
assert(2u16.pow(2u16) == 4u16);

/* AFTER - v0.49.2 */
assert(2u16.pow(2u32) == 4u16);
```

### TS SDK

Release: [TS SDK v0.73.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.73.0)

Several `fuel-core` configuration-related options have been removed from the `LaunchNodeOptions`. These include: `chainConfigPath`, `consensusKey`, `useInMemoryDb`, and `poaInstant`. These options can now only be passed through the `args` property.

```typescript
/* BEFORE - v0.60.0 */
const { cleanup, ip, port } = await launchNode({
  chainConfigPath,
  consensusKey = "0xa449b1ffee0e2205fa924c6740cc48b3b473aa28587df6dab12abc245d1f5298",
  args: defaultFuelCoreArgs,
});

/* AFTER - v0.73.0 */
const { cleanup, ip, port } = await launchNode({
  args: ["--poa-instant", "false", "--poa-interval-period", "400ms"],
});
```

Contract calls requires `gasLimit` and `gasPrice` to be specified in `txParams()`.

```typescript
/* BEFORE - v0.60.0 */
let resp = await contract.functions.count().simulate();

/* AFTER - v0.73.0 */
let resp = await contract.functions
  .count()
  .txParams({ gasPrice: 1, gasLimit: 100_000 })
  .simulate();
```

`chainInfoCache` and `nodeInfoCache` are now private methods, to prevent users from accessing invalid cached information after it becomes stale.

```typescript
/* BEFORE - v0.60.0 */
Provider.chainInfoCache[FUEL_NETWORK_URL];
Provider.nodeInfoCache[FUEL_NETWORK_URL];

/* AFTER - v0.73.0 */
provider.getChain();
provider.getNode();
```

The `switchURL()` method, used to update the URL for the provider, is now named `connect()`.

```typescript
/* BEFORE - v0.60.0 */
await provider.switchUrl(altProviderUrl);

/* AFTER - v0.73.0 */
await provider.connect(altProviderUrl);
```

Support for new Sway types has been introduced with:

1. Bytes

```typescript
/* AFTER - v0.73.0 */
const bytes = [40, 41, 42];
const { value } = await contract.functions.bytes_comparison(bytes).simulate();
```

<!-- markdownlint-disable md029 -->

2. Raw Slices

```typescript
/* AFTER - v0.73.0 */
const rawSlice = [40, 41, 42];
const { value } = await contract.functions
  .raw_slice_comparison(rawSlice)
  .simulate();
```

3. StdString

```typescript
/* AFTER - v0.73.0 */
const stdString = "Hello World";
const { value } = await contract.functions
  .string_comparison(stdString)
  .simulate();
```

<!-- markdownlint-enable md029 -->

Typegen attempts to resolve, auto-load, and embed the Storage Slots for your Contract within the `MyContract__factory` class. However, you can override this, along with other options, when calling the `deployContract` method:

```typescript
/* AFTER - v0.73.0 */
import storageSlots from "../contract/out/debug/storage-slots.json";

const contract = await MyContract__factory.deployContract(bytecode, wallet, {
  storageSlots,
});
```

`concat`, `arrayify`, and `hexlify` have been introduced to the utils to replace their respective functions from the ethers library, avoiding the reexporting of ethers functions.

```typescript
/* BEFORE - v0.60.0 */
import { concat, arrayify, hexlify } from "@ethersproject/bytes";

const someBytes = concat([
  new Uint8Array([1, 2, 3]),
  new Uint8Array([4, 5, 6]),
  new Uint8Array([7, 8, 9]),
]);
const someHex = hexlify(new Uint8Array([0, 1, 2, 3]));
const someArray = arrayify(new Uint8Array([0, 1, 2, 3]));

/* AFTER - v0.73.0 */
import { concat, arrayify, hexlify } from "@fuel-ts/utils";

const someBytes = concat([
  new Uint8Array([1, 2, 3]),
  new Uint8Array([4, 5, 6]),
  new Uint8Array([7, 8, 9]),
]);
const someHex = hexlify(new Uint8Array([0, 1, 2, 3]));
const someArray = arrayify(new Uint8Array([0, 1, 2, 3]));
```

`Address` types can no longer be used directly to represent a `b256` and must instead use the `toB256()` conversion method.

```typescript
/* BEFORE - v0.60.0 */
const addressId = {
  value: userWallet.address,
};

tokenContract.functions
  .transfer_coins_to_output(addressId, assetId, amount)
  .call();

/* AFTER - v0.73.0 */
const addressId = {
  value: userWallet.address.toB256(),
};

tokenContract.functions
  .transfer_coins_to_output(addressId, assetId, amount)
  .call();
```

The `Account` class's `fund()` method now takes in two new parameters: `quantities` and `fee`, of types `CoinQuantity[]` and `BN`, respectively. These can be derived from the provider's `getTransactionCost()` method.

```typescript
/* BEFORE - v0.60.0 */
await wallet.fund(transactionRequest);

/* AFTER - v0.73.0 */
const { maxFee, requiredQuantities } = await provider.getTransactionCost(
  transactionRequest
);

await wallet.fund(transactionRequest, quantities, fee);
```

The `provider`'s `getTransactionCost` now breaks down its old `fee` into `minFee`, `usedFee`, and `maxFee`, based on the actual calculation of the transaction. Additionally, `requiredQuantities`, `receipts`, `minGas`, and `maxGas`, of types `coinQuantity[]`, `TransactionResultReceipt[]`, `BN`, and `BN` respectively, have also been introduced to improve the granularity of cost estimation.

```typescript
/* BEFORE - v0.60.0 */
const { fee } = await this.account.provider.getTransactionCost(
  transactionRequest
);

/* AFTER - v0.73.0 */
const {
  requiredQuantities,
  receipts,
  minGas,
  maxGas,
  minFee,
  maxFee,
  usedFee,
} = await this.account.provider.getTransactionCost(transactionRequest);
```

The `getTransferOperations` function now takes in a `receipts` parameter as well, ensuring that contract transactions return the transfer asset.

```typescript
/* BEFORE - v0.60.0 */
const operations = getTransferOperations({ inputs: [], outputs: [] });

/* AFTER - v0.73.0 */
const operations = getTransferOperations({
  inputs: [],
  outputs: [],
  receipts: [],
});
```

The predicate introduces a new `getTransferTxId`, a method to calculate the transaction ID for a `Predicate.transfer` transaction.

```typescript
/* AFTER - v0.73.0 */
const txId = await predicate.getTransferTxId(address, amount, BaseAssetId, {
  gasPrice,
});
```

The `deployContract` method contains a new parameter, `storageSlotsPath`, to avoid issues that may arise if storage slots are not auto-loaded. Without auto-loading, some contracts will revert due to improper or missing initialization of storage slots.

```typescript
/* BEFORE - v0.60.0 */
const assetId = BaseAssetId;

/* AFTER - v0.73.0 */
const assetId: AssetId = { value: BaseAssetId };
```

`AssetId` has been introduced to match the Sway standard library as a `Struct` wrapper around an inner `Bits256` value.

### Rust SDK

Release: [Rust SDK v0.55.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.55.0)

The `sign_message()` and `sign_transaction` functions in the `Signer` trait have been consolidated into a single method, now simply named `sign`.

```rust
/* BEFORE - v0.48.0 */
let signature1: B512 = wallet.sign_message(data_to_sign).await?.as_ref().try_into()?;

/* AFTER - v0.55.0 */
let signature1: B512 = wallet.sign(data_to_sign).await?.as_ref().try_into()?;
```

The function `check_without_signatures` in the `Transaction` trait has been renamed to `check`. This updated `check` function retains its original capabilities and now includes the additional feature of checking with signatures.

```rust
/* BEFORE - v0.48.0 */
tx.check_without_signatures(chain_info.latest_block.header.height, self.consensus_parameters())?;

/* AFTER - v0.55.0 */
tx.check(chain_info.latest_block.header.height, self.consensus_parameters())?;
```

The typo in the `add_witnessses` function name under the `Account` trait has been fixed and is now `add_witnesses`.

```rust
/* BEFORE - v0.48.0 */
account.add_witnessses(&mut tb);

/* AFTER - v0.55.0 */
account.add_witnesses(&mut tb)?;
```

Use of `Message`, `PublicKey`, `SecretKey` and `Signature` can be found inside `fuels::crypto::` now.

```rust
/* BEFORE - v0.48.0 */
use fuels::accounts::fuel_crypto::SecretKey;

/* AFTER - v0.55.0 */
use fuels::crypto::SecretKey,
```

The `submit_and_await_commit()` function now returns a `TxStatus` instead of a `TxId`.

```rust
/* BEFORE - v0.48.0 */
let tx_id = self.client.submit_and_await_commit(&tx.clone().into()).await?.into();

/* AFTER - v0.55.0 */
let tx_status = self.client.submit_and_await_commit(&tx.clone().into()).await?.into();
```

When constructing a transaction, the provider already possesses all the necessary information, rendering `NetworkInfo` and all its related functions and methods obsolete. Consequently, `ScriptTransactionBuilder::new`, `CreateTransactionBuilder::new`, and `Provider::new` have been removed for `::default()`.

```rust
/* BEFORE - v0.48.0 */
use fuels_core::types::transaction_builders::{DryRunner, NetworkInfo}

ScriptTransactionBuilder::new(network_info)

/* AFTER - v0.55.0 */
use fuels_core::types::transaction_builders::{DryRunner}

ScriptTransactionBuilder::default()
```

In Sway, `U256` has been deprecated in favor of `u256`. It is no longer supported in the SDK. Usage of `U256` will now result in a runtime error.

`TxPolicies` supersedes `TxParameters`.

```rust
/* BEFORE - v0.48.0 */
let tx_parameters = TxParameters::default()

/* AFTER - v0.55.0 */
let tx_policies = TxPolicies::default()
```

Three new optional fields have been introduced in `TxPolicies`:

1. `WitnessLimit`, which sets a new restriction for transaction witnesses by introducing a limit on the maximum byte size of witnesses in transactions.
2. `MaxFee`, which sets an upper limit on the transaction fee that a user is willing to pay.
3. `ScriptGasLimit`, which no longer constrains predicate execution time but exclusively limits the gas limit of scripts. If this field is not set, the SDK will estimate gas consumption and set it automatically.

Additionally, `GasPrice` and `Maturity` fields within `TxPolicies` are now optional parameters.

```rust
/* BEFORE - v0.48.0 */
let tx_parameters = TxParameters::new(gas_price, gas_limit, maturity)

/* AFTER - v0.55.0 */
let tx_policies = TxPolicies::new(Some(gas_price), Some(witness_limit), Some(maturity), Some(max_fee), Some(script_gas_limit))
```

`TxPolicy` Pitfalls

1. If the `max_fee` is greater than `policies.max_fee`, then the transaction will be rejected.
2. If the `witnesses_size` is greater than `policies.witness_limit`, then the transaction will be rejected.

The predicate's `get_message_proof` now uses `nonce` instead of `msg_id`.

```rust
/* BEFORE - v0.48.0 */
let proof = predicate.try_provider()?
  .get_message_proof(&tx_id, &msg_id, None, Some(2))

/* AFTER - v0.55.0 */
let proof = predicate.try_provider()?
  .get_message_proof(&tx_id, &msg_nonce, None, Some(2))
```

When using local chain configs, the `manual_blocks_enabled` option is replaced by the new `debug` flag. Additionally, with `local_node()` being deprecated in favor of `default()`, the options `utxo_validation` and `manual_blocks_enabled` are enabled by default for the test providers.

```rust
/* BEFORE - v0.48.0 */
let config = Config {
    utxo_validation: true,
    manual_blocks_enabled: true,
    ..Config::local_node()
};

/* AFTER - v0.55.0 */
let config = Config {
    ..Config::default()
};
```

When using `transaction_builders`, the `BuildableTransaction` trait must be in scope.

```rust
/* BEFORE - v0.48.0 */
use fuels_core::{
    types::{
        transaction_builders::{TransactionBuilder, ScriptTransactionBuilder},
    },
};

/* AFTER - v0.55.0 */
use fuels_core::{
    types::{
        transaction_builders::{BuildableTransaction, ScriptTransactionBuilder},
    },
};
```

## October 2, 2023

### TS SDK

Release: [TS SDK v0.60.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.60.0)

`Provider` is used so widely in our SDK, there are multiple breaking changes that we need to be aware of and need to communicate to our users:

```typescript
/* BEFORE - v0.57.0 */
const provider = new Provider(url);

/* AFTER - v0.60.0 */
const provider = await Provider.create(url);
```

All of these methods now require a `Provider` to be passed in:

#### Wallet Methods

Some of these methods used to accept a URL instead of a `Provider` object. Note that the `provider` parameter _has_ to be a `Provider` object now.

```typescript
const provider = await Provider.create(url);
```

```typescript
/* BEFORE - v0.57.0 */
WalletUnlocked.fromSeed(seed, path);

WalletUnlocked.fromMnemonic(mnemonic, path, passphrase);

WalletUnlocked.fromExtendedKey(extendedKey);
await WalletUnlocked.fromEncryptedJson(jsonWallet, password);

Wallet.fromAddress(address);

Wallet.fromPrivateKey(pk);

Wallet.generate();

/* AFTER - v0.60.0 */
WalletUnlocked.fromSeed(seed, provider, path);

WalletUnlocked.fromMnemonic(mnemonic, provider, path, passphrase);

WalletUnlocked.fromExtendedKey(extendedKey, provider);
await WalletUnlocked.fromEncryptedJson(jsonWallet, password, provider);

Wallet.fromAddress(address, provider);

Wallet.fromPrivateKey(pk, provider);

Wallet.generate({ provider });
```

#### 'Account' Class

```typescript
/* BEFORE - v0.57.0 */
const account = new Account(address);

/* AFTER - v0.60.0 */
const account = new Account(address, provider);
```

#### `PrivateKeyVault`

These are the options that are accepted by the `PrivateKeyVault` constructor. `provider` is now a required input.

```typescript
/* BEFORE - v0.57.0 */
interface PkVaultOptions {
  secret?: string;
  accounts?: Array<string>;
}

/* AFTER - v0.60.0 */
interface PkVaultOptions {
  secret?: string;
  accounts?: Array<string>;
  provider: Provider;
}
```

#### `MnemonicVault`

```typescript
/* BEFORE - v0.57.0 */
interface MnemonicVaultOptions {
  secret?: string;
  accounts?: Array<string>;
}

/* AFTER - v0.60.0 */
interface MnemonicVaultOptions {
  secret?: string;
  accounts?: Array<string>;
  provider: Provider;
}
```

#### `WalletManager`

```typescript
/* BEFORE - v0.57.0 */
export type VaultConfig = {
  type: string;
  title?: string;
  secret?: string;
};

/* AFTER - v0.60.0 */
export type VaultConfig = {
  type: string;
  title?: string;
  secret?: string;
  provider: Provider;
};
```

#### Predicates

The `provider` is no longer optional. Note the change in parameter order, and that `chainId` is no longer required to be passed.

```typescript
/* BEFORE - v0.57.0 */
const predicate = new Predicate(bytes, chainId, jsonAbi);

/* AFTER - v0.60.0 */
const predicate = new Predicate(bytes, provider, jsonAbi);
```

## September 18, 2023

### Sway

Release: [Sway v0.46.0](https://github.com/FuelLabs/sway/releases/tag/v0.46.0)

From now on, string literals produce the `str` slice type instead of the string array type. To convert between string arrays and slices, you can use the newly provided intrinsics.

```sway
/* BEFORE - v0.45.0 */
let my_string: str[4] = "fuel";

/* AFTER - v0.46.0 */
let my_string: str = "fuel";
```

If you use a function that needs a specific trait and you don't import that trait, the compiler now will raise an error. This is because the compiler isn't aware of the trait in the current context.

For the example below you would now get an error if the `Hash` trait for `u64` isn't imported. To solve this, ensure you import the "Hash" trait.

```sway
/* BEFORE - v0.45.0 */
storage {
    item_map: StorageMap<u64, Item> = StorageMap {},
}

/* AFTER - v0.46.0 */
use std::{
    hash::Hash,
};

storage {
    item_map: StorageMap<u64, Item> = StorageMap {},
}
```

### TS SDK

Release: [TS SDK v0.57.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.57.0)

The `addResourceInputsAndOutputs()` function has been renamed to `addResources()`, streamlining its name.

```typescript
/* BEFORE - v0.55.0 */
request.addResourceInputsAndOutputs(resources);

/* AFTER - v0.57.0 */
request.addResources(resources);
```

Similarly, `addPredicateResourcesInputsAndOutputs()` is now more concisely known as `addPredicateResources()`.

The reason we have a distinct method for adding predicate resources is that the creation of predicate inputs mandates the presence of both the predicate's bytes and data bytes. With these methods, there's no longer a need to manually create and set up an instance of a `ScriptTransactionRequest`, simplifying the process further.

```typescript
/* BEFORE - v0.55.0 */
const predicateInputs: TransactionRequestInput[] = predicateUtxos.map(
  (utxo) => ({
    id: utxo.id,
    type: InputType.Coin,
    amount: utxo.amount,
    assetId: utxo.assetId,
    owner: utxo.owner.toB256(),
    txPointer: "0x00000000000000000000000000000000",
    witnessIndex: 0,
    maturity: 0,
    predicate: predicate.bytes,
    predicateData: predicate.predicateData,
  })
);

/* AFTER - v0.57.0 */
request.addPredicateResources(
  predicateUtxos,
  predicate.bytes,
  predicate.predicateData
);
```

### Rust SDK

Release: [Rust SDK v0.48.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.48.0)

The function `calculate_base_amount_with_fee()` currently returns a value of type `Option<64>`.

```rust
/* BEFORE - v0.47.0 */
let new_base_amount = calculate_base_amount_with_fee(&tb, &consensus_parameters, previous_base_amount)

/* AFTER - v0.48.0 */
let new_base_amount = calculate_base_amount_with_fee(&tb, &consensus_parameters, previous_base_amount)?
```

The function `calculate_base_amount_with_fee()` now returns a value of type `Result<Option<TransactionFee>>` instead of `Option<TransactionFee>`.

```rust
/* BEFORE - v0.47.0 */
let transaction_fee = tb.fee_checked_from_tx(consensus_params).expect("Error calculating TransactionFee");

/* AFTER - v0.48.0 */
let transaction_fee = tb.fee_checked_from_tx(consensus_params)?.ok_or(error!(InvalidData, "Error calculating TransactionFee"))?;
```

Storage slots are now automatically loaded in when using the default configuration.

```rust
/* BEFORE - v0.47.0 */
let storage_config =
StorageConfiguration::load_from("out/debug/contract-storage_slots.json").unwrap();

let load_config = LoadConfiguration::default().with_storage_configuration(storage_config);

let id = Contract::load_from(
    "./out/debug/contract.bin",
    load_config,
)
.unwrap()
.deploy(&wallet, TxParameters::default())
.await
.unwrap();

/* AFTER - v0.48.0 */
let id = Contract::load_from(
    "./out/debug/contract.bin",
    LoadConfiguration::default(),
)
.unwrap()
.deploy(&wallet, TxParameters::default())
.await
.unwrap();
```


---

### File: docs/nightly/migrations-and-disclosures/docs/src/index.md

# Migrations and Disclosures

## Audits

All public audits conducted on the Fuel network can be found [here](https://github.com/FuelLabs/audits)

## Breaking Changes

Throughout Fuel's development journey, numerous testnets have been created to ensure a seamless transition to the mainnet launch.
Given the dynamic nature of learning and adapting during these testing phases, it's common to encounter breaking changes.

Learn how to migrate to the latest versions of Sway and the SDKs [here](./migrations/index.md)!


---

### File: docs/nightly/migrations-and-disclosures/docs/src/migrations/index.md

# Migrations

This section provides information to help with breaking changes, but for full releases, please reference the GitHub release notes tagged in the respective modules.

## Sway

Full migration reference can be found [here](./sway.md)

## Rust SDK

Full migration reference can be found [here](./rust-sdk.md)

## Typescript SDK

Full migration reference can be found [here](./typescript-sdk.md)


---

### File: docs/nightly/migrations-and-disclosures/docs/src/migrations/rust-sdk.md

# Rust SDK Migrations Guide

## March 17, 2025

[Release v0.71.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.71.0)

### Bump minimum `fuel-core-*` versions - [#1600](https://github.com/FuelLabs/fuels-rs/pull/1600)

Minimum `fuel-core-*` versions bumped to `0.41.7`

```rust
// before
fuel-core = { version = "0.41.3", default-features = false, features = [
  "wasm-executor",
] }
fuel-core-chain-config = { version = "0.41.3", default-features = false }
...
```

```rust
// after
fuel-core = { version = "0.41.7", default-features = false, features = [
  "wasm-executor",
] }
fuel-core-chain-config = { version = "0.41.7", default-features = false }
...
```

### Wallet refactoring - [#1620](https://github.com/FuelLabs/fuels-rs/pull/1620)

#### `ImpersonatedAccount` is removed

To achieve the same functionality instantiate a `FakeSigner:

```rust
// before
let address =
    Address::from_str("0x17f46f562778f4bb5fe368eeae4985197db51d80c83494ea7f84c530172dedd1")
        .unwrap();
let address = Bech32Address::from(address);
let impersonator = ImpersonatedAccount::new(address, Some(provider.clone()));
```

```rust
// after
let some_address = wallet.address().clone();
let fake_signer = FakeSigner::new(some_address);
let impersonator = Wallet::new(fake_signer, provider.clone());
```

#### `AwsKmsSigner` and `GoogleKmsSigner` moved

under `fuels::accounts::signers::kms::aws` and `fuels::accounts::signers::kms::google`, respectfully.

```rust
// before
use fuels::accounts::kms::AwsKmsSigner;
use fuels::accounts::kms::GoogleKmsSigner;
```

```rust
// after
use fuels::accounts::signers::kms::aws::AwsKmsSigner;
use fuels::accounts::signers::kms::google::GoogleKmsSigner;
```

#### `KmsWallet` removed

use an ordinary `Wallet` now with a kms signer (aws or google)

#### `WalletUnlocked` and `Wallet` substituted by `Wallet<Unlocked<S = PrivateKeySigner>>` or `Wallet<Locked>`

```rust
// before
wallet.set_provider(provider.clone());

...

let mut wallet = WalletUnlocked::new_random(None);

let coins: Vec<Coin> = setup_single_asset_coins(
    wallet.address(),
    Default::default(),
    DEFAULT_NUM_COINS,
    DEFAULT_COIN_AMOUNT,
);

let chain_config = ChainConfig {
    consensus_parameters: consensus_parameters.clone(),
    ..ChainConfig::default()
};

let provider = setup_test_provider(coins, vec![], None, Some(chain_config)).await?;
wallet.set_provider(provider.clone());
assert_eq!(consensus_parameters, provider.consensus_parameters().await?);

...

let wallet = WalletUnlocked::new_random(None);
```

```rust
// after
let wallet = Wallet::new(signer, provider.clone());

...

let mut rng = thread_rng();
let signer = PrivateKeySigner::random(&mut rng);

let coins: Vec<Coin> = setup_single_asset_coins(
    signer.address(),
    Default::default(),
    DEFAULT_NUM_COINS,
    DEFAULT_COIN_AMOUNT,
);
let chain_config = ChainConfig {
    consensus_parameters: consensus_parameters.clone(),
    ..ChainConfig::default()
};

let provider = setup_test_provider(coins, vec![], None, Some(chain_config)).await?;
let wallet = Wallet::new(signer, provider.clone());
assert_eq!(consensus_parameters, provider.consensus_parameters().await?);

...

let wallet = launch_provider_and_get_wallet().await?;
```

The provider is now mandatory for `Wallet::new`.

Common operations in the new API:

##### Creating a random wallet

a) Two step (useful when you haven't started the node but need the address)

```rust
    // Create a random private key signer
    let signer = PrivateKeySigner::random(&mut rng);
    let coins = setup_single_asset_coins(signer.address(), asset_id, 1, DEFAULT_COIN_AMOUNT);
    let provider = setup_test_provider(coins.clone(), vec![], None, None).await?;
    let wallet = Wallet::new(signer, provider);
 ```

b) One step (when you already have a provider)

```rust
    let wallet = Wallet::random(&mut rng, provider.clone());
```

##### Locking a wallet

```rust
    let locked_wallet = wallet.lock();
```

##### Creating a locked wallet

```rust
    let wallet = Wallet::new_locked(addr, provider.clone());
```

##### Wallets no longer sign

You use one of the signers for that. Or, if your wallet is unlocked, get its signer by calling `wallet.signer()`.

#### `ViewOnlyAccount` no longer requires `core::fmt::Debug` and `core::clone::Clone` as supertraits

#### `Wallet` no longer handles encrypting keys for disk storage

Use the `fuels::accounts::Keystore` for that (feature-gated under `accounts-keystore`)

#### AWS/Google kms feature flags changed

They're now `accounts-signer-aws-kms` and `accounts-signer-google-kms`.

### Use `total_gas` and `total_fee` from tx status - [#1574](https://github.com/FuelLabs/fuels-rs/pull/1574)

- Removed `get_response_from` method from `CallHandlers`
- `CallResponse` refactored and added `tx_status: Success` field
- Method `get_response` accepts `TxStatus` instead of `Vec<Receipts>`
- Method `new` is removed form `CallResponse`
- `GasValidation` trait is removed from transaction builders
- `Account`s  `transfer` method returns `Result<TxResponse>`
- `Account`s  `force_transfer_to_contract` method returns `Result<TxResponse>`
- `Account`s  `withdraw_to_base_layer` method returns `Result<WithdrawToBaseResponse>`
- `Executable<Loader>`'s `upload_blob` returns `Result<Option<TxResponse>>`
- Contract's `deploy` and `deploy_if_not_exists` return `Result<DeployResponse>` and `Response<Option<DeployResponse>>` respectively
- `TransactionCost`'s field `gas_used` renamed to `script_gas`

## August 16, 2024

[Release v0.66.0](https://github.com/FuelLabs/fuels-rs/releases/tag/v0.66.0)

### Unfunded read only calls - [#1412](https://github.com/FuelLabs/fuels-rs/pull/1412)

`SizedAsciiString` no longer implements `AsRef<[u8]>`. To get the underlying bytes you can turn it into a `&str` via the new `AsRef<str>` and call `as_bytes()` on the `&str`: `sized_string.as_ref().as_bytes()``

```rust
// before
let bytes: &[u8] = sized_str.as_ref();
```

```rust
// after
let bytes: &[u8] = sized_str.as_ref().as_bytes();
```

`build_without_signatures` is now achieved by setting the build strategy to `BuildStrategy::NoSignatures` on the transaction builder before calling `build`

```rust
// before
let mut tx = tb.build_without_signatures(provider).await?;
```

```rust
// after
let mut tx = tb.with_build_strategy(ScriptBuildStrategy::NoSignatures).build(provider).await?;
```

`.simulate()` now accepts an `Execution` argument allowing for `Realistic` or `StateReadOnly` simulations.

```rust
// before
let stored = contract_methods.read().simulate().await?;
```

```rust
// after
let stored = contract_methods.read().simulate(Execution::StateReadOnly).await?;
```

### Accounts now cover max fee increase due to tolerance - [#1464](https://github.com/FuelLabs/fuels-rs/pull/1464)

`fee_checked_from_tx` is removed from all transaction builders. max fee can now be estimated using the new method `estimate_max_fee` which takes into account the max fee estimation tolerance set on the builders.

```rust
// before
let transaction_fee = tb.fee_checked_from_tx(provider)
    .await?
    .ok_or(error_transaction!(
        Other,
        "error calculating `TransactionFee`"
    ))?;

let total_used = transaction_fee.max_fee() + reserved_base_amount;
```

```rust
// after
let max_fee = tb.estimate_max_fee(provider).await?;

let total_used = max_fee + reserved_base_amount;
```

### Account impersonation - [#1473](https://github.com/FuelLabs/fuels-rs/pull/1473)

The SDK previously performed transaction validity checks, including signature verification, before sending a transaction to the network. This was problematic since the checks also included signature verification even when utxo validation was turned off. To enable this feature and prevent future issues like failed validation checks due to version mismatches between the network and the SDK's upstream dependencies, we decided to remove the check. Since the SDK already abstracts building transactions for common cases (contract calls, transfers, etc.), validity issues are unlikely. If needed, we can still expose the validity checks as part of the transaction builder or our transaction structs.

```rust
/*

A `ImpersonatedAccount` simulates ownership of assets held by an account with a given address.
`ImpersonatedAccount` will only succeed in unlocking assets if the the network is setup with
utxo_validation set to false.

*/

let node_config = NodeConfig {
    utxo_validation: false,
    ..Default::default()
};
```

### Deploying large contracts (loader + blob support) - [#1472](https://github.com/FuelLabs/fuels-rs/pull/1472)

`Contract::new` is removed, replaced with `Contract::regular` with three states

First: A regular contract

What you're used to seeing. It is either initialized from raw code or loaded from a file:

```rust
let contract = Contract::regular(contract_binary, Salt::zeroed(), vec![]);
```

or

```rust
let contract = Contract::load_from(
    "sway/contracts/storage/out/release/storage.bin",
    LoadConfiguration::default(),
)?;
```

With the notable addition of being able to set `configurables` (previously possible only when using `load_from`):

```rust
let contract = Contract::regular(binary, Salt::zeroed(), vec![]).with_configurables(configurables);
```

a regular contract can be deployed via `deploy`, which hasn't changed, or via `smart_deploy` that will use blobs/loader if the contract is above what can be deployed in a create tx:

```rust
let contract_id = Contract::load_from(
    contract_binary,
    LoadConfiguration::default().with_salt(random_salt()),
)?
.smart_deploy(&wallet, TxPolicies::default(), max_words_per_blob)
.await?;
```

Second: Loader contract, blobs pending upload

You can turn a regular contract into a loader contract:

```rust
let contract = Contract::load_from(
    contract_binary,
    LoadConfiguration::default(),
)?
.convert_to_loader(max_words_per_blob)?
```

or, if you have the blobs, create it directly:

```rust
let contract = Contract::loader_for_blobs(blobs, random_salt(), vec![])?;
```

You can also revert back to the regular contract via `revert_to_regular`.

If you now call `deploy` the contract will first deploy the blobs and then the loader itself.

You can also split this into two parts by first calling `upload_blobs` and then `deploy`:

```rust
let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())?
    .convert_to_loader(1024)?
    .upload_blobs(&wallet, TxPolicies::default())
    .await?
    .deploy(&wallet, TxPolicies::default())
    .await?;
```

doing so will have `deploy` only submit the create tx while the uploading will be done in `upload_blobs`.

Third: Loader, with blobs deployed

You arrive at this contract type by either having the blob ids and creating it manually:

```rust
let contract = Contract::loader_for_blob_ids(all_blob_ids, random_salt(), vec![])?;
```

or by calling `upload_blobs` as in the previous case:

```rust
let contract = Contract::load_from(
    contract_binary,
    LoadConfiguration::default().with_salt(random_salt()),
)?
.convert_to_loader(max_words_per_blob)?
.upload_blobs(&wallet, TxPolicies::default())
.await?;
```

Calling deploy on this contract only deploys the loader.


---

### File: docs/nightly/migrations-and-disclosures/docs/src/migrations/sway.md

# Sway Migrations Guide

## March 13, 2024

[Release v0.67.0](https://github.com/FuelLabs/sway/releases/tag/v0.67.0)

### New `forc migrate`

Below is a simplified example of how to migrate your project quickly. For more information on how to use `forc migrate` please refer to the [`forc migrate` docs](https://docs.fuel.network/docs/forc/plugins/forc_migrate/#forc-migrate).

> Important: Using `forc migrate` requires you to use the version of Sway right before the breaking change version.

For example, breaking changes for Sway will come in version `v0.67.0`, you will need to use `v0.66.10` to run `forc migrate`, in order to migrate properly.

You can compile and migrate using the previous latest version by running the following command:

```bash
fuelup component add forc@0.66.10
```

#### 1. Run `forc migrate show`

Running `forc migrate show` will inform you about all the breaking changes in the next release. For example:

```sh
Breaking change features:
  - storage_domains            (https://github.com/FuelLabs/sway/issues/6701)
  - partial_eq                 (https://github.com/FuelLabs/sway/issues/6883)
  - try_from_bytes_for_b256    (https://github.com/FuelLabs/sway/issues/6994)
  - merge_core_std             (https://github.com/FuelLabs/sway/issues/7006)

Migration steps (1 manual, 3 semiautomatic, and 3 automatic):
storage_domains
  [M] Review explicitly defined slot keys in storage declarations (`in` keywords)
  [S] Explicitly define storage slot keys if they need to be backward compatible

partial_eq
  [A] Implement experimental `PartialEq` and `Eq` traits
  [S] Remove deprecated `Eq` trait implementations and `experimental_partial_eq` attributes

try_from_bytes_for_b256
  [A] Replace `b256::from(<bytes>)` calls with `b256::try_from(<bytes>).unwrap()`
  [A] Replace `<bytes>.into()` calls with `<bytes>.try_into().unwrap()`

merge_core_std
  [S] Replace `core` with `std` in paths

Experimental feature flags:
- for Forc.toml:  experimental = { storage_domains = true, partial_eq = true, try_from_bytes_for_b256 = true, merge_core_std = true }
- for CLI:        --experimental storage_domains,partial_eq,try_from_bytes_for_b256,merge_core_std
```

#### 2. Update `forc.toml` dependencies

In your Sway project, update the `forc.toml` file to use the previous latest version of Sway.

```toml
// before

[dependencies]
standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.1" }
sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.24.0" }
```

```toml
// after

[dependencies]
standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.3" }
sway_libs = { git = "https://github.com/FuelLabs/sway-libs", tag = "v0.24.2" }
```

#### 3. Run `forc migrate run`

Running `forc migrate run` walks you through each of the breaking changes and helps you apply them to your project.
If you just want to see the breaking changes in your project without migrating them, you can run `forc migrate check`.

```sh
   Compiling mira_amm_contract (/mira-v1-core/contracts/mira_amm_contract)
warning: unused manifest key: build-profile.?.release.experimental
   Migrating Breaking change feature storage_domains
     Checked [storage_domains]  Review explicitly defined slot keys in storage declarations (`in` keywords)
      Review [storage_domains]  Explicitly define storage slot keys if they need to be backward compatible
info: [storage_domains] Explicitly define storage slot keys if they need to be backward compatible
  --> /mira-v1-core/contracts/mira_amm_contract/src/main.sw:65:1
   |
63 |   
64 |   
65 | / storage {
66 | |     /// Pools storage
...  |
79 | |     hook: Option<ContractId> = None,
80 | | }
   | |_-
   |
   = help: If the contract owning this storage is behind a proxy, or for any other reason needs
   = help: to use previous storage slot keys, those keys must be explicitly assigned to the
   = help: storage fields by using the `in` keyword.
   = help:  
   = help: E.g.:
   = help:     storage {
   = help:         field in <previous slot key>: u64 = 0,
   = help:     }
   = help:  
   = help: The previous formula for calculating storage keys was: `sha256("storage.<field name>")`.
   = help: The new formula is:                                    `sha256((0u8, "storage.<field name>"))`.
   = help:  
   = help: This migration step will interactively modify the code, based on your input.
   = help:  
   = help: For a detailed migration guide see: https://github.com/FuelLabs/sway/issues/6701
____

The following storage fields will have slot keys calculated by using the new formula:
  - storage.pools
  - storage.total_pools
  - storage.total_reserves
  - storage.lp_total_supply
  - storage.lp_name
  - storage.protocol_fees
  - storage.hook

Do you want these fields to have backward compatible storage slot keys, calculated
by using the previous formula?

If yes, this migration step will insert `in` keywords to all of the above fields,
and calculate the storage slot keys by using the previous formula.

1. Yes, assign the backward compatible storage slot keys.
2. No, this contract does not require backwards compatibility.
Enter your choice [1..2]: 1
    Changing [storage_domains]  Explicitly define storage slot keys if they need to be backward compatible
Source code successfully changed (7 changes).
    Finished Project is compatible with the next breaking change version of Sway
```

#### 4. Switch to the latest version of Sway

```sh
// Assuming you have 0.67.0 installed
fuelup default latest
```

#### 5. Compile your project

```sh
forc build
```

> Using the `forc migrate` tool is highly recommended, and the changes below are only for reference.

### Compiler/std-lib: storage collison between variables and StorageMap, allows hidden backdoors, likely loss of funds - [#6701](https://github.com/FuelLabs/sway/issues/6701)

Certain storage types, like, e.g., `StorageMap` allow storage slots of their contained elements to be defined based on developer's input. E.g., the key in a `StorageMap` used to calculate the storage slot is a developer input.

To ensure that pre-images of such storage slots can never be the same as a pre-image of compiler generated key of a storage field, we will prefix the pre-images of storage fields with a single byte that denotes the storage field domain. Storage types like `StorageMap` must have a different domain prefix than this storage field domain which will be set to 0u8.

```sway
// before
sha256("storage::<optional namespace 1>::<optional namespace 2>.<field name>")
```

```sway
// after
sha256((0u8, "storage::<optional namespace 1>::<optional namespace 2>.<field name>"))
```

If the contract owning the storage is behind a proxy, its storage field keys must be backward compatible and the same as the old keys. In this, and any other case where the backward compatibility of the storage slot keys is needed, the old keys must be explicitly defined for storage fields, by using the in keyword and the old keys.

E.g., assume we have a contract with the following storage behind a proxy:

```sway
// before
storage {
    x: u64 = 0,
    namespace_1 {
        y: u64 = 0,
        namespace_2 {
            z: u64 = 0,
        }
    }
}
```

```sway
// after
storage {
    x in 0xc979570128d5f52725e9a343a7f4992d8ed386d7c8cfd25f1c646c51c2ac6b4b: u64 = 0,
    namespace_1 {
        y in 0x2f055029200cd7fa6751421635c722fcda6ed2261de0f1e0d19d7f257e760589: u64 = 0,
        namespace_2 {
            z in 0x03d2ee7fb8f3f5e1084e86b02d9d742ede96559e44875c6210c7008e2d184694: u64 = 0,
        }
    }
}
```

### Replace `Eq` trait implementations with `PartialEq` and `Eq` implementations - [#6883](https://github.com/FuelLabs/sway/issues/6883)

Partial equivalence feature renames the current `Eq` trait to `PartialEq` and adds a new, empty `Eq` trait with `PartialEq` as a supertrait.

Every existing `Eq` trait implementation needs to be renamed to `PartialEq`, and in addition, an empty `Eq` implementations needs to be added.

```sway
// before
impl Eq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}
```

```sway
// after
impl PartialEq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}

impl Eq for SomeType {}
```

If the original implementation implements Eq for a generic type and in addition has Eq on trait constraints, those Eq trait constraints must be replaced by PartialEq in the new PartialEq impl, and remain Eq in the new, empty, Eq impl.

```sway
// before
impl<A, B> Eq for (A, B)
where
    A: Eq,
    B: Eq,
{
    fn eq(self, other: Self) -> bool {
        self.0 == other.0 && self.1 == other.1
    }
}
```

```sway
// after
impl<A, B> PartialEq for (A, B)
where
    A: PartialEq,
    B: PartialEq,
{
    fn eq(self, other: Self) -> bool {
        self.0 == other.0 && self.1 == other.1
    }
}

impl<A, B> Eq for (A, B)
where
    A: Eq,
    B: Eq,
{}
```

### Implement `TryFrom<Bytes>` for `b256` - [#6994](https://github.com/FuelLabs/sway/issues/6994)

Replace calls to `from(bytes)/bytes.into()` with `try_from(bytes)/bytes.try_into()`.

Calls to `from`:

```sway
// before
let result = b256::from(some_bytes);
```

```sway
// after
let result = b256::try_from(some_bytes).unwrap();
```

Calls to `into`:

```sway
// before
let result = some_bytes.into();
```

```sway
// after
let result = some_bytes.try_into().unwrap();
```

### Merge `core` and `std` libraries - [#7006](https://github.com/FuelLabs/sway/issues/7006)

Currently, we have two standard libraries, `core` and `std`. The distinction between them is rather arbitrary, and we want to merge them into a single library called `std`. All the existing modules in the `core` library will be moved to the `std` library, but their content will not be changed.

```sway
// before
use core::ops::*;

impl core::ops::Eq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}

let _ = core::codec::encode(0u64);
```

```sway
// after
use std::ops::*;

impl std::ops::Eq for SomeType {
    fn eq(self, other: Self) -> bool {
        self.x == other.x
    }
}

let _ = std::codec::encode(0u64);
```

## August 16, 2024

[Release v0.63.0](https://github.com/FuelLabs/sway/releases/tag/v0.63.0)

### `#[namespace()]` attribute is no longer supported - [#6279](https://github.com/FuelLabs/sway/pull/6279)

We no longer support the `#[namespace()]` attribute.  If you use it, notably with SRC14, you should migrate to using the `in` keyword if you want backwards compatibility.  If you just care about namespacing, you should use the new namespacing syntax.

Backwards compatibility places `foo` at `sha256("storage_example_namespace_0")`

```sway
// before
#[namespace(example_namespace)]
storage {
    foo: u64 = 0,
}
```

```sway
// after
storage {
    foo in 0x1102bf23d7c2114d6b409df4a1f8f7982eda775e800267be65c1cc2a93cb6c5c: u64 = 0,
}
```

New / recommended method places `foo` at `sha256("storage::example_namespace.foo")`

```sway
// new
storage {
    example_namespace {
        foo: u64 = 0,
    },
}
```

### Configurables are no longer allowed in pattern matching and shadowing - [#6289](https://github.com/FuelLabs/sway/pull/6289)

The code below does not compile any more.

```sway
configurable {
    X: u8 = 10,
}

fn main() {
    let X = 101u8; // ERROR: Variable "X" shadows configurable of the same name.
}
```

```sway
configurable {
    X: u8 = 10,
}

fn main() {
    match var {
        (0, X) => true // ERROR: "X" is a configurable and configurables cannot be matched against.
    }
}
```

### New ABI specification format - [#6254](https://github.com/FuelLabs/sway/pull/6254)

The new ABI specification format is hash based to improve support for indexing.  There were also updates to support the latest VM features.

### Added variable length message support when verifying ed signatures - [#6419](https://github.com/FuelLabs/sway/pull/6419)

`ed_verify` was changed to use `Bytes` for the message instead of `b256` for a message hash.

```sway
// before
pub fn ed_verify(public_key: b256, signature: B512, msg_hash: b256)
```

```sway
// after
pub fn ed_verify(public_key: b256, signature: B512, msg: Bytes)
```

### Some STD functions now return an `Option` instead of reverting - [#6405](https://github.com/FuelLabs/sway/pull/6405), [#6414](https://github.com/FuelLabs/sway/pull/6414), [#6418](https://github.com/FuelLabs/sway/pull/6418)

Some functions in the STD now return an `Option` instead of reverting.  This allows developers to fail gracefully.  More functions will do this in the future.

```sway
// before
let my_predicate_address: Address = predicate_address();
```

```sway
// after
let my_predicate_address: Address = predicate_address().unwrap();
```

### Some STD functions now return types have been updated to match the Fuel Specifications

- `output_count()` now returns a `u16` over a `u64`

Before:

```sway
let output_count: u64 = output_count();
```

After:

```sway
let my_output_count: u16 = output_count();
```

- `tx_maturity` now returns an `Option<u32>` over an `Option<u64>`

Before:

```sway
let my_tx_maturity: u64 = tx_maturity().unwrap()
```

After:

```sway
let my_tx_maturity: u32 = tx_maturity().unwrap()
```

### Some STD functions have been made private. These will no longer be available for developers to use

- `input_pointer()`
- `output_pointer()`
- `tx_witness_pointer()`
- `tx_script_start_pointer()`
- `tx_script_data_start_pointer()`

The following functions now follow this format:

Inputs:

- `input_type()`
- `input_predicate_data()`
- `input_predicate()`
- `input_message_sender()`
- `input_message_recipient()`
- `input_message_data_length()`
- `input_message_data()`
- `input_message_nonce()`

Outputs:

- `output_type()`
- `output_amount()`

Transactions:

- `tx_script_length()`
- `tx_script_data_length()`
- `tx_witness_data_length()`
- `tx_witness_data()`
- `tx_script_data()`
- `tx_script_bytecode()`
- `tx_script_bytecode_hash()`

### Non-breaking Changes

New partial support for slices.

Automated proxy creation and deployment with forc.


---

### File: docs/nightly/migrations-and-disclosures/docs/src/migrations/typescript-sdk.md

# TypeScript SDK Migrations Guide

## May 19, 2025

[Release v0.101.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.101.0)

### Enforce `predicateData` when predicate has arguments - [#3886](https://github.com/FuelLabs/fuels-ts/pull/3886)

Predicates that define arguments must now be instantiated with the data property. It is no longer allowed to omit data when the predicate expects input arguments.

For example, for the given predicate:

```rs
predicate;

fn main(pin: u64) -> bool {
    return 999 == pin;
}
```

The following code would compile, even though the predicate expects arguments:

```ts
// before
const predicateNoData = new PredicatePin({ provider }) // ✅ Allowed (incorrectly)

const predicate = new PredicatePin({ provider, data: [100] }) // ✅ Correct
```

TypeScript now enforces that data must be provided:

```ts
// after
const predicateNoData = new PredicatePin({ provider }) // ❌ Error: missing required `data`

const predicate = new PredicatePin({ provider, data: [100] }) // ✅ Correct
```

### Remove `BaseInvocationScope.getTransactionId()` - [#3864](https://github.com/FuelLabs/fuels-ts/pull/3864)

- `getTransactionId()` is no longer available on the `BaseInvocationScope`.

```ts
// before
const contract = new CounterContract(contractId, wallet)

const scope = contract.functions.get_counter()

const txId = await scope.getTransactionId()
```

```ts
// after
const contract = new CounterContract(contractId, wallet)

const request = contract.functions.get_counter().fundWithRequiredCoins()

const chainId = await provider.getChainId()

const txId = await scope.getTransactionId(chainId)
```

## March 17, 2025

[Release v0.100.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.100.0)

### Made `ResourceCache` consider resource owner - [#3697](https://github.com/FuelLabs/fuels-ts/pull/3697)

```ts
//before
provider.cache?.getActiveData();
provider.cache?.isCached(key);
```

```ts
//after
const owner = wallet.address.toB256();

provider.cache?.getActiveData(owner)
provider.cache?.isCached(owner, key);
```

### Upgrade `fuel-core` to `0.41.7` - [#3590](https://github.com/FuelLabs/fuels-ts/pull/3590)

Because of the latest `fuel-core` changes, TS SDK does not throw the following error codes and messages anymore:

#### 1. **NOT_ENOUGH_FUNDS**

```ts
// before
"The account(s) sending the transaction don't have enough funds to cover the transaction."
```

```ts
// after
"Insufficient funds or too many small value coins. Consider combining UTXOs."
```

#### 2. **MAX_COINS_REACHED**

```ts
// before
"The account retrieving coins has exceeded the maximum number of coins per asset. Please consider combining your coins into a single UTXO."
```

```ts
// after
"Insufficient funds or too many small value coins. Consider combining UTXOs."
```

Both error codes were removed in favor of `INSUFFICIENT_FUNDS_OR_MAX_COINS`

## February 4, 2025

[Release v0.99.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.99.0)

### Remove `pageInfo` from `getBalances` GraphQL operations - [#3652](https://github.com/FuelLabs/fuels-ts/pull/3652)

- The `pageInfo` field has been removed from the response of the `provider.operations.getBalances` query.

```ts
// before
const { balances, pageInfo } = await provider.operations.getBalances({
  first: 100,
  filter: { owner: wallet.address.toB256() },
});
```

```ts
// after
const { balances } = await provider.operations.getBalances({
  first: 100,
  filter: { owner: wallet.address.toB256() },
});
```

The `getBalances` method of the Provider class remains unchanged, as it never returned pageInfo:

```ts
// not affected
const { balances } = await provider.getBalances();
```

### Remove `ContractUtils` namespaced export - [#3570](https://github.com/FuelLabs/fuels-ts/pull/3570)

- `ContractUtils` was removed and the underlying functions `getContractRoot()`, `getContractStorageRoot()`, `getContractId()`, `hexlifyWithPrefix()` are now exported directly from `fuels`.

```ts
// before
import { ContractUtils } from 'fuels';
```

```ts
// after
import { getContractRoot, getContractStorageRoot, getContractId, hexlifyWithPrefix } from 'fuels';
```

## January 10, 2025

[Release v0.98.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.98.0)

### Making `provider` initialization `sync` again - [#3514](https://github.com/FuelLabs/fuels-ts/pull/3514)

#### 1. `Provider` Instantiation

- Going from `async` to `sync`

```ts
// before
const provider = await Provider.create(NETWORK_URL);
```

```ts
// after
const provider = new Provider(NETWORK_URL);
```

#### 2. `Provider` methods

- The following methods are now `async`

```ts
// before
provider.getNode();
provider.getChain();
provider.getChainId();
provider.getBaseAssetId();
provider.getGasConfig();
provider.validateTransaction();
```

```ts
// after
await provider.getNode();
await provider.getChain();
await provider.getChainId();
await provider.getBaseAssetId();
await provider.getGasConfig();
await provider.validateTransaction();
```

#### 3. `TransferParams` and `ContractTransferParams`

- Property `assetId` is now required by [`TransferParams`](https://github.com/FuelLabs/fuels-ts/blob/5d96eb6748e4210029bcbca0490172de81487e05/packages/account/src/account.ts#L56-L60) and [`ContractTransferParams`](https://github.com/FuelLabs/fuels-ts/blob/5d96eb6748e4210029bcbca0490172de81487e05/packages/account/src/account.ts#L62-L66)

```diff
export type TransferParams = {
  destination: string | AbstractAddress;
  amount: BigNumberish;
-  assetId?: BytesLike;
+  assetId: BytesLike;
};

export type ContractTransferParams = {
  contractId: string | AbstractAddress;
  amount: BigNumberish;
-  assetId?: BytesLike;
+  assetId: BytesLike;
};
```

#### 4. Transaction Response

- The constructor now requires a `chainId`

```ts
// before
new TransactionResponse('0x..', provider);
```

```ts
// after
new TransactionResponse('0x..', provider, chainId);
```

### `autoCost` for transaction estimation and funding - [#3539](https://github.com/FuelLabs/fuels-ts/pull/3539)

  To be brought inline with `autoCost`, funding a contract and script call has been migrated from `fundWithRequiredCoins` to `autoCost`:

```ts
// before
const request: ScriptTransactionRequest = contract.functions.add(1).fundWithRequiredCoins();
```

```ts
// after
const request: ScriptTransactionRequest = contract.functions.add(1).autoCost();
```

### Remove redundant gas price call for tx summary - [#3559](https://github.com/FuelLabs/fuels-ts/pull/3559)

- `calculateTXFeeForSummary` and subsequently the `CalculateTXFeeForSummaryParams` no longer accept a `totalFee` property. If you have the `totalFee`, then there is no need to call the `calculateTxFeeForSummary()` function.

```ts
// before
const totalFee = bn(..):
calculateTXFeeForSummary({ ..., totalFee } as CalculateTXFeeForSummaryParams);
```

```ts
// after
calculateTXFeeForSummary({ ... } as CalculateTXFeeForSummaryParams);
```

### Prevent implicit asset burn - [#3540](https://github.com/FuelLabs/fuels-ts/pull/3540)

  ```ts
// before
const transactionRequest = new ScriptTransactionRequest();
transactionRequest.inputs.push({ ... });

// since outputs weren't added, assets would be burned
await sender.sendTransaction(transactionRequest);
```

```ts
// after
const transactionRequest = new ScriptTransactionRequest();
transactionRequest.inputs.push({ ... });

// now, an error will be thrown unless `enableAssetBurn`is true,
// in which case, assets can still be burned
await sender.sendTransaction(transactionRequest, {
  enableAssetBurn: true,
});
```

### Remove unused operations - [#3553](https://github.com/FuelLabs/fuels-ts/pull/3553)

  The following operations have been removed from the `OperationName` enum, as they were never used to assemble operations:

- `OperationName.mint`
- `OperationName.predicatecall`
- `OperationName.script`
- `OperationName.sent`

### Remove receipts deprecated properties - [#3552](https://github.com/FuelLabs/fuels-ts/pull/3552)

  All receipts deprecated properties were removed:

```ts
// before
ReceiptCall.from

ReceiptLog.val0
ReceiptLog.val1
ReceiptLog.val2
ReceiptLog.val3

ReceiptLogData.val0
ReceiptLogData.val1

ReceiptTransfer.from

ReceiptTransferOut.from
```

```ts
// after
ReceiptCall.id

ReceiptLog.ra
ReceiptLog.rb
ReceiptLog.rc
ReceiptLog.rd

ReceiptLogData.ra
ReceiptLogData.rb

ReceiptTransfer.id

ReceiptTransferOut.id
```

### Remove receipt coders - [#3551](https://github.com/FuelLabs/fuels-ts/pull/3551)

  All previously deprecated receipt coders have been removed. These classes were barely used aside from a few internal helpers, which were converted to utility functions.

```ts
// before
const messageId = ReceiptMessageOutCoder.getMessageId({
  sender,
  recipient,
  nonce,
  amount,
  data,
});

const assetId = ReceiptMintCoder.getAssetId(contractId, subId);

const assetId = ReceiptBurnCoder.getAssetId(contractId, subId);
```

```ts
// after
import { getMessageId, getAssetId } from 'fuels'

const messageId = getMessageId({
  sender,
  recipient,
  nonce,
  amount,
  data,
});

const assetId = getAssetId(contractId, subId);
```

### Remove deprecated `submitAndAwait` operation - [#3548](https://github.com/FuelLabs/fuels-ts/pull/3548)

- `submitAndAwait` operation was removed

After being deprecated since #3101, we have removed this operation altogether. Please use the `submitAndAwaitStatus` method instead which gives the same results as `submitAndAwait`. If you are interested in the deprecation/removal reasons, please refer to https://github.com/FuelLabs/fuel-core/issues/2108.

```ts
// before
const response = await provider.operations.submitAndAwait(txRequest);
```

```ts
// after
const response = await provider.operations.submitAndAwaitStatus(txRequest);
```

### Remove Bech32 address - [#3493](https://github.com/FuelLabs/fuels-ts/pull/3493)

- We no longer support Bech32 addresses

```ts
// before
import { Address, Bech32Address } from "fuels";

const bech32Address: Bech32Address = "fuel1234";
const address = new Address(bech32Address);
```

```ts
// after
import { Address, B256Address } from "fuels";

const b256Address: B256Address = "0x1234";
const address = new Address(b256Address);
```

- Removed `INVALID_BECH32_ADDRESS` error code.

- Removed associated Bech32 helper functions.
  - `normalizeBech32`
  - `isBech32`
  - `toB256`
  - `getBytesFromBech32`
  - `toBech32`
  - `clearFirst12BytesFromB256`

### Redistributed the `@fuel-ts/interfaces` package - [#3492](https://github.com/FuelLabs/fuels-ts/pull/3492)

- Removed the `AbstractAddress` class; use the `Address` class instead.

```ts
// before
import { AbstractAddress } from 'fuels';
```

```ts
// after
import { Address } from 'fuels';
```

- Removed the `@fuel-ts/interfaces` package; use the `fuels` package instead.

```ts
// before
import { BytesLike } from '@fuel-ts/interfaces'
```

```ts
// after
import { BytesLike } from 'fuels'
```

### Optimizing frontend apps - [#3573](https://github.com/FuelLabs/fuels-ts/pull/3573)

- `ScriptTransactionRequest.autoCost()` has been renamed to `ScriptTransactionRequest.estimateAndFund()`, initially introduced by #3535

```ts
// before
await request.autoCost(wallet);
```

```ts
// after
await request.estimateAndFund(wallet);
```

- `BaseInvocationScope.autoCost()` has been renamed back to `BaseInvocationScope.fundWithRequiredCoins()`, initially introduced by #3535

```ts
// before
const request = await contract.functions.increment().autoCost();
```

```ts
// after
const request = await contract.functions.increment().fundWithRequiredCoins();
```

## November 15, 2024

[Release v0.97.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.97.0)

### `onDeploy` fuels config supports all Sway program types - [#3383](https://github.com/FuelLabs/fuels-ts/pull/3383)

- Changed the outputted data from the `onDeploy` callback method for the `fuels.config.ts`. Instead of just emitting the deployed contracts (as an array), it will now emit an object with `contracts`, `predicates` and `scripts`.

```ts
// Before (fuels.config.ts)
import { createConfig, FuelsConfig, DeployedContract } from 'fuels';

export default createConfig({
  output: 'dir/out',
  onDeploy: (config: FuelsConfig, deployedContracts: DeployedContract[]) => {
    console.log('contracts', deployedContracts);
  }
});
```

```ts
// After (fuels.config.ts)
import { createConfig, FuelsConfig, DeployedData } from 'fuels';

export default createConfig({
  output: 'dir/out',
  onDeploy: (config: FuelsConfig, deployed: DeployedData[]) => {
    console.log('contracts', deployed.contracts);
    console.log('predicates', deployed.predicates);
    console.log('scripts', deployed.scripts);
  }
});
```

### Remove unnecessary nonce from message gql queries - [#3298](https://github.com/FuelLabs/fuels-ts/pull/3298)

- Removed the `nonce` property from `Provider.operations.getMessageByNonce()`. This can still be retrieved by `Provider.getMessageByNonce()`.

### Refactor predicate and script deployment - [#3389](https://github.com/FuelLabs/fuels-ts/pull/3389)

  `ContractFactory.deployAsBlobTxForScript` has been removed in favor of `Predicate.deploy` and `Script.deploy`:

```ts
// before
const factory = new ContractFactory(scriptBytecode, scriptAbi, wallet);
const { waitForResult } = await factory.deployAsBlobTxForScript();
const { loaderBytecode, configurableOffsetDiff } = await waitForResult();

// after
const script = new Script(scriptBytecode, scriptAbi, wallet);
const { blobId, waitForResult } = await script.deploy(deployerWallet);
const loaderScript = await waitForResult();

const predicate = new Predicate({ bytecode, abi, provider });
const { blobId, waitForResult } = await predicate.deploy(deployerWallet);
const loaderPredicate = await waitForResult();
```

### Mandate `abi` in `Predicate` constructor - [#3387](https://github.com/FuelLabs/fuels-ts/pull/3387)

- Instantiating a `Predicate` now requires providing its `abi`. If you want to use the `Predicate` as an `Account`, please instantiate it via the `Account` class

```ts
// before
const predicate = new Predicate({ provider, bytecode }); // worked even though abi is missing

// after
const predicate = new Predicate({ abi, provider, bytecode }); // abi is now mandatory

// predicate as account
const account = new Account(predicateAddress, provider);
```

### Optimize `getTransactions` query - [#3336](https://github.com/FuelLabs/fuels-ts/pull/3336)

- The response format for `Provider.getTransactions` remains the same. However, the response format for the query `Provider.operations.getTransactions` has been modified.

```graphql
// before
query getTransactions {
  id
  rawPayload
  status {
    ...
  }
}
```

```graphql
// after
query getTransactions {
  rawPayload
}
```

### Limit TX pagination number for `getTransactionsSummaries` - [#3400](https://github.com/FuelLabs/fuels-ts/pull/3400)

- The pagination number for `getTransactionsSummaries` is limited to `60` now

```ts
// before
const { transactions } = await getTransactionsSummaries({
  provider,
  filters: {
    owner: account.address.toB256(),
    first: 200,
  },
});
```

```ts
// after
const { transactions } = await getTransactionsSummaries({
  provider,
  filters: {
    owner: account.address.toB256(),
    first: 60, // Limit is 60 now. A higher value will result in an error
  },
});
```

### Remove `blockId` in transaction list responses - [#3379](https://github.com/FuelLabs/fuels-ts/pull/3379)

- The `blockId` property has been removed from the following GraphQL queries used to list past transactions:

```ts
const { transactions } = await getTransactionsSummaries({ ... });

const { transactionsByOwner } = await provider.operations.getTransactionsByOwner({ ... });
```

If the `blockId` is required for a given transaction, it needs to be queried separately with `getTransactionSummary` helper:

```ts
import { getTransactionSummary } from 'fuels';

const transaction = await getTransactionSummary({
  id,
  provider,
});
```

*Note: The `blockId` is still available in the result for a submitted transaction.*

### Optimize coin gql queries - [#3301](https://github.com/FuelLabs/fuels-ts/pull/3301)

- The `Provider.operations.getCoins()` and  `Provider.operations.getCoinsToSpend` function no longer return the owner. These methods shouldn't be called directly but are used internally to formulate responses from the SDK.

- Removed the property `owner` from the `Provider.operations.getCoinsToSpend()` function. Suggest to use the owner from the input parameters.

## October 13, 2024

[Release v0.96.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.96.0)

### Checksum method to remove `0x` before hashing - [#3313](https://github.com/FuelLabs/fuels-ts/pull/3313)

  We fixed the checksum utilities:

- `Address.toChecksum()`
- `Address.isChecksumValid()`

Now, we correctly remove the leading `0x` before hashing the address.

Because of this, previous values were invalid, and the update is required.

## October 10, 2024

[Release v0.95.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.95.0)

### Bump transaction pagination limit to 60 - [#3306](https://github.com/FuelLabs/fuels-ts/pull/3306)

- A limit was added of 60 transactions to the `provider.getTransactions()` method.

### Made Address `toString` and `valueOf` returns checksum - [#3310](https://github.com/FuelLabs/fuels-ts/pull/3310)

  The return of both `Address.toString()` and `Address.valueOf` was modified to return the address checksum instead of the Bech32 string

```ts
// before
const address = new Address('fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e');

address.toString()
// fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e

address.valueOf()
// fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e
```

```ts
// after
const address = new Address('fuel1elnmzsav56dqnp95sx4e2pckq36cvae9ser44m5zlvgtwxw49fmqd7e42e');

address.toString()
// 0xEf86aFa9696Cf0dc6385e2C407A6e159A1103cEfB7E2Ae0636FB33d3cb2A9E4A

address.valueOf()
// 0xEf86aFa9696Cf0dc6385e2C407A6e159A1103cEfB7E2Ae0636FB33d3cb2A9E4A
```

### Slim down `chainInfoFragment` and `GasCostsFragment` - [#3286](https://github.com/FuelLabs/fuels-ts/pull/3286)

- `latestBlock` is no longer part of the `ChainInfo` return of `provider.getChain()`. You can fetch it via `provider.getBlock('latest')`.
- `ChainInfo['consensusParameters']['gasCosts']` has been slimmed down to only contain data necessary for the operation of the SDK. Up until now, the SDK was fetching more than it needed. If this change affects you, you will have to create a custom graphql query for `gasCosts` for the additional data you need.

### Optimize balance queries - [#3296](https://github.com/FuelLabs/fuels-ts/pull/3296)

- Removed the `owner` and `assetId` properties from the response of `Provider.operations.getBalance()`. These properties are also required arguments to execute the function so are redundant in the response. Should you require these values, you should take them from the values that you passed to the function.
- Removed the `owner` property from the response of `Provider.operations.getBalances()`. This property is a required argument to execute the function so is redundant in the response. Should you require this value, you should take it from the value that you passed to the function.

## August 30, 2024

[Release v0.94.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.94.0)

### Consider message on resources cache - [#2872](https://github.com/FuelLabs/fuels-ts/pull/2872)

  The provider option flag `cacheUtxo` was renamed to `resourceCacheTTL`

```ts
// before
const provider = await Provider.create(FUEL_NETWORK_URL, {
  cacheUtxo: 5000,
});


using launched = await launchTestNode({
  providerOptions: {
    cacheUtxo: 5000,
  },
});
```

```ts
// after
const provider = await Provider.create(FUEL_NETWORK_URL, {
  resourceCacheTTL: 5000,
});

using launched = await launchTestNode({
  providerOptions: {
    resourceCacheTTL: 5000,
  },
});
```

### Prettify `typegen` api - [#2824](https://github.com/FuelLabs/fuels-ts/pull/2824)

### `Predicate` class

- `Predicate` class constructor parameters renamed: `inputData` > `data`

```ts
// before
import { Predicate } from 'fuels';

const predicate = new Predicate({
  ...unchangedParameters,
  inputData,
});
```

```ts
// after
import { Predicate } from 'fuels';

const predicate = new Predicate({
  ...unchangedParameters,
  data,
});
```

- Typegen extended/generated `Predicate` now accepts a single parameter for initialization

```ts
// before
import { TestPredicateAbi__factory } from './typegend';

TestPredicateAbi__factory.createInstance(provider, data, configurableConstants);
```

```ts
// after
import { TestPredicate } from './typegen';

new TestPredicate({
  provider,
  data,
  configurableConstants
});
```

### `launchTestNode` utility

- Renamed `contractsConfigs[].deployer` to  `contractsConfigs[].factory`
- Removed `contractsConfigs[].bytecode` and `.hex.ts` file

The bytecode is now saved within the factory class, so you don't have to deal with it.

```ts
// before
import { TokenAbi__factory } from './typegend';
import TokenAbiHex from './typegend/contracts/TokenAbi.hex';

using launched = await launchTestNode({
  contractsConfigs: [{
    deployer: TokenAbi__factory,
    bytecode: TokenAbiHex
  }],
});
```

```ts
// after
import { TokenFactory } from './typegend';

using launched = await launchTestNode({
  contractsConfigs: [{
    factory: TokenFactory,
  }],
})
```

### Renamed method `deployContract` to `deploy`

Removed the redundant suffix on the `ContractFactory` class method name.

```ts
// before
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(wallet);

factory.deployContract();
```

```ts
// after
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(wallet);

factory.deploy();
```

### Typegen `Contract` template

- Removed `Abi__factory` suffix from class names
- The file `<name>.hex` was removed (access it via `<Name>.bytecode`)
- The files `<name>__factory.ts` and `<name>.d.dts` were merged into `<name>.ts`
- The class `<Name>` and the interface `<Name>Abi` are now just `<Name>`
- Method `<Name>Factory.deployContract()` renamed to `<Name>Factory.deploy()`
- You may need to remove the previously generated `<typegenDir>/contracts/factories` directory

```ts
// before
import { TestContractAbi, TestContract__factory } from './typegen'
import testContractBytecode from './typegen/contracts/TestContract.hex'

const instance = await TestContract__factory.connect(id, wallet);

const deploy = await TestContract__factory.deployContract(testContractBytecode, wallet);
const { contract } = await deploy.waitForResult();
```

```ts
// after
import { TestContract, TestContractFactory } from './typegen'

const instance = new TestContract(id, wallet);

const deploy = await TestContractFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();
```

### Typegen `Predicate` template

- Removed `Abi__factory` suffix from class names
- Started accepting a single parameter object in constructor
- You may need to remove the previously generated `<typegenDir>/predicates/factories` directory

```ts
// before
import { TestPredicateAbi__factory } from './typegen'

const predicate = TestPredicateAbi__factory.createInstance(provider);
```

```ts
// after
import { TestPredicate } from './typegen'

const predicate = new TestPredicate({ provider });
```

### Typegen `Script` template

- Removed `Abi__factory` suffix from class names
- You may need to remove the previously generated `<typegenDir>/scripts/factories` directory

```ts
// before
import { TestPredicateAbi__factory } from './typegen'

const script = TestScriptAbi__factory.createInstance(wallet);
```

```ts
// after
import { TestPredicate } from './typegen'

const script = new TestScript(wallet);
```

### Non-blocking blob deployment - [#2929](https://github.com/FuelLabs/fuels-ts/pull/2929)

The transaction ID from a contract deployment is now returned as a promise.

```ts
// before
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(bytecode, abi, wallet);
const { waitForResult, contractId, transactionId } = await factory.deploy();
console.log(transactionId); // 0x123....
```

```ts
// after
import { ContractFactory } from 'fuels';

const factory = new ContractFactory(bytecode, abi, wallet);
const { waitForResult, contractId, waitForTransactionId } = await factory.deploy();
const transactionId = await waitForTransactionId();
console.log(transactionId); // 0x123....
```

### Improve `()` and `Option<T>` type handling - [#2777](https://github.com/FuelLabs/fuels-ts/pull/2777)

- `()` and `Option<T>` Sway types are now either required or optional, dependent on where the argument appears in the function arguments.

Given these Sway functions:

```sway
fn type_then_void_then_type(x: u8, y: (), z: u8) -> ()
fn type_then_void_then_void(x: u8, y: (), z: ()) -> ()

fn type_then_option_then_type(x: u8, y: Option<u8>, z: u8) -> ()
fn type_then_option_then_option(x: u8, y: Option<u8>, z: Option<u8>) -> ()
```

This is what changes:

```ts
// before
contract.functions.type_then_void_then_type(42, 43)
contract.functions.type_then_void_then_void(42) // Unchanged

contract.functions.type_then_option_then_type(42, undefined, 43)
contract.functions.type_then_option_then_option(42, undefined, undefined)
```

```ts
// after
contract.functions.type_then_void_then_type(42, undefined, 43)
contract.functions.type_then_void_then_void(42) // Unchanged

contract.functions.type_then_option_then_type(42, undefined, 43)
contract.functions.type_then_option_then_option(42)
```

### `fuel-core@0.32.1` and large contract deployments - [#2827](https://github.com/FuelLabs/fuels-ts/pull/2827)

  `MAX_CONTRACT_SIZE` is no longer exported, it should now be fetched from the chain.

```ts
// before
import { MAX_CONTRACT_SIZE } from 'fuels';
```

```ts
// after
import { Provider, FUEL_NETWORK_URL } from 'fuels';

const provider = await Provider.create(FUEL_NETWORK_URL);
const { consensusParameters } = provider.getChain();
const maxContractSize = consensusParameters.contractParameters.contractMaxSize.toNumber();
```

### Deprecate `FUEL_NETWORK_URL` and `LOCAL_NETWORK_URL`- [#2915](https://github.com/FuelLabs/fuels-ts/pull/2915)

  Removed `FUEL_NETWORK_URL` constant.

```ts
// before
import { FUEL_NETWORK_URL } from 'fuels';

const provider = await Provider.create(FUEL_NETWORK_URL);
```

```ts
// after
const provider = await Provider.create('https://127.0.0.1:4000/v1/graphql');
```

Removed `LOCAL_NETWORK_URL` constant.

```ts
// before
import { LOCAL_NETWORK_URL } from 'fuels';

const provider = await Provider.create(LOCAL_NETWORK_URL);
```

```ts
// after
const provider = await Provider.create('https://127.0.0.1:4000/v1/graphql');
```

### Integrate `launchTestNode` in remaining packages - [#2811](https://github.com/FuelLabs/fuels-ts/pull/2811)

  Removed `generateTestWallet` and `seedTestWallet` utilities.

```ts
// before
import { bn } from "@fuel-ts/math";
import {
  seedTestWallet,
  generateTestWallet,
} from "@fuel-ts/account/test-utils";

const provider = await Provider.create("http://127.0.0.1:4000/v1/graphql");

// seeding
const walletA = Wallet.fromPrivateKey("0x...", provider);
const baseAssetId = provider.getBaseAssetId();
seedTestWallet(wallet, [{ assetId: baseAssetId, amount: bn(100_000) }]);

// generating
const walletB = await generateTestWallet(provider, [[1_000, baseAssetId]]);
```

```ts
// after
import { launchTestNode } from 'fuels/test-utils';

// create two wallets seeded with 100_000 units of the base asset
using launched = await launchTestNode({
  walletsConfig: {
    count: 2,
    amountPerCoin: 100_000,
  },
});

const {
  wallets: [walletA, walletB]
} = launched;

const balance = await walletA.getBalance() // 100_000
```

Removed `launchNodeAndGetWallets` utility.

```ts
// before
import { launchNodeAndGetWallets } from 'fuels/test-utils';

const { provider, wallets } = await launchNodeAndGetWallets();
```

```ts
// after
import { launchTestNode } from 'fuels/test-utils';

using launched = await launchTestNode();

const { provider, wallets } = launched;
```

### Renamed `AssetId` to `TestAssetId`- [#2905](https://github.com/FuelLabs/fuels-ts/pull/2905)

  Renamed testing class `AssetId` to `TestAssetId`.

```ts
// before
import { AssetId } from 'fuels/test-utils';

const [assetA] = AssetId.random();
```

```ts
// after
import { TestAssetId } from 'fuels/test-utils';

const [assetA] = TestAssetId.random();
```

### Adding abi transpiler - [#2856](https://github.com/FuelLabs/fuels-ts/pull/2856)

New ABI spec

The SDK now adheres to the new specs introduced via:

- https://github.com/FuelLabs/fuel-specs/pull/596
- https://github.com/FuelLabs/fuel-specs/pull/599

Check these out to understand all its changes.

The class `AbiCoder` is no longer exported, and the way to do encoding and decoding of specific types is now via the `Interface.encodeType` and `Interface.decodeType` methods:

```ts
// before
const abi = yourAbi;
const functionArg = abi.functions.inputs[0];

const encoded = AbiCoder.encode(abi, functionArg, valueToEncode);
const decoded = AbiCoder.decode(abi, functionArg, valueToDecode, 0);
```

```ts
// after
import { Interface } from 'fuels';

const abi = yourAbi;
const functionArg = abi.functions.inputs[0];

const abiInterface = new Interface(abi);

const encoded = abiInterface.encodeType(functionArg.concreteTypeId, valueToEncode);
const decoded = abiInterface.decodeType(functionArg.concreteTypeId, valueToDecode);
```

Previously, you could get a type from the ABI via the `Interface.findTypeById`. This method has been removed after introducing the new abi specification because the concept of a *type* has been split into concrete types and metadata types. If you want a specific type, you can get it directly from the ABI.

```ts
// before
const abiInterface = new Interface(abi);

// internally this method searched the abi types:
// abi.types.find(t => t.typeId === id);
const type = abiInterface.findTypeById(id);
```

```ts
// after
import { Interface } from 'fuels';

// search the types on the abi directly
const concreteType = abi.concreteTypes.find(ct => ct.concreteTypeId === id);
const metadataType = abiInterface.jsonAbi.metadataTypes.find(mt => mt.metadataTypeId === id);
```

The `JsonAbiArgument` type isn't part of the new ABI spec *([#596](https://github.com/FuelLabs/fuel-specs/pull/596), [#599](https://github.com/FuelLabs/fuel-specs/pull/599))* as such so we stopped exporting it. Its closest equivalent now would be a concrete type because it fully defines a type.

```ts
// before
const arg: JsonAbiArgument = {...};
```

```ts
// after
import { Interface } from 'fuels';

type ConcreteType = JsonAbi["concreteTypes"][number]
const arg: ConcreteType = {...};
```

### Read malleable fields from transaction status on subscription - [#2962](https://github.com/FuelLabs/fuels-ts/pull/2962)

Removed `TransactionResult.gqlTransaction`. You can use the `TransactionResult.transaction` field instead, which has all the data that `TransactionResult.gqlTransaction` has but already decoded.

```ts
// before
const { gqlTransaction } = await new TransactionResponse('your-tx-id').waitForResult();
```

```ts
// after
const { transaction } = await new TransactionResponse('your-tx-id').waitForResult();
```

### Fix assembly process for account transfer operation - [#2963](https://github.com/FuelLabs/fuels-ts/pull/2963)

The `getTransferOperations` helper function now requires an additional `baseAssetId` parameter.

```ts
// before
const transferOperations = getTransferOperations({ inputs, outputs, receipts })
```

```ts
// after
const transferOperations = getTransferOperations({ inputs, outputs, receipts, baseAssetId })
```

### Wrap subscriptions in promise - [#2964](https://github.com/FuelLabs/fuels-ts/pull/2964)

```ts
// before
const subscription = provider.operations.statusChange({ transactionId });
for await (const response of subscription) { ... }
```

```ts
// after
const subscription = await provider.operations.statusChange({ transactionId });
for await (const response of subscription) { ... }
```

## July 30, 2024

[Release v0.93.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.93.0)

### Deploy contract validation - [#2796](https://github.com/FuelLabs/fuels-ts/pull/2796)

`ErrorCode.INVALID_TRANSACTION_TYPE` was migrated to `ErrorCode.UNSUPPORTED_TRANSACTION_TYPE`.

```ts
// before
const code = ErrorCode.INVALID_TRANSACTION_TYPE;
```

```ts
// after
const code = ErrorCode.UNSUPPORTED_TRANSACTION_TYPE;
```

### Remove `awaitExecution` functionality - [#2820](https://github.com/FuelLabs/fuels-ts/pull/2820)

  It is no longer possible to submit transactions using the `awaitExecution` flag and wait for the transaction to be processed at submission:

```ts
// before
const response = await account.sendTransaction(transactionRequest, { awaitExecution: true });
```

```ts
// after
const submit = await account.sendTransaction(transactionRequest);

const response = await submit.waitForResult();
```

### Refactored the `getTransactionCost` method - [#2643](https://github.com/FuelLabs/fuels-ts/pull/2643)

  Refactored functionality for `Provider.getTransactionCost` to `Account.getTransactionCost` **and** changed estimation parameter from `quantitiesToContract` to `quantities`.

```ts
// before
const provider = Provider.create(...);
const account = Wallet.generate({ ... }) || new Predicate(...);
const quantities: Array<CoinQuantityLike> = [
  { amount: 1000, assetId: provider.getBaseAssetId() }
];

const cost = provider.getTransactionCost(txRequest, {
  resourceOwner: account,
  quantitiesToContract: quantities,
})
```

```ts
// after
const provider = Provider.create(...);
const account = Wallet.generate({ ... }) || new Predicate(...);
const quantities: Array<CoinQuantityLike> = [
  { amount: 1000, assetId: provider.getBaseAssetId() }
];

const cost = account.getTransactionCost(txRequest, { quantities });
```

## July 11, 2024

Release [v0.92.0](https://github.com/FuelLabs/fuels-ts/releases/tag/v0.92.0)

### Implement non-blocking contract call - [#2692](https://github.com/FuelLabs/fuels-ts/pull/2692)

  The `call` method in the `BaseInvocationScope` class no longer waits for transaction execution, making it non-blocking. This change affects how transaction responses are handled.

```ts
// before
const { logs, value, transactionResult } = await contract.functions.xyz().call()
```

```ts
// after
const { transactionId, waitForResult } = await contract.functions.xyz().call();

const { logs, value, transactionResult } = await waitForResult();
```

### Made `deployContract` a non-blocking call - [#2597](https://github.com/FuelLabs/fuels-ts/pull/2597)

  The `deployContract` method no longer returns the contract instance directly. Instead, it returns an object containing the `transactionId` , the `contractId`, and a `waitForResult` function.

```ts
// before
const factory = new ContractFactory(contractByteCode, contractAbi, wallet);

const contract = await factory.deployContract();

const { value } = await contract.functions.xyz().call();

// after
const factory = new ContractFactory(contractByteCode, contractAbi, wallet);

const { waitForResult, transactionId, contractId } = await factory.deployContract();

const { contract, transactionResult } = await waitForResult();

const { value } = await contract.functions.xyz().call();
```

### Implement pagination for `Account` methods - [#2408](https://github.com/FuelLabs/fuels-ts/pull/2408)

```ts
// before
const coins = await myWallet.getCoins(baseAssetId);
const messages = await myWallet.getMessages();
const balances = await myWallet.getBalances();
const blocks = await provider.getBlocks();

// after
const { coins, pageInfo } = await myWallet.getCoins(baseAssetId);
const { messages, pageInfo } = await myWallet.getMessages();
const { balances } = await myWallet.getBalances();
const { blocks, pageInfo } = await provider.getBlocks();

/*
  The `pageInfo` object contains cursor pagination information one
  can use to fetch subsequent pages selectively and on demand.
*/
```

### `launchNode.cleanup` not killing node in last test of test group - [#2718](https://github.com/FuelLabs/fuels-ts/pull/2718)

  The `killNode` and `KillNodeParams` functionality has been internalized and the method and interface have been deleted so they're no longer exported.  It's marked as a breaking change for pedantic reasons and there shouldn't really be any affected users given that they kill nodes via `cleanup` which is unchanged, so no migration notes are necessary.

### Remove `InvocationResult` from `program` package - [#2652](https://github.com/FuelLabs/fuels-ts/pull/2652)

  The classes `FunctionInvocationResult`, `InvocationCallResult`, and `InvocationResult` have been removed. This change will not affect most users as the response for a contract call or script call remains the same; only the type name has changed.

```ts
// before
const callResult: FunctionInvocationResult = await contract.functions.xyz().call()

const dryRunResult: InvocationCallResult = await contract.functions.xyz().get()
const dryRunResult: InvocationCallResult = await contract.functions.xyz().dryRun()
const dryRunResult: InvocationCallResult = await contract.functions.xyz().simulate()


// after
const callResult: FunctionResult = await contract.functions.xyz().call()

const dryRunResult: DryRunResult = await contract.functions.xyz().get()
const dryRunResult: DryRunResult = await contract.functions.xyz().dryRun()
const dryRunResult: DryRunResult = await contract.functions.xyz().simulate()
```


---

### File: docs/nightly/node-operator/docs/src/fuel-ignition/index.md

# Running a Fuel Ignition Node

Below is a summary of important information to help you get started with running a node for the Layer 2 Fuel Ignition blockchain.

For the latest version of the Fuel client, please visit [this link](https://github.com/FuelLabs/fuel-core).

## Understanding Fuel Ignition's Consensus Mechanism

Fuel Ignition operates on a Proof of Authority (PoA) consensus mechanism. Here’s a brief overview:

**Validators**: In PoA, there are specific entities, known as validators or "authorities", who are given the responsibility to create new blocks and validate transactions. Unlike other consensus mechanisms like Proof of Work (PoW) or Proof of Stake (PoS), where validators are chosen based on computational power or stake, PoA validators are selected based on their reputation and trustworthiness within the network.

**Benefits of PoA**: PoA provides faster transaction times and requires less computational power, making it more energy-efficient. The security and integrity of the network are maintained by the trustworthiness of the selected validators.

## Hardware Requirements

|  Hardware  | Minimum  | Recommended |
|------------|----------|-------------|
|  Processor |  2 Cores |  8 Cores    |
|  Memory    |  8 GB    |  16 GB      |
|  Storage   |  500 GB  |  1 TB       |

For low API traffic, an AWS m5.large instance should be sufficient. However, we recommend an AWS m5.4xlarge instance to match the configuration we use for running the network.

> For routine tasks such as deploying simple contracts and testing contract interactions locally, you do not need to meet all the hardware requirements listed above.

## Getting Started

Depending on your requirements, you can choose one of the following setups:

1. **[Run a Local Fuel Ignition Node](./local-node.md):** This setup allows you to run a node that operates solely in your local environment.
2. **[Connect to the Fuel Ignition Testnet](./testnet-node.md):** With this setup, your local node will connect and sync with Fuel Ignition.
3. **[Connect to the Fuel Ignition Mainnet](./mainnet-node.md):** With this setup, your local node will connect and sync with the Mainnet version of Fuel Ignition.


---

### File: docs/nightly/node-operator/docs/src/fuel-ignition/local-node.md

# Running a local Fuel node

In addition to deploying and testing on the Fuel Testnet, you can also run a local Fuel Node.

There are two types of Fuel networks that can be run:

1. In-memory network (without persistence)
2. Local network with persistence

## Using `forc node` to run a Local Node

> If you wish to still use the `fuel-core` binary directly, you can skip this section and continue with the steps below.

Make sure you have the [latest version of `fuelup` installed or updated](https://docs.fuel.network/guides/contract-quickstart/#installation). `forc node` abstracts all the flags and configuration options of the `fuel-core` binary and is intended for ease of use. To run a local node using `forc`, you can use the following command:

```sh
forc node local
```

This command will start a local node with the default configuration (with state persistence). The default configuration is highlighted in green at the top of the command output.

If you want to specify a custom configuration, you can use the `--help` flag to see the available options. For example:

```sh
forc node local --help
```

### Dry-run mode

Users of this new plugin may want to review the parameters before running the node. To accommodate this, `forc-node` includes a dry-run mode, which can be enabled using:

```sh
forc-node --dry-run local
```

Instead of starting the node, this command will print the exact command that would be run, allowing you to verify the parameters beforehand.

## Using `fuel-core` binary to run a local node

If you wish to still use the `fuel-core` binary directly, you can follow the steps below.

## In-memory local node (without state persistence)

An in-memory node does not persist the blockchain state anywhere, it is only stored in memory as long as the node is active and running.

First ensure your environments [open files limit](https://askubuntu.com/questions/162229/how-do-i-increase-the-open-files-limit-for-a-non-root-user) `ulimit` is increased, example:

```sh
ulimit -S -n 32768
```

After ensuring your file limit is increased, to spin-up a local in-memory Fuel node download or copy the local snapshot from [here](https://github.com/FuelLabs/chain-configuration/tree/master/local), then run the following command:

```sh
fuel-core run --db-type in-memory --debug --snapshot ./your/path/to/chain_config_folder
```

To deploy a contract to the local node, run the following command:

```sh
forc deploy <signing-key> --node-url 127.0.0.1:4000/v1/graphql
```

Or to deploy with the default signer that is pre-funded by fuel-core:

```sh
forc deploy --default-signer --node-url 127.0.0.1:4000/v1/graphql
```

## Chain Configuration

To modify the initial state of the chain, you must configure the `state_config.json` file in your chain configuration folder.

For simplicity, clone the [repository](https://github.com/FuelLabs/chain-configuration/tree/master) into the directory of your choice.

When using the `--snapshot` flag later, you can replace `./your/path/to/chain_config_folder` with the `local` folder of the repository you just cloned `./chain-configuration/local/`.

To start the node with a custom configuration, you can use the command below:

```sh
fuel-core run --snapshot ./your/path/to/chain_config_folder --db-type in-memory --debug
```

To find an example `local` chain configuration folder for a specific `fuel-core` version, refer to the [`chain-configuration/local`](https://github.com/FuelLabs/chain-configuration/tree/master/local) repo.

### Funding a wallet locally

You can edit the `coins` array inside `state_config.json` to modify the initial assets owned by a given address.

The `owner` address must be a `B256` type address (begins with `0x`) instead of a `Bech32` type (begins with `fuel`).

The `amount` is a numerical value. In the example below, the value translates to 1 ETH.

```json
"coins": [
  {
    "tx_id": "0x0000000000000000000000000000000000000000000000000000000000000001",
    "output_index": 0,
    "tx_pointer_block_height": 0,
    "tx_pointer_tx_idx": 0,
    "owner": "0x488284d46414347c78221d3bad71dfebcff61ab2ae26d71129701d50796f714d",
    "amount": 1000000000,
    "asset_id": "0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07"
  }
]
```

## Local node (with state persistence)

This node does persist the blockchain state locally.
To run a local node with persistence a chain configuration file is required.

To start the node, run the following command:

```sh
fuel-core run --ip 127.0.0.1 --port 4000 --snapshot ./your/path/to/chain_config_folder --db-path ./.fueldb --debug
```

## Connecting to the local node from a browser wallet

To connect to the local node using a browser wallet, import the network address as:

```sh
http://127.0.0.1:4000/v1/graphql
```


---

### File: docs/nightly/node-operator/docs/src/fuel-ignition/mainnet-node.md

# Running a local Fuel node connected to Mainnet using P2P

> Fuel is preparing for the next major client release, upgrading the network from version 0.40.x to 0.41.x. This will be a required upgrade for all node operators.
> The **mainnet upgrade is scheduled for March 6**. You can upgrade immediately to the [0.41.6](https://github.com/FuelLabs/fuel-core/releases/tag/v0.41.6) release and sync with the current network using the latest release.
> This release brings database optimizations for some API queries. To take full advantage of these improvements, we recommend re-syncing the chain from the genesis block. While not mandatory, doing so will ensure the best performance.

## Installation

To install the Fuel toolchain, you can use the `fuelup-init` script.
This will install `forc`, `forc-client`, `forc-fmt`, `forc-lsp`, `forc-wallet` as well as `fuel-core` in `~/.fuelup/bin`.

```sh
curl https://install.fuel.network | sh
```

> Having problems? Visit the [installation guide](https://docs.fuel.network/guides/installation/) or post your question in our [forum](https://forum.fuel.network/).

## Getting a mainnet Ethereum API Key

An API key from any RPC provider that supports the Sepolia network will work. Relayers will help listen to events from the Ethereum network. We recommend either [Infura](https://www.infura.io/) or [Alchemy](https://www.alchemy.com/)

The endpoints should look like the following:

### Infura

```sh
https://mainnet.infura.io/v3/{YOUR_API_KEY}
```

### Alchemy

```sh
https://eth-mainnet.g.alchemy.com/v2/{YOUR_API_KEY}
```

Note that using other network endpoints will result in the relayer failing to start.

## Using `forc node` to run a Mainnet Node

> If you wish to still use the `fuel-core` binary directly, you can skip this section and continue with the steps below.

Make sure you have the [latest version of `fuelup` installed or updated](https://docs.fuel.network/guides/contract-quickstart/#installation). `forc node` abstracts all the flags and configuration options of the `fuel-core` binary and is intended for ease of use. To run a mainnet node using `forc`, you can use the following command:

```sh
forc node ignition
```

This command will prompt for two things:

1. You will be asked to create a keypair if you don't already have one.
2. You will be asked to provide an Ethereum RPC endpoint that you retrieved from the [Getting a mainnet Ethereum API Key](#getting-a-mainnet-ethereum-api-key) section above.

The default configuration is highlighted in green at the top of the command output.

If you want to specify a custom configuration, you can use the `--help` flag to see the available options. For example:

```sh
forc node ignition --help
```

### Dry-run mode

Users of this new plugin may want to review the parameters before running the node. To accommodate this, `forc-node` includes a dry-run mode, which can be enabled using:

```sh
forc-node --dry-run ignition
```

Instead of starting the node, this command will print the exact command that would be run, allowing you to verify the parameters beforehand.

## Using `fuel-core` binary to run a local node

If you wish to still use the `fuel-core` binary directly, you can follow the steps below.

## Generating a P2P Key

Generate a new P2P key pairing by running the following command:

```sh
fuel-core-keygen new --key-type peering
{
  "peer_id":"16Uiu2HAmEtVt2nZjzpXcAH7dkPcFDiL3z7haj6x78Tj659Ri8nrs",
  "secret":"b0ab3227974e06d236d265bd1077bb0522d38ead16c4326a5dff2f30edf88496",
  "type":"peering"
}
### Do not share or lose this private key! Press any key to complete. ###
```

Make sure you save this somewhere safe so you don't need to generate a new key pair in the future.

## Chain Configuration

To run a local node with persistence, you must have a folder with the following chain configuration files:

For simplicity, clone the [repository](https://github.com/FuelLabs/chain-configuration/tree/master) into the directory of your choice.

When using the `--snapshot` flag later, you can replace `./your/path/to/chain_config_folder` with the `ignition` folder of the repository you just cloned `./chain-configuration/ignition/`.

## Running a Local Node

First ensure your environments [open files limit](https://askubuntu.com/questions/162229/how-do-i-increase-the-open-files-limit-for-a-non-root-user) `ulimit` is increased, example:

```sh
ulimit -S -n 32768
```

> Please make sure you have the [latest version](https://docs.fuel.network/guides/installation/#updating-fuelup) of the Fuel toolchain installed and properly configured before continuing.

Finally to put everything together to start the node, run the following command:

```sh
fuel-core run \
--enable-relayer \
--service-name fuel-mainnet-node \
--keypair {P2P_PRIVATE_KEY} \
--relayer {ETHEREUM_RPC_ENDPOINT} \
--ip=0.0.0.0 --port 4000 --peering-port 30333 \
--db-path ~/.fuel-mainnet \
--snapshot ./your/path/to/chain_config_folder \
--utxo-validation --poa-instant false --enable-p2p \
--bootstrap-nodes /dnsaddr/mainnet.fuel.network \
--sync-header-batch-size 50 \
--relayer-v2-listening-contracts=0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf \
--relayer-da-deploy-height=20620434 \
--relayer-log-page-size=100 \
--sync-block-stream-buffer-size 30
```

For the full description details of each flag above, run:

```sh
fuel-core run --help
```

## Connecting to the local node from a browser wallet

To connect to the local node using a browser wallet, import the network address as:

```sh
http://0.0.0.0:4000/v1/graphql
```


---

### File: docs/nightly/node-operator/docs/src/fuel-ignition/testnet-node.md

# Running a local Fuel node connected to Testnet using P2P

> Fuel is getting ready for our next major client release, which will upgrade the network from version 0.40.x to 0.41.x. This will be a required upgrade for any node operators.
> We are targeting **February 20 for the testnet upgrade**. You can upgrade immediately to the [0.41.6](https://github.com/FuelLabs/fuel-core/releases/tag/v0.41.6) release and sync with the current network using the latest release.
> This update includes several improvements, such as database optimizations for some API queries. To fully benefit from these changes, you will need to re-sync the chain from the genesis block. While this isn't required for operation, it is recommended for optimal performance.

## Installation

To install the Fuel toolchain, you can use the `fuelup-init` script.
This will install `forc`, `forc-client`, `forc-fmt`, `forc-lsp`, `forc-wallet` as well as `fuel-core` in `~/.fuelup/bin`.

```sh
curl https://install.fuel.network | sh
```

> Having problems? Visit the [installation guide](https://docs.fuel.network/guides/installation/) or post your question in our [forum](https://forum.fuel.network/).

## Getting a Sepolia (Ethereum Testnet) API Key

An API key from any RPC provider that supports the Sepolia network will work. Relayers will help listen to events from the Ethereum network. We recommend either [Infura](https://www.infura.io/) or [Alchemy](https://www.alchemy.com/)

The endpoints should look like the following:

### Infura

```sh
https://sepolia.infura.io/v3/{YOUR_API_KEY}
```

### Alchemy

```sh
https://eth-sepolia.g.alchemy.com/v2/{YOUR_API_KEY}
```

Note that using other network endpoints will result in the relayer failing to start.

## Using `forc node` to run a Testnet Node

> If you wish to still use the `fuel-core` binary directly, you can skip this section and continue with the steps below.

Make sure you have the [latest version of `fuelup` installed or updated](https://docs.fuel.network/guides/contract-quickstart/#installation). `forc node` abstracts all the flags and configuration options of the `fuel-core` binary and is intended for ease of use. To run a testnet node using `forc`, you can use the following command:

```sh
forc node testnet
```

This command will prompt for two things:

1. You will be asked to create a keypair if you don't already have one.
2. You will be asked to provide an Ethereum RPC endpoint that you retrieved from the [Getting a Sepolia (Ethereum Testnet) API Key](#getting-a-sepolia-ethereum-testnet-api-key) section above.

The default configuration is highlighted in green at the top of the command output.

If you want to specify a custom configuration, you can use the `--help` flag to see the available options. For example:

```sh
forc node testnet --help
```

### Dry-run mode

Users of this new plugin may want to review the parameters before running the node. To accommodate this, `forc-node` includes a dry-run mode, which can be enabled using:

```sh
forc-node --dry-run testnet
```

Instead of starting the node, this command will print the exact command that would be run, allowing you to verify the parameters beforehand.

## Using `fuel-core` binary to run a local node

If you wish to still use the `fuel-core` binary directly, you can follow the steps below.

## Generating a P2P Key

Generate a new P2P key pairing by running the following command:

```sh
fuel-core-keygen new --key-type peering
{
  "peer_id":"16Uiu2HAmEtVt2nZjzpXcAH7dkPcFDiL3z7haj6x78Tj659Ri8nrs",
  "secret":"b0ab3227974e06d236d265bd1077bb0522d38ead16c4326a5dff2f30edf88496",
  "type":"peering"
}
### Do not share or lose this private key! Press any key to complete. ###
```

Make sure you save this somewhere safe so you don't need to generate a new key pair in the future.

## Chain Configuration

To run a local node with persistence, you must have a folder with the following chain configuration files:

For simplicity, clone the [repository](https://github.com/FuelLabs/chain-configuration/tree/master) into the directory of your choice.

When using the `--snapshot` flag later, you can replace `./your/path/to/chain_config_folder` with the `ignition-test` folder of the repository you just cloned `./chain-configuration/ignition-test/`.

## Running a Local Node

First ensure your environments [open files limit](https://askubuntu.com/questions/162229/how-do-i-increase-the-open-files-limit-for-a-non-root-user) `ulimit` is increased, example:

```sh
ulimit -S -n 32768
```

Finally to put everything together to start the node, run the following command:

```sh
fuel-core run \
--service-name=fuel-sepolia-testnet-node \
--keypair {P2P_PRIVATE_KEY} \
--relayer {ETHEREUM_RPC_ENDPOINT} \
--ip=0.0.0.0 --port=4000 --peering-port=30333 \
--db-path=~/.fuel-sepolia-testnet \
--snapshot ./your/path/to/chain_config_folder \
--utxo-validation --poa-instant false --enable-p2p \
--bootstrap-nodes /dnsaddr/testnet.fuel.network \
--sync-header-batch-size 50 \
--enable-relayer \
--relayer-v2-listening-contracts=0x01855B78C1f8868DE70e84507ec735983bf262dA \
--relayer-da-deploy-height=5827607 \
--relayer-log-page-size=500 \
--sync-block-stream-buffer-size 30
```

For the full description details of each flag above, run:

```sh
fuel-core run --help
```

## Connecting to the local node from a browser wallet

To connect to the local node using a browser wallet, import the network address as:

```sh
http://0.0.0.0:4000/v1/graphql
```


---

### File: docs/nightly/node-operator/docs/src/fuel-sequencer/index.md

# Running a Fuel Sequencer Node or Validator

Below is a summary of key information to help you get started with running a node for the Fuel Sequencer blockchain.

For more details, please refer to the deployment [repository](https://github.com/FuelLabs/fuel-sequencer-deployments/).

## Hardware Requirements

| Hardware   | Minimum  | Recommended |
|------------|---------|-------------|
| Processor  | 4 Cores | 8 Cores     |
| Memory     | 8 GB    | 16 GB       |
| Storage    | 200 GB  | 1 TB        |

## Port Configuration

Unless otherwise configured, the following ports should be available:

- **Sequencer**: 26656, 26657, 9090, 1317  
- **Sidecar**: 8080  
- **Ethereum**: 8545, 8546  

These components interact with each other, so any changes to the port configuration must be reflected in the corresponding components. Specifically:

- Changes to **Sequencer ports** must be updated in the **Sidecar's runtime flags**.
- Changes to the **Sidecar port** must be updated in the **Sequencer's app config**.
- Changes to **Ethereum ports** must be updated in the **Sidecar's runtime flags**.

## Getting Started

Depending on your needs, you can choose one of the following setups:

1. **[Running a Mainnet Fuel Sequencer Node](./mainnet-node.md):** Your local node will connect to and sync with the mainnet Fuel Sequencer network.
2. **[Running a Mainnet Fuel Sequencer Validator](./mainnet-validator.md):** Your local node will connect to, sync with, and validate transactions on the mainnet Fuel Sequencer network.
3. **[Running a Testnet Fuel Sequencer Node](./testnet-node.md):** Your local node will connect to and sync with the testnet Fuel Sequencer network.
4. **[Running a Testnet Fuel Sequencer Validator](./testnet-validator.md):** Your local node will connect to, sync with, and validate transactions on the testnet Fuel Sequencer network.


---

### File: docs/nightly/node-operator/docs/src/fuel-sequencer/mainnet-node.md

# Run Sequencer Node

## Prerequisites

This guide assumes that Golang is installed to run Cosmovisor. We recommend using version **1.21 or later**. You can download it [here](https://go.dev/dl/).

## Run the Node

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-mainnet-1.3.2
  - For example:
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-mainnet-1/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-mainnet-1.3.2/fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-mainnet-1.3.2
```

Initialise the node directory, giving your node a meaningful name:

```sh
fuelsequencerd init <node-name> --chain-id seq-mainnet-1
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10fuel"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = false`.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "fc5fd264190e4a78612ec589994646268b81f14e@80.64.208.207:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1258291` (1.2MiB)
  - Set `max_txs_bytes = 23068672` (22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-mainnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

### Running the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

#### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

#### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## Ethereum Bridge Event Handling

The Sidecar subscribes to a limited set of specific events emitted by the Ethereum bridge contracts. Each event type corresponds directly to a whitelisted message type, eliminating the need for generic authorization wrappers. The Sidecar implements dedicated handlers for each event type, ensuring efficient and secure processing of Ethereum-originated operations.

Proto-encoding of authorization transactions is performed by the Sequencer app, not the Ethereum contracts, significantly reducing gas costs and computational overhead. This architecture maintains all original security guarantees while optimizing for cost and efficiency.

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-mainnet#set-up-cosmovisor


---

### File: docs/nightly/node-operator/docs/src/fuel-sequencer/mainnet-validator.md

# Run Sequencer Validator

## Typical Setup

The validator setup will consist of a Fuel Sequencer, Sidecar, and a connection to an Ethereum Mainnet Node.

![fuel sequencer validator](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/fuel-sequencer-validator.png)

## Prerequisites

The guide assumes that Golang is installed in order to run Cosmovisor. We recommend installing version `1.21+`.

## Run an Ethereum Mainnet Full Node

To ensure the highest performance and reliability of the Sequencer infrastructure, **running your own Ethereum Mainnet full node is a requirement**. Avoiding the use of third-party services for Ethereum node operations significantly helps the Sequencer network's liveness. Please note these recommended node configurations:

```bash
--syncmode=snap
--gcmode=full
```

## Configure the Sequencer

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-mainnet-1.3.2
  - For example:
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-mainnet-1/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-mainnet-1.3.2/fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-mainnet-1.3.2
```

Initialise the node directory, giving your node a meaningful name:

```sh
fuelsequencerd init <node-name> --chain-id seq-mainnet-1
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10fuel"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = true`.
  - Ensure that `address` is where the Sidecar will run.
- Configure `[api]`:
  - Set `swagger=true` (optional).
  - Set `rpc-max-body-bytes = 1153434` (optional - relevant for public REST).
- Configure `[commitments]`:
  - Set `api-enabled = true` (optional - relevant for public REST).
- Configure `[state-sync]`:
  - Set `snapshot-interval = 1000` (optional - to provide state-sync service).
- Configure:
  - Set `rpc-read-timeout = 10` (optional - relevant for public REST).
  - Set `rpc-write-timeout = 0` (optional - relevant for public REST).

> **WARNING**: leaving the `[commitments]` API accessible to anyone can lead to DoS! It is highly recommended to handle whitelisting or authentication by a reverse proxy like [Traefik](https://traefik.io/traefik/) for gRPC if the commitments API is enabled.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "fc5fd264190e4a78612ec589994646268b81f14e@80.64.208.207:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1258291` (1.2MiB)
  - Set `max_txs_bytes = 23068672` (22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-mainnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

## Run the Sidecar

At this point you should already be able to run `fuelsequencerd start-sidecar` with the right flags, to run the Sidecar. However, **it is highly recommended to run the Sidecar as a background service**.

It is also very important to ensure that you provide all the necessary flags when running the Sidecar to ensure that it can connect to an Ethereum node and to the Sequencer node, and is also accessible by the Sequencer node. The most important flags are:

- `host`: host for the gRPC server to listen on
- `port`: port for the gRPC server to listen on
- `eth_ws_url`: Ethereum node WebSocket endpoint
- `eth_rpc_url`: Ethereum node RPC endpoint
- `eth_contract_address`: address in hex format of the contract to monitor for logs. This MUST be set to `0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3`.
- `sequencer_grpc_url`: Sequencer node gRPC endpoint

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sidecar
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=<HOME>/go/bin/fuelsequencerd start-sidecar \
    --host "0.0.0.0" \
    --sequencer_grpc_url "127.0.0.1:9090" \
    --eth_ws_url "<ETHEREUM_NODE_WS>" \
    --eth_rpc_url "<ETHEREUM_NODE_RPC>" \
    --eth_contract_address "0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3"
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sidecar</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/fuelsequencerd</string>
        <string>start-sidecar</string>
        <string>--host</string>
        <string>0.0.0.0</string>
        <string>--sequencer_grpc_url</string>
        <string>127.0.0.1:9090</string>
        <string>--eth_ws_url</string>
        <string>[ETHEREUM_NODE_WS]</string>
        <string>--eth_rpc_url</string>
        <string>[ETHEREUM_NODE_RPC]</string>
        <string>--eth_contract_address</string>
        <string>0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.err</string>
</dict>
</plist>
```

</details>

## Run the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## Creating an Account

To run a validator, you will need to have a Sequencer account address. Generate an address with a key name:

```sh
fuelsequencerd keys add <NAME> # for a brand new key

# or

fuelsequencerd keys add <NAME> --recover # to create from a mnemonic
```

This will give you an output with an address (e.g. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) and a private mnemonic, if you generated a brand new key. Store the mnemonic safely.

Fuel Sequencer addresses also have an Ethereum-compatible (i.e. hex) format. To generate the hex address corresponding to your Sequencer address, run the following:

```sh
fuelsequencerd keys parse <ADDRESS>
```

This will give an output in this form:

```text
bytes: FF8162F37072354EB1E222084DA0D4221E93550F
human: fuelsequencer
```

Adding the `0x` prefix to the address in the first line gives you your Ethereum-compatible address, used to deposit into and interact with your Sequencer address from Ethereum. In this case, it's `0xFF8162F37072354EB1E222084DA0D4221E93550F`.

## Funding the Account

Ensure your mainnet Ethereum account (EOA) has sufficient ETH to cover gas fees and FUEL tokens to transfer to your Sequencer account.

### Important Addresses  

- [**FUEL Token:** `0x675B68AA4d9c2d3BB3F0397048e62E6B7192079c`](https://etherscan.io/address/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c)  
- [**Sequencer Interface (Bridge):** `0xca0c6B264f0F9958Ec186eb2EAa208966187D866`](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866)  

### Token Approval  

Before proceeding, you must **approve** the Fuel token contract to allow the transfer of tokens.  

In the [Fuel Token Etherscan contract UI](https://etherscan.io/token/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c#writeProxyContract), use the **`approve (0x095ea7b3)`** function:  

- **Spender (`address`)**: Set this to the **Sequencer Interface (Bridge)** address: [`0xca0c6B264f0F9958Ec186eb2EAa208966187D866`](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866).  
- **Value (`uint256`)**: Enter the number of tokens to approve, **including 9 additional decimal places**. For unlimited approval, use:  

  ```sh
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  ```

![Mainnet Etherscan Approval UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-etherscan-approval-ui.png)

### Bridging Tokens  

To bridge tokens, connect your Ethereum wallet by clicking **"Connect to Web3"** in the top left. Then, use the **`depositFor (0x36efd6f)`** function to fund your sequencer account.  

Transfer your FUEL tokens using the [Sequencer Interface (Bridge)Etherscan UI](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866).  

![Mainnet Etherscan UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-etherscan-ui.png)  

- **Amount (`uint256`)**: Enter the number of tokens to send, **including 9 additional decimal places**.  
- **Recipient address**: Enter the Ethereum-compatible address you generated earlier (e.g., `0xFF8162F37072354EB1E222084DA0D4221E93550F`).  

Click **"Write"** to confirm the transaction. The transfer may take **~20 minutes** to process.  

### Verifying Funds

To verify your funds, enter your sequencer account address (i.e. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) in the [mainnet block explorer](https://fuel-seq.simplystaking.xyz/fuel-mainnet/statesync).  

![Mainnet Block Explorer](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-blockexplorer.png)  

> **⚠ WARNING:** Always test with a small transfer before bridging FUEL tokens.

## Withdrawals

Withdrawals can be easily initiated through the CLI and will be settled on Ethereum approximately 3 days later, as the commitment and bridge finalizations must be completed first.

Identify the account from which you wish to withdraw. Use the following command to list all previously created account names matching your account address above:

```sh
fuelsequencerd keys list
```

Example output:

```sh
address: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
  name: my-mainnet-validator
  pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Al6W+Ttrscm/8njeMOt79T0BOdphfWGXrDLij+O3g19N"}'
  type: local
```

Verify that this is the correct address and account name from which you wish to withdraw.

To initiate the withdrawal, use the following command where `<eth-destination-address>` is any Ethereum address you wish to withdraw to and `<amount-in-fuel>` is the amount of FUEL you wish to withdraw:

Note: The amount in FUEL must include 9 decimal places.

```sh
fuelsequencerd tx bridge withdraw-to-ethereum <eth-destination-address> <amount-in-fuel> \
  --from=<key> \
  --gas-prices=10fuel \
  --gas=auto \
  --gas-adjustment 1.5 \
  --node="https://fuel-rpc.polkachu.com/" \
  --chain-id="seq-mainnet-1"
```

For example:

```sh
fuelsequencerd tx bridge withdraw-to-ethereum 0xd70080dE4535db4A64798a23619Db64fB28fD079 1fuel \
    --from=my-mainnet-validator \
    --gas-prices=10fuel \
    --gas=auto \
    --gas-adjustment 1.5 \
    --node="https://fuel-rpc.polkachu.com/" \
    --chain-id="seq-mainnet-1"
```

Review the transaction details and confirm the transaction by typing `yes` when prompted:

```sh
gas estimate: 106942
auth_info:
  fee:
    amount:
    - amount: "1069420"
      denom: fuel
    gas_limit: "106942"
    granter: ""
    payer: ""
  signer_infos: []
  tip: null
body:
  extension_options: []
  memo: ""
  messages:
  - '@type': /fuelsequencer.bridge.v1.MsgWithdrawToEthereum
    amount:
      amount: "1"
      denom: fuel
    from: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
    to: 0xd70080dE4535db4A64798a23619Db64fB28fD079
  non_critical_extension_options: []
  timeout_height: "0"
signatures: []
confirm transaction before signing and broadcasting [y/N]:
```

If the transaction is successful, you will receive a transaction hash, which you can paste and monitor the status of your withdrawal [here](https://fuel-seq.simplystaking.xyz/fuel-mainnet/):

```sh
code: 0
codespace: ""
data: ""
events: []
gas_used: "0"
gas_wanted: "0"
height: "0"
info: ""
logs: []
raw_log: ""
timestamp: ""
tx: null
txhash: AD541CE1DCDBD8638C5DFD3C7AF3A3AAF8B9CD0AF265C3AFD96633CE8FAF4CF4
```

![Block Explorer Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-blockexplorer-withdrawal.png)

After verifying your withdrawal on the shared sequencer explorer, visit [Simply Staking](https://stake.simplystaking.com/fuel) and connect your wallet. Navigate to the **Withdrawal** tab on the right to monitor the progress of your withdrawal.

![Simply Staking Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-simplystaking-withdrawal.png)

Once the 3-day waiting period has passed, the withdrawal will require manual action to pull the funds out.

<!-- TODO: ![Final Withdrawal Screenshot](pic) -->

## Create the Validator

To create the validator, a prerequisite is to have at least 1FUEL, with enough extra to pay for gas fees. You can check your balance from the explorer.

[//]: # (TODO: steps on how to deposit FUEL tokens to a Sequencer address)

Once you have FUEL tokens, run the following to create a validator, using the name of the account that you created in the previous steps:

```sh
fuelsequencerd tx staking create-validator path/to/validator.json \
    --from <NAME> \
    --gas auto \
    --gas-prices 10fuel \
    --gas-adjustment 1.5 \
    --chain-id seq-mainnet-1
```

...where validator.json contains:

```json
{
 "pubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"<PUBKEY>"},
 "amount": "1000000000fuel",
 "moniker": "<MONIKER>",
 "identity": "<OPTIONAL-IDENTITY>",
 "website": "<OPTIONAL-WEBSITE>",
 "security": "<OPTIONAL-EMAIL>",
 "details": "<OPTIONAL-DETAILS>",
 "commission-rate": "0.05",
 "commission-max-rate": "<MAX-RATE>",
 "commission-max-change-rate": "<MAX-CHANGE-RATE>",
 "min-self-delegation": "1"
}
```

...where the pubkey can be obtained using `fuelsequencerd tendermint show-validator`.

### What to Expect

- The Sequencer should show block syncing.
- The Sidecar should show block extraction. Occasionally it also receives requests for events.

### Tendermint KMS

If you will be using `tmkms`, make sure that in the config:

- Chain ID is set to `seq-mainnet-1` wherever applicable
- `account_key_prefix = "fuelsequencerpub"`
- `consensus_key_prefix = "fuelsequencervalconspub"`
- `sign_extensions = true`
- `protocol_version = "v0.34"`

### Additional Advanced Configuration

Sidecar flags:

- `development`: starts the sidecar in development mode.
- `eth_max_block_range`: max number of Ethereum blocks queried at one go.
- `eth_min_logs_query_interval`: minimum wait between successive queries for logs.
- `unsafe_eth_start_block`: the Ethereum block to start querying from.
- `unsafe_eth_end_block`: the last Ethereum block to query. Incorrect use can cause the validator to propose empty blocks, leading to slashing!
- `sequencer_path_to_cert_file`: path to the certificate file of the Sequencer infrastructure for secure communication. Specify this value if the Sequencer infrastructure was set up using TLS.
- `sidecar_path_to_cert_file`: path to the certificate file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `sidecar_path_to_key_file`: path to the private key file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `prometheus_enabled`: enables serving of prometheus metrics.
- `prometheus_listen_address`: address to listen for prometheus collectors (default ":8081").
- `prometheus_max_open_connections`: max number of simultaneous connections (default 3).
- `prometheus_namespace`: instrumentation namespace (default "sidecar").
- `prometheus_read_header_timeout`: amount of time allowed to read request headers (default 10s).
- `prometheus_write_timeout`: maximum duration before timing out writes of the response (default 10s).

Sidecar client flags:

- `sidecar_grpc_url`: the sidecar's gRPC endpoint.
- `query_timeout`: how long to wait before the request times out.

## Bridge Event Validation and Sequencer Consensus

Validators process specific event types emitted by the Ethereum bridge contracts, each mapped to a whitelisted message type. The Sidecar provides these events to the Sequencer app using dedicated handlers for each message type, streamlining validation and processing.

Proto-encoding of authorization transactions is handled by the Sequencer app, resulting in lower gas costs and improved efficiency. The system preserves all security guarantees, with validators participating in consensus on the ordering and inclusion of these events.

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-mainnet#set-up-cosmovisor


---

### File: docs/nightly/node-operator/docs/src/fuel-sequencer/testnet-node.md

# Run Sequencer Node

## Prerequisites

This guide assumes that Golang is installed to run Cosmovisor. We recommend using version **1.21 or later**. You can download it [here](https://go.dev/dl/).

## Run the Node

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-testnet-2.2
  - For example:
    - `fuelsequencerd-seq-testnet-2.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-testnet-2.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-testnet-2/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-testnet-2.2/fuelsequencerd-seq-testnet-2.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-testnet-2.2
```

Initialise node directory:

```sh
fuelsequencerd init <node-name> --chain-id seq-testnet-2
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10test"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = false`.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "3a0b4118c01addd33d5add81783805d5add2fb17@80.64.208.17:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1153434` (1.1MiB)
  - Set `max_txs_bytes = 23068670` (~22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-testnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

### Running the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

#### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

#### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-mainnet#set-up-cosmovisor


---

### File: docs/nightly/node-operator/docs/src/fuel-sequencer/testnet-validator.md

# Run Sequencer Validator

## Typical Setup

The validator setup will consist of a Fuel Sequencer, Sidecar, and a connection to an Ethereum Sepolia Node.

![fuel sequencer validator](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/fuel-sequencer-validator.png)

## Prerequisites

This guide assumes that Golang is installed to run Cosmovisor. We recommend using version **1.21 or later**. You can download it [here](https://go.dev/dl/).

## Run an Ethereum Sepolia Full Node

To ensure the highest performance and reliability of the Sequencer infrastructure, **running your own Ethereum Sepolia full node is a requirement**. Avoiding the use of third-party services for Ethereum node operations significantly helps the Sequencer network's liveness. Please note these recommended node configurations:

```bash
--syncmode=snap
--gcmode=full
```

## Configure the Sequencer

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-testnet-2.2
  - For example:
    - `fuelsequencerd-seq-testnet-2.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-testnet-2.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-testnet-2/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-testnet-2.2/fuelsequencerd-seq-testnet-2.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-testnet-2.2
```

Initialise the node directory, giving your node a meaningful name:

```sh
fuelsequencerd init <node-name> --chain-id seq-testnet-2
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10test"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = true`.
  - Ensure that `address` is where the Sidecar will run.
- Configure `[api]`:
  - Set `swagger=true` (optional).
  - Set `rpc-max-body-bytes = 1153434` (optional - relevant for public REST).
- Configure `[commitments]`:
  - Set `api-enabled = true` (optional - relevant for public REST).
- Configure `[state-sync]`:
  - Set `snapshot-interval = 1000` (optional - to provide state-sync service).
- Configure:
  - Set `rpc-read-timeout = 10` (optional - relevant for public REST).
  - Set `rpc-write-timeout = 0` (optional - relevant for public REST).

> **WARNING**: leaving the `[commitments]` API accessible to anyone can lead to DoS! It is highly recommended to handle whitelisting or authentication by a reverse proxy like [Traefik](https://traefik.io/traefik/) for gRPC if the commitments API is enabled.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "fc5fd264190e4a78612ec589994646268b81f14e@80.64.208.207:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1258291` (1.2MiB)
  - Set `max_txs_bytes = 23068672` (22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-testnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

## Run the Sidecar

At this point you should already be able to run `fuelsequencerd start-sidecar` with the right flags, to run the Sidecar. However, **it is highly recommended to run the Sidecar as a background service**.

It is also very important to ensure that you provide all the necessary flags when running the Sidecar to ensure that it can connect to an Ethereum node and to the Sequencer node, and is also accessible by the Sequencer node. The most important flags are:

- `host`: host for the gRPC server to listen on
- `port`: port for the gRPC server to listen on
- `eth_ws_url`: Ethereum node WebSocket endpoint
- `eth_rpc_url`: Ethereum node RPC endpoint
- `eth_contract_address`: address in hex format of the contract to monitor for logs.  This MUST be set to `0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD`.
- `sequencer_grpc_url`: Sequencer node gRPC endpoint

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sidecar
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=<HOME>/go/bin/fuelsequencerd start-sidecar \
    --host "0.0.0.0" \
    --sequencer_grpc_url "127.0.0.1:9090" \
    --eth_ws_url "<ETHEREUM_NODE_WS>" \
    --eth_rpc_url "<ETHEREUM_NODE_RPC>" \
    --eth_contract_address "0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD"
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sidecar</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/fuelsequencerd</string>
        <string>start-sidecar</string>
        <string>--host</string>
        <string>0.0.0.0</string>
        <string>--sequencer_grpc_url</string>
        <string>127.0.0.1:9090</string>
        <string>--eth_ws_url</string>
        <string>[ETHEREUM_NODE_WS]</string>
        <string>--eth_rpc_url</string>
        <string>[ETHEREUM_NODE_RPC]</string>
        <string>--eth_contract_address</string>
        <string>0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.err</string>
</dict>
</plist>
```

</details>

## Run the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## Creating an Account

To run a validator, you will need to have a Sequencer account address. Generate an address with a key name:

```sh
fuelsequencerd keys add <NAME> # for a brand new key

# or

fuelsequencerd keys add <NAME> --recover # to create from a mnemonic
```

This will give you an output with an address (e.g. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) and a private mnemonic, if you generated a brand new key. Store the mnemonic safely.

Fuel Sequencer addresses also have an Ethereum-compatible (i.e. hex) format. To generate the hex address corresponding to your Sequencer address, run the following:

```sh
fuelsequencerd keys parse <ADDRESS>
```

This will give an output in this form:

```text
bytes: FF8162F37072354EB1E222084DA0D4221E93550F
human: fuelsequencer
```

Adding the `0x` prefix to the address in the first line gives you your Ethereum-compatible address, used to deposit into and interact with your Sequencer address from Ethereum. In this case, it's `0xFF8162F37072354EB1E222084DA0D4221E93550F`.

## Funding the Account

Ensure your Ethereum account (EOA) has sufficient ETH to cover gas fees.

### Important Addresses  

- [**FUEL Token:** `0xd7Fc4e8FB2c05567C313f4C9b9e07641a361a550`](https://sepolia.etherscan.io/token/0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550)  
- [**Sequencer Interface (Bridge):** `0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4`](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4)  

### Token Faucet  

To obtain testnet tokens, visit [Fuel's official Ethereum testnet staking UI](https://app-testnet.fuel.network/staking/on-ethereum) with any Ethereum EOA that has not previously received FUEL tokens from the faucet.  

Click **"Faucet Fuel Token"** to receive `100 FUEL` tokens for testing.  

![Testnet Fuel Faucet](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-fuel-faucet.png)  

### Token Approval  

Before proceeding, you must **approve** the Fuel token contract to allow the transfer of tokens.  

In the [Fuel Token Etherscan contract UI](https://sepolia.etherscan.io/token/0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550#writeProxyContract), use the **`approve (0x095ea7b3)`** function:  

- **Spender (`address`)**: Set this to the **Sequencer Interface (Bridge)** address: [`0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4`](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4).  
- **Value (`uint256`)**: Enter the number of tokens to approve, **including 9 additional decimal places**. For unlimited approval, use:  

  ```sh
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  ```

![Testnet Etherscan Approval UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-etherscan-approval-ui.png)

### Bridging Tokens  

To bridge tokens, connect your Ethereum wallet by clicking **"Connect to Web3"** in the top left. Then, use the **`depositFor (0x36efd6f)`** function to fund your sequencer account.  

Transfer your FUEL tokens using the [Sequencer Interface (Bridge) Etherscan UI](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4#writeProxyContract).  

![Testnet Etherscan UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-etherscan-ui.png)  

- **Amount (`uint256`)**: Enter the number of tokens to send, **including 9 additional decimal places**.  
- **Recipient address**: Enter the Ethereum-compatible address you generated earlier (e.g., `0xFF8162F37072354EB1E222084DA0D4221E93550F`).  

Click **"Write"** to confirm the transaction. The transfer may take **~20 minutes** to process.  

### Verifying Funds

To verify your funds, enter your sequencer account address (i.e. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) in the [testnet block explorer](https://fuel-seq.simplystaking.xyz/fuel-testnet/statesync).  

![Testnet Block Explorer](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-blockexplorer.png)  

> **⚠ WARNING:** Always test with a small transfer before bridging FUEL tokens.

## Withdrawals

Withdrawals can be easily initiated through the CLI and will be settled on Sepolia approximately 3 days later, as the commitment and bridge finalizations must be completed first.

Identify the account from which you wish to withdraw. Use the following command to list all previously created account names matching your account address above:

```sh
fuelsequencerd keys list
```

Example output:

```sh
address: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
  name: my-testnet-validator
  pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Al6W+Ttrscm/8njeMOt79T0BOdphfWGXrDLij+O3g19N"}'
  type: local
```

Verify that this is the correct address and account name from which you wish to withdraw.

To initiate the withdrawal, use the following command where `<eth-destination-address>` is any Sepolia address you wish to withdraw to and `<amount-in-fuel>` is the amount of TEST (FUEL) you wish to withdraw:

Note: The amount in TEST (FUEL) must include 9 decimal places.

```sh
fuelsequencerd tx bridge withdraw-to-ethereum <eth-destination-address> <amount-in-fuel> \
  --from=<key> \
  --gas-prices=10test \
  --gas=auto \
  --gas-adjustment 1.5 \
  --node="https://testnet-rpc-fuel-seq.simplystaking.xyz/" \
  --chain-id="seq-testnet-2"
```

For example:

```sh
fuelsequencerd tx bridge withdraw-to-ethereum 0xd70080dE4535db4A64798a23619Db64fB28fD079 1test \
    --from=my-testnet-validator \
    --gas-prices=10test \
    --gas=auto \
    --gas-adjustment 1.5 \
    --node="https://testnet-rpc-fuel-seq.simplystaking.xyz/" \
    --chain-id="seq-testnet-2"
```

Review the transaction details and confirm the transaction by typing `yes` when prompted:

```sh
gas estimate: 106713
auth_info:
  fee:
    amount:
    - amount: "1067130"
      denom: test
    gas_limit: "106713"
    granter: ""
    payer: ""
  signer_infos: []
  tip: null
body:
  extension_options: []
  memo: ""
  messages:
  - '@type': /fuelsequencer.bridge.v1.MsgWithdrawToEthereum
    amount:
      amount: "1"
      denom: test
    from: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
    to: 0xd70080dE4535db4A64798a23619Db64fB28fD079
  non_critical_extension_options: []
  timeout_height: "0"
signatures: []
confirm transaction before signing and broadcasting [y/N]: 
```

If the transaction is successful, you will receive a transaction hash, which you can paste and monitor the status of your withdrawal [here](https://fuel-seq.simplystaking.xyz/fuel-testnet/):

```sh
code: 0
codespace: ""
data: ""
events: []
gas_used: "0"
gas_wanted: "0"
height: "0"
info: ""
logs: []
raw_log: ""
timestamp: ""
tx: null
txhash: FF51288FB916CEE4538E17FB70E438278143FAD2B613D98362A562B02C07253F
```

![Block Explorer Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-blockexplorer-withdrawal.png)

After verifying your withdrawal on the shared sequencer explorer, visit [Simply Staking](https://stake.simplystaking.com/fuel-testnet) and connect your wallet. Navigate to the **Withdrawal** tab on the right to monitor the progress of your withdrawal.

![Simply Staking Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-simplystaking-withdrawal.png)

Once the 3-day waiting period has passed, the withdrawal will require manual action to pull the funds out.

## Create the Validator

To create the validator, a prerequisite is to have at least 1TEST, with enough extra to pay for gas fees. You can check your balance from the explorer.

[//]: # (TODO: steps on how to deposit TEST tokens to a Sequencer address)

Once you have TEST tokens, run the following to create a validator, using the name of the account that you created in the previous steps:

```sh
fuelsequencerd tx staking create-validator path/to/validator.json \
    --from <NAME> \
    --gas auto \
    --gas-prices 10test \
    --gas-adjustment 1.5 \
    --chain-id seq-testnet-2
```

...where validator.json contains:

```json
{
 "pubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"<PUBKEY>"},
 "amount": "1000000000test",
 "moniker": "<MONIKER>",
 "identity": "<OPTIONAL-IDENTITY>",
 "website": "<OPTIONAL-WEBSITE>",
 "security": "<OPTIONAL-EMAIL>",
 "details": "<OPTIONAL-DETAILS>",
 "commission-rate": "0.05",
 "commission-max-rate": "<MAX-RATE>",
 "commission-max-change-rate": "<MAX-CHANGE-RATE>",
 "min-self-delegation": "1"
}
```

...where the pubkey can be obtained using `fuelsequencerd tendermint show-validator`.

### What to Expect

- The Sequencer should show block syncing.
- The Sidecar should show block extraction. Occasionally it also receives requests for events.

### Tendermint KMS

If you will be using `tmkms`, make sure that in the config:

- Chain ID is set to `seq-testnet-2` wherever applicable
- `account_key_prefix = "fuelsequencerpub"`
- `consensus_key_prefix = "fuelsequencervalconspub"`
- `sign_extensions = true`
- `protocol_version = "v0.34"`

### Additional Advanced Configuration

Sidecar flags:

- `development`: starts the sidecar in development mode.
- `eth_max_block_range`: max number of Ethereum blocks queried at one go.
- `eth_min_logs_query_interval`: minimum wait between successive queries for logs.
- `unsafe_eth_start_block`: the Ethereum block to start querying from.
- `unsafe_eth_end_block`: the last Ethereum block to query. Incorrect use can cause the validator to propose empty blocks, leading to slashing!
- `sequencer_path_to_cert_file`: path to the certificate file of the Sequencer infrastructure for secure communication. Specify this value if the Sequencer infrastructure was set up using TLS.
- `sidecar_path_to_cert_file`: path to the certificate file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `sidecar_path_to_key_file`: path to the private key file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `prometheus_enabled`: enables serving of prometheus metrics.
- `prometheus_listen_address`: address to listen for prometheus collectors (default ":8081").
- `prometheus_max_open_connections`: max number of simultaneous connections (default 3).
- `prometheus_namespace`: instrumentation namespace (default "sidecar").
- `prometheus_read_header_timeout`: amount of time allowed to read request headers (default 10s).
- `prometheus_write_timeout`: maximum duration before timing out writes of the response (default 10s).

Sidecar client flags:

- `sidecar_grpc_url`: the sidecar's gRPC endpoint.
- `query_timeout`: how long to wait before the request times out.

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-testnet#set-up-cosmovisor


---

### File: docs/nightly/node-operator/docs/src/index.md

# Running a Node

This guide is designed to swiftly introduce you to the process of running a local node for the Fuel blockchain.

## What is a Node?

In the context of the Fuel blockchain, a node, often referred to as a 'client', is a piece of software that downloads and maintains a copy of the Fuel blockchain. It verifies the authenticity of every block and transaction, ensuring that your copy is always up-to-date and in sync with the network.

## Why Run Your Own Node?

Running your own node provides several advantages:

1. **Query Freedom:** By hosting your own node, you can execute a higher number of queries without encountering any rate limits.
2. **Network Independence:** Having your own node ensures that you're not reliant on third-party services, giving you full control over your interactions with the Fuel blockchain.

## Types Of Networks

There are two networks you can currently run the nodes for

1. Fuel Ignition: Fuel V2 layer 2 rollup to go on Ethereum Mainnet.

2. Fuel's proposed cosmos based blockchain shared sequencer design prioritizes speed and efficiency, rapidly processing cross-chain transactions. Our fast sequencing empowers developers to build versatile, low-latency cross-chain applications, mitigating typical multi-chain fragmentation.

## Getting Started

Depending on which network you wish to participate in follow the following sections.

1. [Fuel Ignition](./fuel-ignition/index.md)
2. [Fuel Shared Sequencer](./fuel-sequencer/index.md)


---

### File: docs/nightly/sway-by-example-lib/docs/src/base-asset.md

# Base Asset

Examples of base asset in Sway

```sway
contract;

use std::{
    auth::{
        msg_sender,
    },
    call_frames::{
        msg_asset_id,
    },
    contract_id::ContractId,
    context::{
        balance_of,
        msg_amount,
    },
    asset::{
        transfer,
    },
};

abi MyContract {
    #[payable]
    fn deposit();
    fn withdraw(amount: u64);
    fn get_balance() -> u64;
}

impl MyContract for Contract {
    #[payable]
    fn deposit() {
        require(msg_asset_id() == AssetId::base(), "not base asset");
        require(msg_amount() > 0, "amount = 0");
    }

    fn withdraw(amount: u64) {
        transfer(msg_sender().unwrap(), AssetId::base(), amount);
    }

    fn get_balance() -> u64 {
        balance_of(ContractId::this(), AssetId::base())
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/big-numbers.md

# Big Numbers

Examples of Big Numbers in Sway

```sway
contract;

// Storage declaration
storage {
    big_number: u256 = 0,
}

// ABI definition
abi BigNumberContract {

    #[storage(write)]
    fn set_big_number(value: u256);

    #[storage(read)]
    fn get_big_number() -> u256;

    #[storage(write)]
    fn add_u64_to_big_number(value: u64);

    #[storage(write)]
    fn multiply_big_number_by_u64(value: u64);
}

// Implementation of the ABI
impl BigNumberContract for Contract {
    /// Sets the big number to a new value.
    ///
    /// # Arguments
    ///
    /// * `value`: [u256] - The new value to set.
    ///
    /// # Storage Access
    ///
    /// * Writes: `1`
    #[storage(write)]
    fn set_big_number(value: u256) {
        // Write the new value to the storage variable `big_number`.
        storage.big_number.write(value);
    }

    /// Returns the current big number.
    ///
    /// # Returns
    ///
    /// * [u256] - The current big number.
    ///
    /// # Storage Access
    ///
    /// * Reads: `1`
    #[storage(read)]
    fn get_big_number() -> u256 {
        // Read and return the value of the storage variable `big_number`.
        storage.big_number.read()
    }

    /// Adds a `u64` value to the current big number.
    ///
    /// # Arguments
    ///
    /// * `value`: [u64] - The value to add.
    ///
    /// # Storage Access
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    #[storage(write)]
    fn add_u64_to_big_number(value: u64) {
        // Read the current value of the storage variable `big_number`.
        let current_value = storage.big_number.read();
        // Convert the `u64` value to `u256`.
        let value_as_u256 = value.as_u256();
        // Add the converted value to the current value.
        let new_value = current_value + value_as_u256;
        // Write the new value back to the storage variable `big_number`.
        storage.big_number.write(new_value);
    }

    /// Multiplies the current big number by a `u64` value.
    ///
    /// # Arguments
    ///
    /// * `value`: [u64] - The value to multiply by.
    ///
    /// # Storage Access
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    #[storage(write)]
    fn multiply_big_number_by_u64(value: u64) {
        // Read the current value of the storage variable `big_number`.
        let current_value = storage.big_number.read();
        // Convert the `u64` value to `u256`.
        let value_as_u256 = value.as_u256();
        // Multiply the current value by the converted value.
        let new_value = current_value * value_as_u256;
        // Write the new value back to the storage variable `big_number`.
        storage.big_number.write(new_value);
    }
}


```


---

### File: docs/nightly/sway-by-example-lib/docs/src/blockchain-types.md

# Blockchain Types

Examples of blockchain data types in Sway

```sway
contract;

// Address
// Contract Id
// Identity

abi MyContract {
    fn test_func() -> Identity;
}

impl MyContract for Contract {
    fn test_func() -> Identity {
        // Address
        let b: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
        let addr: Address = Address::from(b);
        let b: b256 = addr.into();

        // Contract id
        let b: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
        let my_contract_id: ContractId = ContractId::from(b);
        let b: b256 = my_contract_id.into();

        // Identity type
        let raw_addr: b256 = 0xddec0e7e6a9a4a4e3e57d08d080d71a299c628a46bc609aab4627695679421ca;
        let addr = Address::from(raw_addr);
        let my_id: Identity = Identity::Address(addr);

        // Match on identity
        let id: Address = match my_id {
            Identity::Address(addr) => addr,
            Identity::ContractId(id) => revert(0),
        };

        my_id
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/compound-types.md

# Compound Types

Examples of compound data types in Sway

```sway
contract;

// Compound types
// - Tuples
// - destructuring
// - Structs
// - Arrays

struct Point {
    x: u64,
    y: u64,
}

abi MyContract {
    fn test_func() -> Point;
}

impl MyContract for Contract {
    fn test_func() -> Point {
        // Tuples
        let t: (u64, bool) = (42, true);
        // Access tuple value
        assert(t.0 == 42);
        assert(t.1);

        // Destructuring a tuple (type annotation is optional)
        let (num, boo) = t;

        // Tuple of length 1
        let one: (u64, ) = (123, );

        // Struct
        let p = Point { x: 1, y: 2 };
        // Access struct fields
        assert(p.x == 1);
        assert(p.y == 2);

        // Array
        let u_arr: [u8; 5] = [1, 2, 3, 4, 5];
        let s_arr: [str; 4] = ["cat", "dog", "snake", "fish"];

        let struct_arr: [Point; 2] = [Point { x: 1, y: 2 }, Point { x: 11, y: 22 }];

        // Mutating array
        let mut mut_arr: [bool; 2] = [true, false];
        mut_arr[1] = true;

        p
    }

}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/configurable-constants.md

# Configurable Constants

Examples of configurable constants in Sway

```sway
contract;

// Configurable constants

configurable {
    MY_NUM: u64 = 123,
    OWNER: Address = Address::from(0x3333333333333333333333333333333333333333333333333333333333333333),
    POINT: Point = Point { x: 1, y: 2 },
}

struct Point {
    x: u64,
    y: u64,
}

abi MyContract {
    fn test_func() -> (u64, Address, Point);
}

impl MyContract for Contract {
    fn test_func() -> (u64, Address, Point) {
        (MY_NUM, OWNER, POINT)
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/constants.md

# Constants

Examples of constants in Sway

```sway
contract;

// Constants

// 0x0000000000000000000000000000000000000000000000000000000000000000
const ZERO_B256: b256 = b256::min();
const ZERO_ADDRESS = Address::from(ZERO_B256);

// Associated constants
struct Point {
    x: u64,
    y: u64,
}

impl Point {
    const ZERO: Point = Point { x: 0, y: 0 };
}

abi MyContract {
    fn test_func() -> Point;
}

impl MyContract for Contract {
    fn test_func() -> Point {
        // Can also define a constant inside a function
        const MY_NUM: u64 = 123;
        Point::ZERO
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/enums.md

# Enums

Examples of enums in Sway

```sway
contract;

// Enums
// - Basics
// - Enums of structs
// - Enum of enums

enum Color {
    Red: (),
    Blue: (),
    Green: (),
}

// Enums of structs
struct Point {
    x: u64,
    y: u64,
}

enum Shape {
    Circle: (Point, u64),
    Triangle: [Point; 3],
}

// Enum of enums
enum Error {
    Auth: AuthError,
    Transfer: TransferError,
}

enum AuthError {
    NotOwner: (),
    NotApproved: (),
}

enum TransferError {
    TransferToZeroAddress: (),
    InsufficientBalance: (),
}

abi MyContract {
    fn test_func() -> Error;
}

impl MyContract for Contract {
    fn test_func() -> Error {
        let color = Color::Blue;

        let circle = Shape::Circle((Point { x: 0, y: 0 }, 1));
        let triangle = Shape::Triangle([
            Point { x: 0, y: 0 },
            Point { x: 1, y: 1 },
            Point { x: 2, y: 0 },
        ]);

        let error = Error::Auth(AuthError::NotOwner);

        error
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/functions.md

# Functions

Examples of functions in Sway

```sway
contract;

// Functions
// - Internal and external functions
// - ref mut
// - Return multiple outputs

abi MyContract {
    fn test_func() -> (u64, bool);
}

fn eq(x: u64, y: u64) -> bool {
    x == y
}

fn inc(ref mut num: u64) {
    num += 1;
}

fn swap_mut(ref mut pair: (u64, u64)) {
    let tmp = pair.0;
    pair.0 = pair.1;
    pair.1 = tmp;
}

fn swap(x: u64, y: u64) -> (u64, u64) {
    (y, x)
}

impl MyContract for Contract {
    fn test_func() -> (u64, bool) {
        assert(eq(11, 11));
        assert(!eq(11, 12));

        let mut num: u64 = 123;
        inc(num);
        assert(num == 123 + 1);

        let mut pair = (12, 13);
        swap_mut(pair);
        assert(pair.0 == 13);
        assert(pair.1 == 12);

        let x = 1;
        let y = 2;
        let (y, x) = swap(x, y);
        assert(y == 1);
        assert(x == 2);
        (123, true)
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/hashing.md

# Hashing with Keccak256

Example of how to compute hash in Sway using Keccak256

```sway
contract;

use std::hash::*;
use std::bytes::Bytes;
use std::codec::encode;

abi HashFunction {
    fn hash(_text: str, _num: u64, _addr: b256) -> b256;
    fn collision(_text: str, _anotherText: str) -> b256;
    fn guess(_word: str) -> bool;
}

impl HashFunction for Contract {
    fn hash(_text: str, _num: u64, _addr: b256) -> b256 {
        keccak256({
            let mut bytes = Bytes::new();
            bytes.append(Bytes::from(encode(_text)));
            bytes.append(Bytes::from(encode(_num)));
            bytes.append(Bytes::from(encode(_addr)));
            bytes
        })
    }

    // The collision function is not strictly necessary unless you have a specific use case that requires hashing two strings together. 
    // If your primary goal is to hash individual strings you can remove the collision function.
    fn collision(_text: str, _anotherText: str) -> b256 {
        keccak256({
            let mut bytes = Bytes::new();
            bytes.append(Bytes::from(encode(_text)));
            bytes.append(Bytes::from(encode(_anotherText)));
            bytes
        })
    }

    fn guess(_word: str) -> bool {
        let answer: b256 = 0x60298f78cc0b47170ba79c10aa3851d7648bd96f2f8e46a19dbc777c36fb0c00;
        keccak256({
            let mut bytes = Bytes::new();
            bytes.append(Bytes::from(encode(_word)));
            bytes
        }) == answer
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/hello-sway.md

# Hello Sway

The `contract` keyword at the top defines one of the four program types found in Sway. Others being libraries, scripts and predicates.

```sway
// The underlying smart contracts written in Sway are no different than those in Solidity
// Some bytecode is deployed with an API and state to interact with
contract;

// The ABI (Application Binary Interface) clearly defines the signature of the functions present in the contract
abi HelloModular {
    // The "annotation" storage indicates the impure actions of the function
    // In this case the greet() function only has reading capabilities.
    // Note: Storage can only be found in contract type programs
    #[storage(read)]
    fn my_lucky_number() -> u64;
}

// Storage contains all of the state available in the contract 
storage {
    lucky_number: u64 = 777,
}

// The actual implementation of ABI for the contract
impl HelloModular for Contract {
    #[storage(read)]
    fn my_lucky_number() -> u64 {
        storage.lucky_number.read()
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/if.md

# If Statements

Examples of if statements in Sway

```sway
contract;

// if, else if, else
// if let

abi MyContract {
    fn test_func(x: u64) -> u64;
}

impl MyContract for Contract {
    fn test_func(x: u64) -> u64 {
        // if, else if, else
        if x < 10 {
            // do something
        } else if x < 20 {
            // do something else
        } else {
            // do something else
        }

        // if let
        let mut y = 0;
        if x < 10 {
            y = x * x;
        } else {
            y = x + 1;
        }

        // Assign the outcome of if statements to the variable y
        let y = if x < 10 {
            // do something, for example
            x * x
        } else {
            // do something else, for example
            x + 1
        }; // Notice semicolon here

        y
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/imports.md

# Imports

Examples of imports in Sway

```sway
contract;

// Imports
// - Internal
mod imports_library;
use imports_library::*;

// - External
use math_lib::full_math::*;

// - Standard library (std)
use std::{
    identity::*,
    auth::msg_sender,
};

// - Sway standards
use standards::src20::SRC20;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}

```

## Project Structures

### Internal

```bash

└── imports
    ├── Forc.toml
    └── src
        ├── imports_library.sw
        └── main.sw

```

### External

```bash

├── imports
│   ├── Forc.toml
│   └── src
│       ├── imports_library.sw
│       └── main.sw
└── math_lib
    ├── Forc.toml
    └── src
        ├── Q64x64.sw
        ├── full_math.sw
        └── math_lib.sw

```

All external imports must be defined as dependencies within `Forc.toml`

```toml
[project]
authors = ["Kin Chan"]
entry = "main.sw"
license = "Apache-2.0"
name = "imports"

[dependencies]
standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.7.1" }
math_lib = { path = "../math_lib/" }

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/index.md

# Sway By Example

Library of compiled Sway programs to showcase accessible code for the Sway language.


---

### File: docs/nightly/sway-by-example-lib/docs/src/library.md

# Library

Example on how to create a library in Sway and how to use it in your Smart Contract.
This example also showcases how to use different types of imports in Sway depending on external library or library from the same project.

```sway
contract;

// 1. Importing within the same project
// Using "mod" keyword, you can import an internal library that has been defined in this project.
mod sqrt_lib;

// It is a good practice to import in ABI
// It is also a good practice to define events and custom errors using this way

// Using "use" keyword imports in a library. This method is used to import an external lilbray that is defined outside the main `src` directory.
// use sqrt_lib::math_sqrt;
// $ tree
// .
// ├── my_project
// │   ├── Cargo.toml
// │   ├── Forc.toml
// │   └─── src
// │       └── main.sw
// │
// └── external_lib
//     ├── Cargo.toml
//     ├── Forc.toml
//     └─── src
//         └── lib.sw
// External library is outside the src directory of our project. Thus, it needs to be added as a dependency in the Forc.toml of our project.
// [dependencies]
// external_lib = { path = "../external_lib" }


// 2. Importing the standard library
// The standard library consists of
//   a. language primitives
//   b. blockchain contextual operations
//   c. native asset management
//   etc.
// Functions like msg.sender(), block.timestamp(),etc are found here https://github.com/FuelLabs/sway/tree/master/sway-lib-std
// use std::{
//     identity::*,
//     address::*,
//     constants::*,
//     auth::msg_sender,
// };


// 3. Importing from a different project
// If any library is not listed as a dependency, but present in forc.toml, you can use it as below.
// Math libraries copied from https://github.com/sway-libs/concentrated-liquidity/
// use math_lib::full_math::*;

use ::sqrt_lib::math_sqrt;

abi TestMath {
    fn test_square_root(x: u256) -> u256;
}

impl TestMath for Contract {
    fn test_square_root(x: u256) -> u256 {
        math_sqrt(x)
    }
}
```


---

### File: docs/nightly/sway-by-example-lib/docs/src/logging.md

# Logging

Examples of logging in Sway

```sway

contract;

use std::logging::log;

abi MyContract {
    fn test_func(val: u64);
}

impl MyContract for Contract {
    fn test_func(val: u64) {
        log(val);
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/match.md

# Match Statements

Examples of match statements in Sway

```sway
contract;

// Control flow
// Assign variable
// Enum

abi MyContract {
    fn test_function(x: u64, y: Option<u64>) -> u64;
}

fn do_something() {}

fn do_something_else() {}

impl MyContract for Contract {
    fn test_function(x: u64, y: Option<u64>) -> u64 {
        // Control flow
        match x {
            0 => do_something(),
            _ => do_something_else(),
        }

        // Assign variable
        let res: str = match x {
            0 => "a",
            1 => "b",
            2 => "c",
            _ => "d",
        };

        // Enum
        let z = match y {
            Option::Some(val) => val + 1,
            Option::None => 0,
        };

        z
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/options.md

# Options

Examples of options in Sway

```sway
contract;

// Option<T> = Some(T) | None

abi MyContract {
    fn test_func() -> (Option<bool>, Option<bool>, Option<bool>);
}

impl MyContract for Contract {
    fn test_func() -> (Option<bool>, Option<bool>, Option<bool>) {
        let liked = Option::Some(true);
        let disliked = Option::Some(false);
        let none = Option::None;
        (liked, disliked, none)
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/predicate.md

# Predicate

Examples of a predicate program type in Sway

|                                | Predicates | Contracts |
|--------------------------------|------------|-----------|
| Access data on chain           |      ❌     |     ✅     |
| Read data from smart contracts |      ❌     |     ✅     |
| Check date or time             |      ❌     |     ✅     |
| Read block hash or number      |      ❌     |     ✅     |
| Read input coins               |      ✅     |     ✅     |
| Read output coins              |      ✅     |     ✅     |
| Read transaction scripts       |      ✅     |     ✅     |
| Read transaction bytecode      |      ✅     |     ✅     |

```sway
predicate;

use std::{
    auth::predicate_address,
    inputs::{
        input_amount,
    },
    outputs::{
        output_amount,
    },
    tx::{
        tx_id,
        tx_witnesses_count
    },
    constants::ZERO_B256,
};

// Configurables
configurable {
    FLOOR: u64 = 1,
}

fn input_output_checks() -> bool {
    if (100 >= input_amount(0).unwrap() && 100 >= output_amount(0).unwrap()) {
        return true
    }
    return false
}

// Primitive Arguments 
fn main(a: u64, b: str, c: bool, d: b256) -> bool {
    // This predicate's own address
    let this_predicate_root = predicate_address();

    if (a == 0 || b == "a" || c == false ||  d == ZERO_B256) {
        return false
    }

    if tx_witnesses_count() < 1 { 
        return false
    }

    // While loop 
    let mut x = 10;
    while x != FLOOR { 
        x -= 1; 
    }

    return input_output_checks()
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/primitive-types.md

# Primitive Types

Examples of primitive data types in Sway

```sway
contract;

// Primitive types
// - Unsigned integers
// - Strings
// - Boolean
// - 256 bits = 32 bytes

abi MyContract {
    fn test_func() -> bool;
}

impl MyContract for Contract {
    fn test_func() -> bool {
        // Unsigned integers
        // 0 <= u8 <= 2**8 - 1
        let u_8: u8 = 123;
        // 0 <= u16 <= 2**16 - 1
        let u_16: u16 = 123;
        // 0 <= u32 <= 2**32 - 1
        let u_32: u32 = 123;
        // 0 <= u64 <= 2**64 - 1
        let u_64: u64 = 123;
        // 0 <= u256 <= 2**256 - 1 
        // Since u256 are bigger than registers they are stored in memory rather than registers
        let u256: u256 = 123;

        let u_64_max = u64::max();

        // String slice
        let s_slice: str = "fuel";

        // Fixed length string array
        let s_array: str[4] = __to_str_array("fuel");

        // Boolean
        let boo: bool = true;
        // 256 bits = 32 bytes
        let b_256: b256 = 0x1111111111111111111111111111111111111111111111111111111111111111;

        true
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/results.md

# Results

Examples of if statements in Sway

```sway
contract;

// Result<T, E> = Ok(T) | Err(E)

enum MathError {
    DivByZero: (),
}

fn div(x: u64, y: u64) -> Result<u64, MathError> {
    if y == 0 {
        return Result::Err(MathError::DivByZero);
    }

    Result::Ok(x / y)
}

abi MyContract {
    fn test_div(x: u64, y: u64) -> u64;
}

impl MyContract for Contract {
    fn test_div(x: u64, y: u64) -> u64 {
        let res = div(x, y);
        match res {
            Result::Ok(val) => val,
            Result::Err(err) => revert(0),
        }
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/script.md

# Script

Examples of a script program type in Sway

|                                | Predicates | Scripts  |
|--------------------------------|------------|-----------|
| Access data on chain           |      ❌     |     ✅     |
| Read data from smart contracts |      ❌     |     ✅     |
| Check date or time             |      ❌     |     ✅     |
| Read block hash or number      |      ❌     |     ✅     |
| Read input coins               |      ✅     |     ✅     |
| Read output coins              |      ✅     |     ✅     |
| Read transaction scripts       |      ✅     |     ✅     |
| Read transaction bytecode      |      ✅     |     ✅     |

```sway
script;

abi ContractA {
    fn test_func(x: u64) -> Identity;
}

const CONTRACTA_ID = 0x79fa8779bed2f36c3581d01c79df8da45eee09fac1fd76a5a656e16326317ef0;

fn main(a: u64) {
    let c = abi(ContractA, CONTRACTA_ID);

    // Call a contract multiple times
    log(c.test_func(a));
    log(c.test_func(a + 32));
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/solidity.md

# Solidity

A quick `Solidity` → `Sway` cross reference for the most commonly used items

- block.timestamp
- msg.sender
- etc

If something is missing here you can most likely find it in the Sway STD Library

```sway
contract;

use std::{
    identity::Identity,
    block::{ height, timestamp },
    auth::msg_sender,
    hash::*,
    constants::*,
};

abi SolidityCheatsheet {
    fn get_blocknumber() -> u32;
    fn get_blocktime() -> u64;
    fn get_msg_sender() -> Identity;
    fn get_bytes32() -> b256;
    fn get_hash() -> b256;
    fn get_u256_number() -> u256;
}

impl SolidityCheatsheet for Contract {
    fn get_blocknumber() -> u32 {
        return height(); // block.number equivalent
    }
    
    fn get_blocktime() -> u64 {
        return timestamp(); // block.timestamp equivalent
    }
    
    fn get_msg_sender() -> Identity {
        return msg_sender().unwrap(); // msg.sender equivalent
    }
    
    fn get_bytes32() -> b256 {
        return 45.as_u256().as_b256(); // u64 to u256 to b256
    }
    
    fn get_hash() -> b256 {
        return sha256("Sway is the way"); // hashing of fixed size string
    }

    fn get_u256_number() -> u256 {
        return u256::from((u64::min(), u64::min(), u64::min(), u64::min())); // big number equivalent
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/src20.md

# SRC20

Examples of a SRC 20 contract in Sway

```sway
contract;

use standards::src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent,};
use std::{auth::msg_sender, string::String};

configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

impl SRC20 for Contract {
    /// Returns the total number of individual assets minted by a contract.
    ///
    /// # Additional Information
    ///
    /// For this single asset contract, this is always one.
    ///
    /// # Returns
    ///
    /// * [u64] - The number of assets that this contract has minted.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let assets = src_20_abi.total_assets();
    ///     assert(assets == 1);
    /// }
    /// ```
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    /// Returns the total supply of coins for the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the total supply, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u64>] - The total supply of an `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let supply = src_20_abi.total_supply(DEFAULT_SUB_ID);
    ///     assert(supply.unwrap() != 0);
    /// }
    /// ```
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }

    /// Returns the name of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the name, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The name of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let name = src_20_abi.name(DEFAULT_SUB_ID);
    ///     assert(name.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    /// Returns the symbol of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the symbol, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The symbol of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let symbol = src_20_abi.symbol(DEFAULT_SUB_ID);
    ///     assert(symbol.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    /// Returns the number of decimals the asset uses.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the decimals, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u8>] - The decimal precision used by `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let decimals = src_20_abi.decimals(DEFAULT_SUB_ID);
    ///     assert(decimals.unwrap() == 9u8);
    /// }
    /// ```
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();

        log(SetNameEvent {
            asset,
            name: Some(String::from_ascii_str(from_str_array(NAME))),
            sender,
        });

        log(SetSymbolEvent {
            asset,
            symbol: Some(String::from_ascii_str(from_str_array(SYMBOL))),
            sender,
        });

        log(SetDecimalsEvent {
            asset,
            decimals: DECIMALS,
            sender,
        });

        log(TotalSupplyEvent {
            asset,
            supply: TOTAL_SUPPLY,
            sender,
        });
    }
}
```


---

### File: docs/nightly/sway-by-example-lib/docs/src/storage-map.md

# Storage Map

Examples of storage map in Sway

```sway
contract;

use std::{
    hash::Hash,
    auth::msg_sender
};

// StorageMap
// - basic (insert, read, update, remove)
// - nested

abi MyContract {
    #[storage(read, write)]
    fn basic_examples();

    #[storage(read, write)]
    fn nested_examples();
}

storage {
    balance_of: StorageMap<Identity, u64> = StorageMap {},
    allowance: StorageMap<(Identity, Identity), u64> = StorageMap {},
}

const ADDR: b256 = 0x1000000000000000000000000000000000000000000000000000000000000000;

impl MyContract for Contract {
    #[storage(read, write)]
    fn basic_examples() {
        let sender = msg_sender().unwrap();

        // Insert
        storage.balance_of.insert(sender, 123);
        // Read
        let bal = storage.balance_of.get(sender).try_read().unwrap_or(0);
        // Update
        storage.balance_of.insert(sender, bal + 1);
        // Remove
        storage.balance_of.remove(sender);
    }

    #[storage(read, write)]
    fn nested_examples() {
        let sender = msg_sender().unwrap();
        let spender = Identity::Address(Address::from(ADDR));

        // Read
        let val = storage.allowance.get((sender, spender)).try_read().unwrap_or(0);
        // Insert / update
        storage.allowance.insert((sender, spender), val + 1);
        // Remove
        storage.allowance.remove((sender, spender));
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/structs.md

# Structs

Examples of structs in Sway

```sway
contract;

// Structs
// - Create, read and update
// - Shorthand notation
// - Destructure

struct Point {
    x: u64,
    y: u64,
}

// Nested struct
struct Line {
    p0: Point,
    p1: Point,
}

abi MyContract {
    fn test_func() -> Line;
}

impl MyContract for Contract {
    fn test_func() -> Line {
        // Create, read and update
        let mut p0 = Point { x: 1, y: 2 };

        p0.x = 11;

        // Shorthand
        let x: u64 = 123;
        let y: u64 = 123;

        let p1 = Point { x, y };

        // Nested structs
        let line = Line { p0, p1 };

        // Destructure
        let Line {
            p0: Point { x: x0, y: y0 },
            p1: Point { x: x1, y: y1l },
        } = line;

        line
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/tuples.md

# Tuples

Examples of tuples in Sway

```sway
contract;

// Tuples
// - Create, read, update
// - Nested
// - Destructure and "_"

abi MyContract {
    fn test_func() -> (u64, (str, bool));
}

impl MyContract for Contract {
    fn test_func() -> (u64, (str, bool)) {
        let mut tuple: (u64, bool, u64) = (1, false, 2);
        tuple.0 = 123;
        let x = tuple.0;

        let nested = (1, ("Fuel", false));
        let s = nested.1.0;

        let (n, (s, b)) = nested;
        // Skip variables for 0 and 1.1 
        let (_, (s, _)) = nested;

        nested
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/variables.md

# Variables

Examples of variables in Sway

```sway
contract;

abi MyContract {
    fn test_func() -> u64;
}

impl MyContract for Contract {
    fn test_func() -> u64 {
        // Immutable
        // 0 <= u64 <= 2**64 - 1
        let x = 5;
        // Cannot re-assign x to another value
        // x = 6;

        // Mutable
        let mut y = 5;
        y = 6;

        // Type annotations
        let i: u32 = 123;

        y
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/vector.md

# Vector

Examples of vectors in Sway

```sway
contract;

use std::{storage::storage_vec::*};

// storage vector, heap

abi MyContract {
    #[storage(read, write)]
    fn storage_vec_examples();
    fn heap_vec_examples();
}

storage {
    nums: StorageVec<u64> = StorageVec {},
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn storage_vec_examples() {
        // push
        // pop
        // get
        // set
        // remove - moves all elements down by one 
        // swap remove - remove element, move last element
        // len
        // clear - sets length to zero
        // loop

        // push
        storage.nums.push(100);
        storage.nums.push(200);
        storage.nums.push(300);
        storage.nums.push(400);
        storage.nums.push(500);
        storage.nums.push(600);

        // pop - remove last - returns Option<num>
        let last = storage.nums.pop();

        // get
        let first = storage.nums.get(0).unwrap();
        let none = storage.nums.get(1000);

        // set
        storage.nums.set(0, 123);

        // remove - Returns value removed
        // Before remove [100, 200, 300, 400]
        // After  remove [100, 300, 400]
        let removed_val = storage.nums.remove(1);

        // swap remove
        // Before swap_remove [100, 300, 400, 500]
        // After  swap_remove [100, 500, 400]
        storage.nums.swap_remove(1);

        let len = storage.nums.len();

        // clear - sets length to zero
        storage.nums.clear();

        // Loop example
        let mut i = 0;
        while i < len {
            let val = storage.nums.get(i).unwrap();
            i += 1;
        }
    }

    fn heap_vec_examples() {
        // new
        // push
        // pop
        // remove
        // get
        // set
        // len
        let mut v: Vec<u64> = Vec::new();

        v.push(100);
        v.push(200);
        v.push(300);
        v.push(400);
        v.push(500);

        // Returns Option<u64>
        v.pop();

        // Before remove [100, 200, 300, 400]
        // After  remove [100, 300, 400]
        // Returns removed element
        v.remove(1);

        let val = v.get(1).unwrap();

        v.set(1, val + 1);

        let len = v.len();
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/verify-signature.md

# Verifying Signatures in Sway

Example of how to verify signatures in Sway

```sway
contract;

use std::hash::*;
use std::ecr::{ec_recover_address, EcRecoverError};
use std::bytes::Bytes;
use std::b512::B512;
use std::constants::ZERO_B256;
use std::codec::encode;

abi VerifySignature {
    fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256;
    fn GetEthSignedMessageHash(message_hash: b256) -> b256;
    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256;
    fn verify(signer: b256, to: b256, amount: u64, message: str, nonce: u64, signature: B512) -> bool;
    
}

fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256 {
        keccak256({
        let mut bytes = Bytes::new();
        bytes.append(Bytes::from(encode(to)));
        bytes.append(Bytes::from(encode(amount)));
        bytes.append(Bytes::from(encode(message)));
        bytes.append(Bytes::from(encode(nonce)));
        bytes
    })
    }

    fn GetEthSignedMessageHash(message_hash: b256) -> b256 {
        keccak256({
        let mut bytes = Bytes::new();
        bytes.append(Bytes::from(encode("\x19Fuel Signed Message:\n32")));
        bytes.append(Bytes::from(encode(message_hash)));
        bytes
    })
    }

    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256 {
        match ec_recover_address(signature, eth_signed_message_hash) {
            Ok(address) => address.bits(),
            Err(_) => ZERO_B256,
        }
    }

impl VerifySignature for Contract {


    fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256{
        ::GetMessageHash(to, amount, message, nonce)
    }

    fn GetEthSignedMessageHash(message_hash: b256) -> b256 {
        ::GetEthSignedMessageHash(message_hash)
    }

    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256{
        ::RecoverSigner(eth_signed_message_hash, signature)
    }
    
   fn verify(signer: b256, to: b256, amount: u64, message: str, nonce: u64, signature: B512) -> bool {   
        let MessageHash = GetMessageHash(to, amount, message, nonce);
        let EthSignedMessage = GetEthSignedMessageHash(MessageHash);
        let RecoverSigner = RecoverSigner(EthSignedMessage, signature);
        RecoverSigner == signer
    }
}

```


---

### File: docs/nightly/sway-by-example-lib/docs/src/while-loop.md

# While Loop

Examples of while loop in Sway

```sway
contract;

// While loops
// continue and break

abi MyContract {
    fn example_1() -> u64;
    fn example_2() -> u64;
    fn example_3() -> u64;
}

impl MyContract for Contract {
    fn example_1() -> u64 {
        let mut total = 0;
        let mut i = 0;
        while i < 5 {
            i += 1;
            total += i;
        }

        // total = 1 + 2 + 3 + 4 + 5
        total
    }

    fn example_2() -> u64 {
        // continue - sum odds
        let mut total = 0;
        let mut i = 0;
        while i < 5 {
            i += 1;
            // Skip if even
            if i % 2 == 0 {
                continue;
            }
            total += i;
        }

        // total = 1 + 3 + 5
        total
    }

    fn example_3() -> u64 {
        // break
        let mut total = 0;
        let mut i = 0;
        while i < 5 {
            i += 1;
            if i > 3 {
                // Exit loop
                break;
            }
            total += i;
        }

        // total = 1 + 2 + 3
        total
    }
}

```


---

### File: docs/nightly/sway-libs/docs/book/src/admin/index.md

# Admin Library

The Admin library provides a way to block users without an "administrative status" from calling functions within a contract. The Admin Library differs from the [Ownership Library](../ownership/index.md) as multiple users may have administrative status. The Admin Library is often used when needing administrative calls on a contract that involve multiple users or a whitelist.

This library extends the [Ownership Library](../ownership/index.md). The Ownership library must be imported and used to enable the Admin library. Only the contract's owner may add and remove administrative users.

For implementation details on the Admin Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/admin/admin/).

## Importing the Admin Library

In order to use the Admin Library, the Admin and the Ownership Libraries must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Admin and the Ownership Libraries as dependencies to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add admin@0.26.0
forc add ownership@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Admin Library, be sure to include both the Admin and Ownership Libraries in your import statements.

```sway
use {admin::*, ownership::*};
```

## Integrating the Admin Library into the Ownership Library

To use the Admin library, be sure to set a contract owner for your contract. The following demonstrates setting a contract owner using the [Ownership Library](../ownership/).

```sway
use {admin::add_admin, ownership::initialize_ownership};

#[storage(read, write)]
fn my_constructor(new_owner: Identity) {
    initialize_ownership(new_owner);
}

#[storage(read, write)]
fn add_a_admin(new_admin: Identity) {
    // Can only be called by contract's owner set in the constructor above.
    add_admin(new_admin);
}
```

## Basic Functionality

### Adding an Admin

To add a new admin to a contract, call the `add_admin()` function.

```sway
#[storage(read, write)]
fn add_a_admin(new_admin: Identity) {
    // Can only be called by contract's owner.
    add_admin(new_admin);
}
```

> **NOTE** Only the contract's owner may call this function. Please see the example above to set a contract owner.

### Removing an Admin

To remove an admin from a contract, call the `revoke_admin()` function.

```sway
#[storage(read, write)]
fn remove_an_admin(old_admin: Identity) {
    // Can only be called by contract's owner.
    revoke_admin(old_admin);
}
```

> **NOTE** Only the contract's owner may call this function. Please see the example above to set a contract owner.

### Applying Restrictions

To restrict a function to only an admin, call the `only_admin()` function.

```sway
#[storage(read)]
fn only_owner_may_call() {
    only_admin();
    // Only an admin may reach this line.
}
```

> **NOTE:** Admins and the contract's owner are independent of one another. `only_admin()` will revert if called by the contract's owner.

To restrict a function to only an admin or the contract's owner, call the `only_owner_or_admin()` function.

```sway
#[storage(read)]
fn both_owner_or_admin_may_call() {
    only_owner_or_admin();
    // Only an admin may reach this line.
}
```

### Checking Admin Status

To check the administrative privileges of a user, call the `is_admin()` function.

```sway
#[storage(read)]
fn check_if_admin(admin: Identity) {
    let status = is_admin(admin);
    assert(status);
}
```


---

### File: docs/nightly/sway-libs/docs/book/src/asset/base.md

# Base Functionality

For implementation details on the Asset Library base functionality please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/base/index.html).

## Importing the Asset Library Base Functionality

In order to use base functionality the Asset Library, the Asset Library and the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Asset Library and the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add asset@0.26.0
forc add src20@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Asset Library Base Functionality and [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use asset::base::*;
use src20::*;
```

## Integration with the SRC-20 Standard

The [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) definition states that the following abi implementation is required for any Native Asset on Fuel:

```sway
abi SRC20 {
    #[storage(read)]
    fn total_assets() -> u64;
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64>;
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8>;
}
```

The Asset Library has the following complimentary functions for each function in the `SRC20` abi:

- `_total_assets()`
- `_total_supply()`
- `_name()`
- `_symbol()`
- `_decimals()`

The following ABI and functions are also provided to set your [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard storage values:

```sway
abi SetAssetAttributes {
    #[storage(write)]
    fn set_name(asset: AssetId, name: String);
    #[storage(write)]
    fn set_symbol(asset: AssetId, symbol: String);
    #[storage(write)]
    fn set_decimals(asset: AssetId, decimals: u8);
}
```

- `_set_name()`
- `_set_symbol()`
- `_set_decimals()`

> **NOTE** The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions will set the attributes of an asset *unconditionally*. External checks should be applied to restrict the setting of attributes.

## Setting Up Storage

Once imported, the Asset Library's base functionality should be available. To use them, be sure to add the storage block below to your contract which enables the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard.

```sway
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}
```

## Implementing the SRC-20 Standard with the Asset Library

To use the Asset Library's base functionly, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard in combination with the Asset Library with no user defined restrictions or custom functionality.

```sway
use asset::base::{_decimals, _name, _symbol, _total_assets, _total_supply};
use src20::SRC20;
use std::{hash::Hash, storage::storage_string::*, string::String};

// The SRC-20 storage block
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

// Implement the SRC-20 Standard for this contract
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        // Pass the `total_assets` StorageKey to `_total_assets()` from the Asset Library.
        _total_assets(storage.total_assets)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        // Pass the `total_supply` StorageKey to `_total_supply()` from the Asset Library.
        _total_supply(storage.total_supply, asset)
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        // Pass the `name` StorageKey to `_name_()` from the Asset Library.
        _name(storage.name, asset)
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        // Pass the `symbol` StorageKey to `_symbol_()` function from the Asset Library.
        _symbol(storage.symbol, asset)
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        // Pass the `decimals` StorageKey to `_decimals_()` function from the Asset Library.
        _decimals(storage.decimals, asset)
    }
}
```

## Setting an Asset's SRC-20 Attributes

To set some the asset attributes for an Asset, use the `SetAssetAttributes` ABI provided by the Asset Library. The example below shows the implementation of the `SetAssetAttributes` ABI with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetAttributes` ABI to ensure only a single user has permissions to set an Asset's attributes.

The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions follows the SRC-20 standard for logging and will emit their respective log when called.

```sway
use asset::base::*;
use std::{hash::Hash, storage::storage_string::*, string::String};

storage {
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SetAssetAttributes for Contract {
    #[storage(write)]
    fn set_name(asset: AssetId, name: String) {
        _set_name(storage.name, asset, name);
    }

    #[storage(write)]
    fn set_symbol(asset: AssetId, symbol: String) {
        _set_symbol(storage.symbol, asset, symbol);
    }

    #[storage(write)]
    fn set_decimals(asset: AssetId, decimals: u8) {
        _set_decimals(storage.decimals, asset, decimals);
    }
}
```

> **NOTE** The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions will set the attributes of an asset *unconditionally*. External checks should be applied to restrict the setting of attributes.


---

### File: docs/nightly/sway-libs/docs/book/src/asset/index.md

# Asset Library

The Asset Library provides basic helper functions for the [SRC-20; Native Asset Standard](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/), [SRC-3; Mint and Burn Standard](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/), and the [SRC-7; Arbitrary Asset Metadata Standard](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/). It is intended to make development of Native Assets using Sway quick and easy while following the standard's specifications.

For implementation details on the Asset Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/).

## [SRC-20 Functionality](./base.md)

The Base or core of any Asset on the Fuel Network must follow the [SRC-20; Native Asset Standard](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/). The Asset Library's [Base](./base.md) section supports the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/)'s implementation.

## [SRC-3 Functionality](supply.md)

The [SRC-3; Mint and Burn Standard](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) prescribes an ABI for how Native Assets on the Fuel Network are minted and burned. The Asset Library's [supply](./supply.md) section supports the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/)'s implementation.

## [SRC-7 Functionality](./metadata.md)

The [SRC-7; Onchain Asset Metadata Standard](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) prescribes an ABI for stateful metadata associated with Native Assets on the Fuel Network. The Asset Library's [metadata](./metadata.md) section supports the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/)'s implementation.


---

### File: docs/nightly/sway-libs/docs/book/src/asset/metadata.md

# Metadata Functionality

For implementation details on the Asset Library metadata functionality please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/metadata/index.html).

## Importing the Asset Library Metadata Functionality

In order to use metadata functionality the Asset Library, the Asset Library and the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Asset Library and the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add asset@0.26.0
forc add src7@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Asset Library Base Functionality and [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use asset::metadata::{_metadata, _set_metadata, SetAssetMetadata, StorageMetadata};
use src7::*;
```

## Integration with the SRC-7 Standard

The [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) definition states that the following abi implementation is required for any Native Asset on Fuel which uses stateful metadata:

```sway
abi SRC7 {
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata>;
}
```

The Asset Library has the following complimentary data type for the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard:

- `StorageMetadata`

## Setting Up Storage

Once imported, the Asset Library's metadata functionality should be available. To use them, be sure to add the storage block below to your contract which enables the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard.

```sway
storage {
    metadata: StorageMetadata = StorageMetadata {},
}
```

## Using the `StorageMetadata` Type

### Setting Metadata

As described in the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard, the metadata type is a simple enum of the following types:

- `b256`
- `Bytes`
- `u64`
- `String`

To set some metadata of any of the above types for an Asset, you can use the `SetAssetMetadata` ABI provided by the Asset Library with the `_set_metadata()` function. Be sure to follow the [SRC-9](https://docs.fuel.network/docs/sway-standards/src-9-metadata-keys/) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetMetadata` ABI to ensure only a single user has permissions to set an Asset's metadata.

The `_set_metadata()` function follows the SRC-7 standard for logging and will emit the `SetMetadataEvent` when called.

```sway
use asset::metadata::*;
use src7::Metadata;

storage {
    metadata: StorageMetadata = StorageMetadata {},
}

impl SetAssetMetadata for Contract {
    #[storage(read, write)]
    fn set_metadata(asset: AssetId, key: String, metadata: Metadata) {
        // add your authentication logic here
        // eg. only_owner()
        _set_metadata(storage.metadata, asset, key, metadata);
    }
}
abi CustomSetAssetMetadata {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    );
}

impl CustomSetAssetMetadata for Contract {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    ) {
        let b256_metadata = Metadata::B256(bits256);
        let bytes_metadata = Metadata::Bytes(bytes);
        let int_metadata = Metadata::Int(int);
        let string_metadata = Metadata::String(string);

        // your authentication logic here

        // set whichever metadata you want
        storage.metadata.insert(asset, key, string_metadata);
    }
}
```

> **NOTE** The `_set_metadata()` function will set the metadata of an asset *unconditionally*. External checks should be applied to restrict the setting of metadata.

To set the metadata of an Asset, using only one of the above types, you can define a custom ABI and use it as such:

```sway
abi CustomSetAssetMetadata {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    );
}

impl CustomSetAssetMetadata for Contract {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    ) {
        let b256_metadata = Metadata::B256(bits256);
        let bytes_metadata = Metadata::Bytes(bytes);
        let int_metadata = Metadata::Int(int);
        let string_metadata = Metadata::String(string);

        // your authentication logic here

        // set whichever metadata you want
        storage.metadata.insert(asset, key, string_metadata);
    }
}
```

> **NOTE** The `_set_metadata()` function will set the metadata of an asset *unconditionally*. External checks should be applied to restrict the setting of metadata.

### Implementing the SRC-7 Standard with StorageMetadata

To use the `StorageMetadata` type, simply get the stored metadata with the associated `key` and `AssetId` using the provided `_metadata()` convenience function. The example below shows the implementation of the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard in combination with the Asset Library's `StorageMetadata` type and the `_metadata()` function with no user defined restrictions or custom functionality.

```sway
use asset::metadata::*;
use src7::{Metadata, SRC7};

storage {
    metadata: StorageMetadata = StorageMetadata {},
}

// Implement the SRC-7 Standard for this contract
impl SRC7 for Contract {
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        // Return the stored metadata
        storage.metadata.get(asset, key)
    }
}
```

### Getting Metadata

To get the metadata for an asset, apart from the above mentioned `_metadata()` convenience function, you can also use the `get()` method on the `StorageMetadata` type, which returns the `Metadata` type.

```sway
    use asset::metadata::*; // To access trait implementations you must import everything using the glob operator.
    let metadata: Option<Metadata> = storage.metadata.get(asset, key);
    match metadata.unwrap() {
        Metadata::B256(b256) => {
        // do something with b256
},
        Metadata::Bytes(bytes) => {
        // do something with bytes
},
        Metadata::Int(int) => {
        // do something with int
},
        Metadata::String(string) => {
        // do something with string
},
    }
    let metadata: Metadata = storage.metadata.get(asset, key).unwrap();

    if metadata.is_b256() {
        let b256: b256 = metadata.as_b256().unwrap();
        // do something with b256
    } else if metadata.is_bytes() {
        let bytes: Bytes = metadata.as_bytes().unwrap();
        // do something with bytes
    } else if metadata.is_u64() {
        let int: u64 = metadata.as_u64().unwrap();
        // do something with int
    } else if metadata.is_string() {
        let string: String = metadata.as_string().unwrap();
        // do something with string
    }
```

This results an `Option` type as the metadata may not be set for the asset and key combination.

If you know that the metadata is set, but you don't know the type, you can use a match statement to access the metadata.

```sway
    match metadata.unwrap() {
        Metadata::B256(b256) => {
        // do something with b256
},
        Metadata::Bytes(bytes) => {
        // do something with bytes
},
        Metadata::Int(int) => {
        // do something with int
},
        Metadata::String(string) => {
        // do something with string
},
    }
```

If you know that the metadata is set and you know the type, you can use the `as_*` methods to access the metadata. We also provide `is_*` methods to check if the metadata is of a specific type.

```sway
    let metadata: Metadata = storage.metadata.get(asset, key).unwrap();

    if metadata.is_b256() {
        let b256: b256 = metadata.as_b256().unwrap();
        // do something with b256
    } else if metadata.is_bytes() {
        let bytes: Bytes = metadata.as_bytes().unwrap();
        // do something with bytes
    } else if metadata.is_u64() {
        let int: u64 = metadata.as_u64().unwrap();
        // do something with int
    } else if metadata.is_string() {
        let string: String = metadata.as_string().unwrap();
        // do something with string
    }
```


---

### File: docs/nightly/sway-libs/docs/book/src/asset/supply.md

# Supply Functionality

For implementation details on the Asset Library supply functionality please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/supply/index.html).

## Importing the Asset Library Supply Functionality

In order to use the supply functionality of the Asset Library, the Asset Library and the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Asset Library and the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add asset@0.8.0
forc add src3@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Asset Library Supply Functionality and [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use asset::supply::*;
use src3::*;
```

## Integration with the SRC-3 Standard

The [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) definition states that the following abi implementation is required for any Native Asset on Fuel which mints and burns tokens:

```sway
abi SRC3 {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64);
    #[payable]
    #[storage(read, write)]
    fn burn(vault_sub_id: SubId, amount: u64);
}
```

The Asset Library has the following complimentary functions for each function in the `SRC3` abi:

- `_mint()`
- `_burn()`

> **NOTE** The `_mint()` and `_burn()` functions will mint and burn assets *unconditionally*. External checks should be applied to restrict the minting and burning of assets.

## Setting Up Storage

Once imported, the Asset Library's supply functionality should be available. To use them, be sure to add the storage block below to your contract which enables the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard.

```sway
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}
```

## Implementing the SRC-3 Standard with the Asset Library

To use either function, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard in combination with the Asset Library with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the Asset Library's supply functionality to ensure only a single user has permissions to mint an Asset.

The `_mint()` and `_burn()` functions follows the SRC-20 standard for logging and will emit the `TotalSupplyEvent` when called.

```sway
use asset::supply::{_burn, _mint};
use src3::SRC3;

storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}

// Implement the SRC-3 Standard for this contract
impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        // Pass the StorageKeys to the `_mint()` function from the Asset Library.
        _mint(
            storage
                .total_assets,
            storage
                .total_supply,
            recipient,
            sub_id
                .unwrap_or(b256::zero()),
            amount,
        );
    }

    // Pass the StorageKeys to the `_burn_()` function from the Asset Library.
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        _burn(storage.total_supply, sub_id, amount);
    }
}
```

> **NOTE** The `_mint()` and `_burn()` functions will mint and burn assets *unconditionally*. External checks should be applied to restrict the minting and burning of assets.


---

### File: docs/nightly/sway-libs/docs/book/src/bigint/index.md

# Big Integers Library

<!--Include BigInt when BigInt is available-->
The Big Integers library provides a library to use extremely large numbers in Sway. It has 1 distinct types: `BigUint`. These types are heap allocated.

Internally the library uses the `Vec<u64>` type to represent the underlying values of the big integers.

For implementation details on the Big Integers Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/big_int/big_int/).

## Importing the Big Integers Library

In order to use the Big Integers Library, the Big Integers Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Big Integers Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add big_int@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Big Integers Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use big_int::*;
use big_int::BigUint;
```

In order to use any of the Big Integer types, import them into your Sway project like so:

```sway
use big_int::BigUint;
```

## Basic Functionality

<!--Uncomment when BigInt is available-->
<!--All the functionality is demonstrated with the `BigUint` type, but all of the same functionality is available for the other types as well.-->

### Minimum and Maximum Values

For the `BigUint` type, the minimum value is zero. There is no maximum value and the `BigUint` will grow to accommodate as large of a number as needed.

### Instantiating a Big Integer

#### Zero value

Once imported, a `Big Integer` type can be instantiated defining a new variable and calling the `new` function.

```sway
    let mut big_int = BigUint::new();
```

this newly initialized variable represents the value of `0`.

The `new` function is functionally equivalent to the `zero` function.

```sway
    let zero = BigUint::zero();
```

<!--#### Positive and Negative Values

As the signed variants can only represent half as high a number as the unsigned variants (but with either a positive or negative sign), the `try_from` and `neg_try_from` functions will only work with half of the maximum value of the unsigned variant.

You can use the `try_from` function to create a new positive `Big Integer` from a its unsigned variant.

```sway
[Snippet for positive_conversion not found]
```

You can use the `neg_try_from` function to create a new negative `Big Integer` from a its unsigned variant.

```sway
[Snippet for negative_conversion not found]
```
-->

### Basic Mathematical Functions

Basic arithmetic operations are working as usual.

```sway
    let big_uint_1 = BigUint::from(1u64);
    let big_uint_2 = BigUint::from(2u64);

    // Add
    let result: BigUint = big_uint_1 + big_uint_2;

    // Multiply
    let result: BigUint = big_uint_1 * big_uint_2;

    // Subtract
    let result: BigUint = big_uint_2 - big_uint_1;

    // Eq
    let result: bool = big_uint_1 == big_uint_2;

    // Ord
    let result: bool = big_uint_1 < big_uint_2;
```

#### Checking if a Big Integer is Zero

The library also provides a helper function to easily check if a `Big Integer` is zero.

```sway
fn is_zero() {
    let big_int = BigUint::zero();
    assert(big_int.is_zero());
}
```

### Type Conversions

The Big Integers Library offers a number of different conversions between mathematical types. These include the following:

- `u8`
- `u16`
- `u32`
- `u64`
- `U128`
- `u256`
- `Bytes`

To convert any of the above type to a Big Integer, you may use the `From` implementation.

```sway
    // u8
    let u8_big_int = BigUint::from(u8::max());

    // u16
    let u16_big_int = BigUint::from(u16::max());

    // u32
    let u32_big_int = BigUint::from(u32::max());

    // u64
    let u64_big_int = BigUint::from(u64::max());

    // U128
    let u128_big_int = BigUint::from(U128::max());

    // u256
    let u256_big_int = BigUint::from(u256::max());

    // Bytes
    let bytes_big_int = BigUint::from(Bytes::new());
```

To convert back to any of the above types, the `TryInto` implementation will be needed. If the Bit Integer does not fit into the conversion type, `None` will be returned.

```sway
    let big_uint = BigUint::zero();

    // u8
    let u8_result: Option<u8> = <BigUint as TryInto<u8>>::try_into(big_uint);

    // u16
    let u16_result: Option<u16> = <BigUint as TryInto<u16>>::try_into(big_uint);

    // u32
    let u32_result: Option<u32> = <BigUint as TryInto<u32>>::try_into(big_uint);

    // u64
    let u64_result: Option<u64> = <BigUint as TryInto<u64>>::try_into(big_uint);

    // U128
    let u128_big_int: Option<U128> = <BigUint as TryInto<U128>>::try_into(big_uint);

    // u256
    let u256_big_int: Option<u256> = <BigUint as TryInto<u256>>::try_into(big_uint);
```

The only exception is the `Bytes` type, which uses `Into`.

```sway
    // Bytes
    let bytes_big_int: Bytes = <BigUint as Into<Bytes>>::into(big_uint);
```

### Underlying Values

As mentioned previously, the big integers are internally represented by a `Vec<u64>`. To introspect these underlying values you may either get a copy of the data, inspect individual elements, or get the length.

To get a copy of the underlying data, you may call the `limbs()` function. Please note that modifying the copy will have no impact on the Big Integer.

```sway
    let limbs: Vec<u64> = big_int.limbs();
```

To introspect an individual element, you may use the `get_limb()` function.

```sway
    let limb: Option<u64> = big_int.get_limb(0);
```

To get the length of the underlying `Vec<u64>`, call the `number_of_limbs()` function.

```sway
    let number_of_limbs: u64 = big_int.number_of_limbs();
```

And to check whether two Big Integers have the same number of limbs, you may use the `equal_limb_size()` function.

```sway
    let result: bool = big_int_1.equal_limb_size(big_int_2);
```


---

### File: docs/nightly/sway-libs/docs/book/src/bytecode/index.md

# Bytecode Library

The Bytecode Library allows for on-chain verification and computation of bytecode roots for contracts and predicates.

A bytecode root for a contract and predicate is the Merkle root of the [binary Merkle tree](https://github.com/FuelLabs/fuel-specs/blob/master/src/protocol/cryptographic-primitives.md#binary-merkle-tree) with each leaf being 16KiB of instructions. This library will compute any contract's or predicate's bytecode root/address allowing for the verification of deployed contracts and generation of predicate addresses on-chain.

For implementation details on the Bytecode Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/bytecode/bytecode/).

## Importing the Bytecode Library

In order to use the Bytecode Library, the Bytecode Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Bytecode Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add bytecode@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Bytecode Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use bytecode::*;
```

## Using the Bytecode Library In Sway

Once imported, using the Bytecode Library is as simple as calling the desired function. Here is a list of function definitions that you may use.

- `compute_bytecode_root()`
- `compute_predicate_address()`
- `predicate_address_from_root()`
- `swap_configurables()`
- `verify_contract_bytecode()`
- `verify_predicate_address()`

## Known Issues

Please note that if you are passing the bytecode from the SDK and are including configurable values, the `Vec<u8>` bytecode provided must be copied to be mutable. The following can be added to make your bytecode mutable:

```sway
fn make_mutable(not_mutable_bytecode: Vec<u8>) {
    // Copy the bytecode to a newly allocated memory to avoid memory ownership error.
    let mut bytecode_slice = raw_slice::from_parts::<u8>(
        alloc_bytes(not_mutable_bytecode.len()),
        not_mutable_bytecode
            .len(),
    );
    not_mutable_bytecode
        .ptr()
        .copy_bytes_to(bytecode_slice.ptr(), not_mutable_bytecode.len());
    let mut bytecode_vec = Vec::from(bytecode_slice);
    // You may now use `bytecode_vec` in your computation and verification function calls
}
```

## Basic Functionality

The examples below are intended for internal contract calls. If you are passing bytecode from the SDK, please follow the steps listed above in known issues to avoid the memory ownership error.

## Swapping Configurables

Given some bytecode, you may swap the configurables of both Contracts and Predicates by calling the `swap_configurables()` function.

```sway
fn swap(
    my_bytecode: Vec<u8>,
    my_configurables: ContractConfigurables,
) {
    let mut my_bytecode = my_bytecode;
    let resulting_bytecode: Vec<u8> = swap_configurables(my_bytecode, my_configurables);
}
```

## Contracts

### Computing the Bytecode Root

To compute a contract's bytecode root you may call the `compute_bytecode_root()` function.

```sway
fn compute_bytecode(
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    let root: BytecodeRoot = compute_bytecode_root(my_bytecode, my_configurables);
}
```

### Verifying a Contract's Bytecode Root

To verify a contract's bytecode root you may call `verify_bytecode_root()` function.

```sway
fn verify_contract(
    my_contract: ContractId,
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    verify_contract_bytecode(my_contract, my_bytecode, my_configurables);
    // By reaching this line the contract has been verified to match the bytecode provided.
}
```

## Predicates

### Computing the Address from Bytecode

To compute a predicate's address you may call the `compute_predicate_address()` function.

```sway
fn compute_predicate(
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    let address: Address = compute_predicate_address(my_bytecode, my_configurables);
}
```

### Computing the Address from a Root

If you have the root of a predicate, you may compute it's corresponding predicate address by calling the `predicate_address_from_root()` function.

```sway
fn predicate_address(my_root: BytecodeRoot) {
    let address: Address = predicate_address_from_root(my_root);
}
```

### Verifying the Address

To verify a predicates's address you may call `verify_predicate_address()` function.

```sway
fn verify_predicate(
    my_predicate: Address,
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    verify_predicate_address(my_predicate, my_bytecode, my_configurables);
    // By reaching this line the predicate bytecode matches the address provided.
}
```


---

### File: docs/nightly/sway-libs/docs/book/src/getting_started/index.md

# Getting Started

## Adding Sway Libs as a Dependency

To import any library, a dependency should be added to the project's `Forc.toml` file under `[dependencies]`.

```sway
[dependencies]
example = "0.0.0"
```

The library you wish to use may be added as a dependency with the `forc add` command. For example, to import the Ownership Library, use the following `forc` command:

```bash
forc add ownership@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

## Importing Sway Libs to Your Project

Once Sway Libs is a dependency to your project, you may then import a library in your Sway Smart Contract as so:

```sway
use <library>::<library_function>;
```

For example, to import the `only_owner()` from the Ownership Library, use the following statement at the top of your Sway file:

```sway
use ownership::only_owner;
```

> **NOTE:**
> All projects currently use `forc v0.69.0`, `fuels-rs v0.70.0` and `fuel-core v0.44.0`.

## Using Sway Libs

Once the library you require has been imported to your project, you may call or use any functions and structures the library provides.

In the following example, we import the Pausable Library and implement the `Pausable` ABI with it's associated functions.

```sway
use pausable::{_is_paused, _pause, _unpause, Pausable};

// Implement the Pausable ABI for our contract
impl Pausable for Contract {
    #[storage(write)]
    fn pause() {
        _pause(); // Call the provided pause function.
    }

    #[storage(write)]
    fn unpause() {
        _unpause(); // Call the provided unpause function.
    }

    #[storage(read)]
    fn is_paused() -> bool {
        _is_paused() // Call the provided is paused function.
    }
}
```

Any instructions related to using a specific library should be found within the [libraries](../index.md) section of the Sway Libs Book.

<!--
Uncomment this when https://github.com/FuelLabs/sway/pull/7229 is merged.
For implementation details on the libraries please see the [Sway Libs Docs]().
-->


---

### File: docs/nightly/sway-libs/docs/book/src/getting_started/running_tests.md

# Running Tests

There are two sets of tests that should be run: inline tests and sdk-harness tests. Please make sure you are using `forc v0.63.3` and `fuel-core v0.34.0`. You can check what version you are using by running the `fuelup show` command.

Make sure you are in the source directory of this repository `sway-libs/<you are here>`.

Run the inline tests:

```bash
forc test --path libs --release --locked
```

Once these tests have passed, run the sdk-harness tests:

```bash
forc test --path tests --release --locked && cargo test --manifest-path tests/Cargo.toml
```

> **NOTE:**
> This may take a while depending on your hardware, future improvements to Sway will decrease build times. After this has been run once, individual test projects may be built on their own to save time.


---

### File: docs/nightly/sway-libs/docs/book/src/index.md

# Sway Libraries

The purpose of Sway Libraries is to contain libraries which users can import and use that are not part of the standard library.

There are several types of libraries that Sway Libs encompasses. These include libraries that provide convenience functions, [Sway-Standards](https://github.com/FuelLabs/sway-standards) supporting libraries, data type libraries, security functionality libraries, and other tools valuable to blockchain development.

<!--
Uncomment when https://github.com/FuelLabs/sway/pull/7229 is merged.
For implementation details on the libraries please see the [Sway Libs Docs]().
-->

## Assets Libraries

Asset Libraries are any libraries that use [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on the Fuel Network.

### [Asset Library](./asset/index.md)

The [Asset](./asset/index.md) Library provides helper functions for the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/), [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/), and [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standards.

## Access Control and Security Libraries

Access Control and Security Libraries are any libraries that are built and intended to provide additional safety when developing smart contracts.

### [Ownership Library](./ownership/index.md)

The [Ownership](./ownership/index.md) Library is used to apply restrictions on functions such that only a **single** user may call them.

### [Admin Library](./admin/index.md)

The [Admin](./admin/index.md) Library is used to apply restrictions on functions such that only a select few users may call them like a whitelist.

### [Pausable Library](./pausable/index.md)

The [Pausable](./pausable/index.md) Library allows contracts to implement an emergency stop mechanism.

### [Reentrancy Guard Library](./reentrancy/index.md)

The [Reentrancy Guard](./reentrancy/index.md) Library is used to detect and prevent reentrancy attacks.

## Cryptography Libraries

Cryptography Libraries are any libraries that provided cryptographic functionality beyond what the std-lib provides.

### [Bytecode Library](./bytecode/index.md)

The [Bytecode](./bytecode/index.md) Library is used for on-chain verification and computation of bytecode roots for contracts and predicates.

### [Merkle Library](./merkle/index.md)

The [Merkle Proof](./merkle/index.md) Library is used to verify Binary and Sparse Merkle Trees computed off-chain.

## Math Libraries

Math Libraries are libraries which provide mathematic functions or number types that are outside of the std-lib's scope.

### [Signed Integers](./signed_integers/index.md)

The [Signed Integers](./signed_integers/index.md) Library is an interface to implement signed integers.

### [Big Integers](./bigint/index.md)

The [Big Integers](./bigint/index.md) Library is an interface to implement extremely large integers.

## Data Structures Libraries

Data Structure Libraries are libraries which provide complex data structures which unlock additional functionality for Smart Contracts.

### [Queue](./queue/index.md)

The [Queue](./queue/index.md) Library is a linear data structure that provides First-In-First-Out (FIFO) operations.

## Upgradability Libraries

Upgradability Libraries are libraries which provide functions to implement contract upgrades.

### [Upgradability](./upgradability/index.md)

The [Upgradability](./upgradability/index.md) Library provides functions that can be used to implement contract upgrades via simple upgradable proxies.


---

### File: docs/nightly/sway-libs/docs/book/src/merkle/index.md

# Merkle Library

Merkle trees allow for on-chain verification of off-chain data. With the merkle root posted on-chain, the generation of proofs off-chain can provide verifiably true data.

The Merkle Library currently supports two different tree structures: Binary Trees and Sparse Trees. For information implementation specifications, please refer to the [Merkle Tree Specification](https://docs.fuel.network/docs/specs/protocol/cryptographic-primitives/#merkle-trees).

For implementation details on the Merkle Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/merkle/merkle/).

## Importing the Merkle Library

In order to use the Merkle Library, the Merkle Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Merkle Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add merkle@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Binary Merkle Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use merkle::binary::{leaf_digest, process_proof, verify_proof};
use merkle::common::{MerkleRoot, node_digest, ProofSet};
```

To import the Sparse Merkle Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use merkle::sparse::*;
use merkle::common::{MerkleRoot, ProofSet};
```

## Using the Binary Merkle Proof Library In Sway

Once imported, using the Binary Merkle Proof library is as simple as calling the desired function. Here is a list of function definitions that you may use.

- `leaf_digest()`
- `node_digest()`
- `process_proof()`
- `verify_proof()`

### Binary Sway Functionality

#### Computing Leaves and Nodes of a Binary Tree

The Binary Proof currently allows for you to compute leaves and nodes of a merkle tree given the appropriate hash digest.

To compute a leaf use the `leaf_digest()` function:

```sway
fn compute_leaf(hashed_data: b256) {
    let leaf: b256 = leaf_digest(hashed_data);
}
```

To compute a node given two leaves, use the `node_digest()` function:

```sway
fn compute_node(leaf_a: b256, leaf_b: b256) {
    let node: b256 = node_digest(leaf_a, leaf_b);
}
```

> **NOTE** Order matters when computing a node.

#### Computing the Merkle Root of a Binary Tree

To compute a Merkle root given a proof, use the `process_proof()` function.

```sway
fn process(key: u64, leaf: b256, num_leaves: u64, proof: ProofSet) {
    let merkle_root: MerkleRoot = process_proof(key, leaf, num_leaves, proof);
}
```

#### Verifying the Proof of a Binary Tree

To verify a proof against a merkle root, use the `verify_proof()` function.

```sway
fn verify(
    merkle_root: MerkleRoot,
    key: u64,
    leaf: b256,
    num_leaves: u64,
    proof: ProofSet,
) {
    assert(verify_proof(key, leaf, merkle_root, num_leaves, proof));
}
```

### Using the Binary Merkle Proof Library with Fuels-rs

To generate a Binary Merkle Tree and corresponding proof for your Sway Smart Contract, use the [Fuel-Merkle](https://github.com/FuelLabs/fuel-vm/tree/master/fuel-merkle) crate.

#### Importing Binary Into Your Project

To import the Fuel-Merkle crate, the following should be added to the project's `Cargo.toml` file under `[dependencies]`:

```sway
fuel-merkle = { version = "0.56.0" }
```

> **NOTE** Make sure to use the latest version of the [fuel-merkle](https://crates.io/crates/fuel-merkle) crate.

#### Importing Binary Into Your Rust File

The following should be added to your Rust file to use the Fuel-Merkle crate.

```rust
use fuel_merkle::binary::in_memory::MerkleTree;
```

#### Using Fuel-Merkle's Binary Tree

##### Generating A Binary Tree

To create a merkle tree using Fuel-Merkle is as simple as pushing your leaves in increasing order.

```rust
    // Create a new Merkle Tree and define leaves
    let mut tree = MerkleTree::new();
    let leaves = [b"A", b"B", b"C"].to_vec();

    // Hash the leaves and then push to the merkle tree
    for datum in &leaves {
        let mut hasher = Sha256::new();
        hasher.update(datum);
        let hash = hasher.finalize();
        tree.push(&hash);
    }
```

##### Generating And Verifying A Binary Proof

To generate a proof for a specific leaf, you must have the index or key of the leaf. Simply call the prove function:

```rust
    // Define the key or index of the leaf you want to prove and the number of leaves
    let key: u64 = 0;

    // Get the merkle root and proof set
    let (merkle_root, proof_set) = tree.prove(key).unwrap();

    // Convert the proof set from Vec<Bytes32> to Vec<Bits256>
    let mut bits256_proof: Vec<Bits256> = Vec::new();
    for itterator in proof_set {
        bits256_proof.push(Bits256(itterator));
    }
```

Once the proof has been generated, you may call the Sway Smart Contract's `verify_proof` function:

```rust
    // Create the merkle leaf
    let mut leaf_hasher = Sha256::new();
    leaf_hasher.update(leaves[key as usize]);
    let hashed_leaf_data = leaf_hasher.finalize();
    let merkle_leaf = leaf_sum(&hashed_leaf_data);

    // Get the number of leaves or data points
    let num_leaves: u64 = leaves.len() as u64;

    // Call the Sway contract to verify the generated merkle proof
    let result: bool = contract_instance
        .methods()
        .verify(
            Bits256(merkle_root),
            key,
            Bits256(merkle_leaf),
            num_leaves,
            bits256_proof,
        )
        .call()
        .await
        .unwrap()
        .value;
    assert!(result);
```

## Using the Sparse Merkle Proof Library In Sway

Once imported, using the Sparse Merkle Proof library is as simple as calling the desired function on the `Proof` type. Here is a list of function definitions that you may use.

- `root()`
- `verify()`

To explore additional utility and support functions available, please check out the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/merkle/merkle/).

### Sparse Sway Functionality

#### Computing the Merkle Root of a Sparse Tree

To compute a Sparse Merkle root given a proof, use the `root()` function. You must provide the appropriate `MerkleTreeKey` and leaf data. Please note that the leaf data should be `Some` if you are proving an inclusion proof, and `None` if your are proving an exclusion proof.

```sway
fn compute_root(key: MerkleTreeKey, leaf: Option<Bytes>, proof: Proof) {
    let merkle_root: MerkleRoot = proof.root(key, leaf);
}
```

#### Verifying the Proof of a Sparse Tree

To verify a proof against a merkle root, use the `verify()` function. You must provide the appropriate `MerkleTreeKey`, `MerkleRoot`, and leaf data. Please note that the leaf data should be `Some` if you are proving an inclusion proof, and `None` if your are proving an exclusion proof.

```sway
fn verify_proof(
    root: MerkleRoot,
    key: MerkleTreeKey,
    leaf: Option<Bytes>,
    proof: Proof,
) {
    let result: bool = proof.verify(root, key, leaf);
    assert(result);
}
```

#### Verifying an Inclusion Proof with Hashed Data

If you would like to verify an inclusion proof using only the SHA256 hash of the leaf data rather than the entire `Bytes`, you may do so as shown:

```sway
fn inclusion_proof_hash(key: MerkleTreeKey, leaf: b256, proof: Proof) {
    assert(proof.is_inclusion());

    // Compute the merkle root of an inclusion proof using the sha256 hash of the leaf
    let root: MerkleRoot = proof.as_inclusion().unwrap().root_from_hash(key, leaf);

    // Verifying an inclusion proof using the sha256 hash of the leaf
    let result: bool = proof.as_inclusion().unwrap().verify_hash(root, key, leaf);
    assert(result);
}
```

### Using the Sparse Merkle Proof Library with Fuels-rs

To generate a Sparse Merkle Tree and corresponding proof for your Sway Smart Contract, use the [Fuel-Merkle](https://github.com/FuelLabs/fuel-vm/tree/master/fuel-merkle) crate.

#### Importing Sparse Tree Into Your Project

To import the Fuel-Merkle crate, the following should be added to the project's `Cargo.toml` file under `[dependencies]`:

```sway
fuel-merkle = { version = "0.56.0" }
```

> **NOTE** Make sure to use the latest version of the [fuel-merkle](https://crates.io/crates/fuel-merkle) crate.

#### Importing Sparse Tree Into Your Rust File

The following should be added to your Rust file to use the Fuel-Merkle crate.

```rust
use fuel_merkle::sparse::in_memory::MerkleTree as SparseTree;
use fuel_merkle::sparse::proof::ExclusionLeaf as FuelExclusionLeaf;
use fuel_merkle::sparse::proof::Proof as FuelProof;
use fuel_merkle::sparse::MerkleTreeKey as SparseTreeKey;
use fuels::types::{Bits256, Bytes};
```

#### Using Fuel-Merkle's Sparse Tree

##### Generating A Sparse Tree

To create a merkle tree using Fuel-Merkle is as simple as pushing your leaves in increasing order.

```rust
    // Create a new Merkle Tree and define leaves
    let mut tree = SparseTree::new();
    let leaves = ["A", "B", "C"].to_vec();
    let leaf_to_prove = "A";
    let key = SparseTreeKey::new(leaf_to_prove);

    // Hash the leaves and then push to the merkle tree
    for datum in &leaves {
        let _ = tree.update(SparseTreeKey::new(datum), datum.as_bytes());
    }
```

##### Generating And Verifying A Sparse Proof

To generate a proof for a specific leaf, you must have the index or key of the leaf. Simply call the prove function:

```rust
    // Get the merkle root and proof set
    let root = tree.root();
    let fuel_proof: FuelProof = tree.generate_proof(&key).unwrap();

    // Convert the proof from a FuelProof to the Sway Proof
    let sway_proof: Proof = fuel_to_sway_sparse_proof(fuel_proof);
```

Once the proof has been generated, you may call the Sway Smart Contract's `verify_proof` function:

```rust
    // Call the Sway contract to verify the generated merkle proof
    let result: bool = contract_instance
        .methods()
        .verify(
            Bits256(root),
            Bits256(*key),
            Some(Bytes(leaves[0].into())),
            sway_proof,
        )
        .call()
        .await
        .unwrap()
        .value;

    assert!(result);
```

##### Converting from a Fuel Proof to a Sway Proof

The Rust SDK does not currently support the `Proof` type in Sway and will conflict with the `Proof` type in fuel-merkle. Therefore, you MUST import the `Proof` type from fuel-merkle as `FuelProof`.

To convert between the two types, you may use the following function:

```rust
pub fn fuel_to_sway_sparse_proof(fuel_proof: FuelProof) -> Proof {
    let mut proof_bits: Vec<Bits256> = Vec::new();
    for iterator in fuel_proof.proof_set().iter() {
        proof_bits.push(Bits256(iterator.clone()));
    }

    match fuel_proof {
        FuelProof::Exclusion(exlcusion_proof) => Proof::Exclusion(ExclusionProof {
            proof_set: proof_bits,
            leaf: match exlcusion_proof.leaf {
                FuelExclusionLeaf::Leaf(leaf_data) => ExclusionLeaf::Leaf(ExclusionLeafData {
                    leaf_key: Bits256(leaf_data.leaf_key),
                    leaf_value: Bits256(leaf_data.leaf_value),
                }),
                FuelExclusionLeaf::Placeholder => ExclusionLeaf::Placeholder,
            },
        }),
        FuelProof::Inclusion(_) => Proof::Inclusion(InclusionProof {
            proof_set: proof_bits,
        }),
    }
}
```


---

### File: docs/nightly/sway-libs/docs/book/src/ownership/index.md

# Ownership Library

The **Ownership Library** provides a straightforward way to restrict specific calls in a Sway contract to a single _owner_. Its design follows the [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) standard from [Sway Standards](https://docs.fuel.network/docs/sway-standards/) and offers a set of functions to initialize, verify, revoke, and transfer ownership.

For implementation details, visit the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/ownership/ownership/).

## Importing the Ownership Library

In order to use the Ownership Library, the Ownership Library and the [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Ownership Library and the [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add ownership@0.26.0
forc add src5@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Ownership Library and [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use ownership::*;
use src5::*;
```

## Integrating the Ownership Library into the SRC-5 Standard

When integrating the Ownership Library with [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/), ensure that the `SRC5` trait from **Sway Standards** is implemented in your contract, as shown below. The `_owner()` function from this library is used to fulfill the SRC-5 requirement of exposing the ownership state.

```sway
use ownership::_owner;
use src5::{SRC5, State};

impl SRC5 for Contract {
    #[storage(read)]
    fn owner() -> State {
        _owner()
    }
}
```

## Basic Usage

### Setting a Contract Owner

Establishes the initial ownership state by calling `initialize_ownership(new_owner)`. This can only be done once, typically in your contract's constructor.

```sway
#[storage(read, write)]
fn my_constructor(new_owner: Identity) {
    initialize_ownership(new_owner);
}
```

Please note that the example above does not apply any restrictions on who may call the `initialize()` function. This leaves the opportunity for a bad actor to front-run your contract and claim ownership for themselves. To ensure the intended `Identity` is set as the contract owner upon contract deployment, use a `configurable` where the `INITIAL_OWNER` is the intended owner of the contract.

```sway
configurable {
    INITAL_OWNER: Identity = Identity::Address(Address::zero()),
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn initialize() {
        initialize_ownership(INITAL_OWNER);
    }
}
```

### Applying Restrictions

Protect functions so only the owner can call them by invoking `only_owner()` at the start of those functions.

```sway
#[storage(read)]
fn only_owner_may_call() {
    only_owner();
    // Only the contract's owner may reach this line.
}
```

### Checking the Ownership Status

To retrieve the current ownership state, call `_owner()`.

```sway
#[storage(read)]
fn get_owner_state() {
    let owner: State = _owner();
}
```

### Transferring Ownership

To transfer ownership from the current owner to a new owner, call `transfer_ownership(new_owner)`.

```sway
#[storage(read, write)]
fn transfer_contract_ownership(new_owner: Identity) {
    // The caller must be the current owner.
    transfer_ownership(new_owner);
}
```

### Renouncing Ownership

To revoke ownership entirely and disallow the assignment of a new owner, call `renounce_ownership()`.

```sway
#[storage(read, write)]
fn renounce_contract_owner() {
    // The caller must be the current owner.
    renounce_ownership();
    // Now no one owns the contract.
}
```

## Events

### `OwnershipRenounced`

Emitted when ownership is revoked.

- **Fields:**
  - `previous_owner`: Identity of the owner prior to revocation.

### `OwnershipSet`

Emitted when initial ownership is set.

- **Fields:**
  - `new_owner`: Identity of the newly set owner.

### `OwnershipTransferred`

Emitted when ownership is transferred from one owner to another.

- **Fields:**
  - `new_owner`: Identity of the new owner.
  - `previous_owner`: Identity of the prior owner.

## Errors

### `InitializationError`

- **Variants:**
  - `CannotReinitialized`: Thrown when attempting to initialize ownership if the owner is already set.

### `AccessError`

- **Variants:**
  - `NotOwner`: Thrown when a function restricted to the owner is called by a non-owner.

## Example Integration

Below is a example illustrating how to use this library within a Sway contract:

```sway
contract;

use ownership::{_owner, initialize_ownership, only_owner, renounce_ownership, transfer_ownership};
use src5::{SRC5, State};

configurable {
    INITAL_OWNER: Identity = Identity::Address(Address::zero()),
}

impl SRC5 for Contract {
    #[storage(read)]
    fn owner() -> State {
        _owner()
    }
}

abi MyContract {
    #[storage(read, write)]
    fn initialize();
    #[storage(read)]
    fn restricted_action();
    #[storage(read, write)]
    fn change_owner(new_owner: Identity);
    #[storage(read, write)]
    fn revoke_ownership();
    #[storage(read)]
    fn get_current_owner() -> State;
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn initialize() {
        initialize_ownership(INITAL_OWNER);
    }

    // A function restricted to the owner
    #[storage(read)]
    fn restricted_action() {
        only_owner();
        // Protected action
    }

    // Transfer ownership
    #[storage(read, write)]
    fn change_owner(new_owner: Identity) {
        transfer_ownership(new_owner);
    }

    // Renounce ownership
    #[storage(read, write)]
    fn revoke_ownership() {
        renounce_ownership();
    }

    // Get current owner state
    #[storage(read)]
    fn get_current_owner() -> State {
        _owner()
    }
}
```

1. **Initialization:** Call `constructor(new_owner)` once to set the initial owner.  
2. **Restricted Calls:** Use `only_owner()` to guard any owner-specific functions.  
3. **Ownership Checks:** Retrieve the current owner state via `_owner()`.  
4. **Transfer or Renounce:** Use `transfer_ownership(new_owner)` or `renounce_ownership()` for ownership modifications.


---

### File: docs/nightly/sway-libs/docs/book/src/pausable/index.md

# Pausable Library

The Pausable library allows contracts to implement an emergency stop mechanism. This can be useful for scenarios such as having an emergency switch to freeze all transactions in the event of a large bug.

It is highly encouraged to use the [Ownership Library](../ownership/index.md) in combination with the Pausable Library to ensure that only a single administrative user has the ability to pause your contract.

For implementation details on the Pausable Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/pausable/pausable/).

## Importing the Pausable Library

In order to use the Pausable library, the Pausable Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Pausable Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add pausable@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Pausable Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use pausable::*;
```

## Basic Functionality

### Implementing the `Pausable` abi

The Pausable Library has two states:

- `Paused`
- `Unpaused`

By default, your contract will start in the `Unpaused` state. To pause your contract, you may call the `_pause()` function. The example below provides a basic pausable contract using the Pausable Library's `Pausable` abi without any restrictions such as an administrator.

```sway
use pausable::{_is_paused, _pause, _unpause, Pausable};

impl Pausable for Contract {
    #[storage(write)]
    fn pause() {
        _pause();
    }

    #[storage(write)]
    fn unpause() {
        _unpause();
    }

    #[storage(read)]
    fn is_paused() -> bool {
        _is_paused()
    }
}
```

## Applying Paused Restrictions

When developing a contract, you may want to lock functions down to a specific state. To do this, you may call either of the `require_paused()` or `require_not_paused()` functions. The example below shows these functions in use.

```sway
use pausable::require_paused;

#[storage(read)]
fn require_paused_state() {
    require_paused();
    // This comment will only ever be reached if the contract is in the paused state
}
```

```sway
use pausable::require_not_paused;

#[storage(read)]
fn require_not_paused_state() {
    require_not_paused();
    // This comment will only ever be reached if the contract is in the unpaused state
}
```

## Using the Ownership Library with the Pausable Library

It is highly recommended to integrate the [Ownership Library](../ownership/index.md) with the Pausable Library and apply restrictions the `pause()` and `unpause()` functions. This will ensure that only a single user may pause and unpause a contract in cause of emergency. Failure to apply this restriction will allow any user to obstruct a contract's functionality.

The follow example implements the `Pausable` abi and applies restrictions to it's pause/unpause functions. The owner of the contract must be set in a constructor defined by `MyConstructor` in this example.

```sway
use pausable::{_is_paused, _pause, _unpause, Pausable};
use ownership::{initialize_ownership, only_owner};

abi MyConstructor {
    #[storage(read, write)]
    fn my_constructor(new_owner: Identity);
}

impl MyConstructor for Contract {
    #[storage(read, write)]
    fn my_constructor(new_owner: Identity) {
        initialize_ownership(new_owner);
    }
}

impl Pausable for Contract {
    #[storage(write)]
    fn pause() {
        // Add the `only_owner()` check to ensure only the owner may unpause this contract.
        only_owner();
        _pause();
    }

    #[storage(write)]
    fn unpause() {
        // Add the `only_owner()` check to ensure only the owner may unpause this contract.
        only_owner();
        _unpause();
    }

    #[storage(read)]
    fn is_paused() -> bool {
        _is_paused()
    }
}
```


---

### File: docs/nightly/sway-libs/docs/book/src/queue/index.md

# Queue Library

A Queue is a linear structure which follows the First-In-First-Out (FIFO) principle. This means that the elements added first are the ones that get removed first.

For implementation details on the Queue Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/queue/queue/).

## Importing the Queue Library

In order to use the Queue Library, the Queue Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Queue Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add queue@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Queue Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use queue::*;
```

## Basic Functionality

### Instantiating a New Queue

Once the `Queue` has been imported, you can create a new queue instance by calling the `new` function.

```sway
    let mut queue = Queue::new();
```

## Enqueuing elements

Adding elements to the `Queue` can be done using the `enqueue` function.

```sway
    // Enqueue an element to the queue
    queue.enqueue(10u8);
```

### Dequeuing Elements

To remove elements from the `Queue`, the `dequeue` function is used. This function follows the FIFO principle.

```sway
    // Dequeue the first element and unwrap the value
    let first_item = queue.dequeue().unwrap();
```

### Fetching the Head Element

To retrieve the element at the head of the `Queue` without removing it, you can use the `peek` function.

```sway
    // Peek at the head of the queue
    let head_item = queue.peek();
```

### Checking the Queue's Length

The `is_empty` and `len` functions can be used to check if the queue is empty and to get the number of elements in the queue respectively.

```sway
    // Checks if queue is empty (returns True or False)
    let is_queue_empty = queue.is_empty();

    // Returns length of queue
    let queue_length = queue.len();
```


---

### File: docs/nightly/sway-libs/docs/book/src/reentrancy/index.md

# Reentrancy Guard Library

The Reentrancy Guard Library provides an API to check for and disallow reentrancy on a contract. A reentrancy attack happens when a function is externally invoked during its execution, allowing it to be run multiple times in a single transaction.

The reentrancy check is used to check if a contract ID has been called more than once in the current call stack.

A reentrancy, or "recursive call" attack can cause some functions to behave in unexpected ways. This can be prevented by asserting a contract has not yet been called in the current transaction. An example can be found [here](https://swcregistry.io/docs/SWC-107).

For implementation details on the Reentrancy Guard Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/reentrancy/reentrancy/).

## Importing the Reentrancy Guard Library

In order to use the Reentrancy Guard library, the Reentrancy Guard Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Reentrancy Guard Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add reentrancy@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Reentrancy Guard Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use reentrancy::*;
```

## Basic Functionality

Once imported, using the Reentrancy Library can be done by calling one of the two functions:

- `is_reentrant() -> bool`
- `reentrancy_guard()`

### Using the Reentrancy Guard

Once imported, using the Reentrancy Guard Library can be used by calling the `reentrancy_guard()` in your Sway Smart Contract. The following shows a Sway Smart Contract that applies the Reentrancy Guard Library:

```sway
use reentrancy::reentrancy_guard;

abi MyContract {
    fn my_non_reentrant_function();
}

impl MyContract for Contract {
    fn my_non_reentrant_function() {
        reentrancy_guard();

        // my code here
    }
}
```

### Checking Reentrancy Status

To check if the current caller is a reentrant, you may call the `is_reentrant()` function.

```sway
use reentrancy::is_reentrant;

fn check_if_reentrant() {
    assert(!is_reentrant());
}
```

## Cross Contract Reentrancy

Cross-Contract Reentrancy is not possible on Fuel due to the use of Native Assets. As such, no contract calls are performed when assets are transferred. However standard security practices when relying on other contracts for state should still be applied, especially when making external calls.


---

### File: docs/nightly/sway-libs/docs/book/src/signed_integers/index.md

# Signed Integers Library

The Signed Integers library provides a library to use signed numbers in Sway. It has 6 distinct types: `I8`, `I16`, `I32`, `I64`, `I128`, `I256`. These types are stack allocated.

Internally the library uses the `u8`, `u16`, `u32`, `u64`, `U128`, `u256` types to represent the underlying values of the signed integers.

For implementation details on the Signed Integers Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/signed_int/signed_int/).

## Importing the Signed Integer Library

In order to use the Signed Integers Library, the Signed Integers Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Signed Integers Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add signed_int@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Signed Integers Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use signed_int::*;
use signed_int::i8::I8;
```

In order to use any of the Signed Integer types, import them into your Sway project like so:

```sway
use signed_int::i8::I8;
```

## Basic Functionality

All the functionality is demonstrated with the `I8` type, but all of the same functionality is available for the other types as well.

### Instantiating a Signed Integer

#### Zero value

Once imported, a `Signed Integer` type can be instantiated defining a new variable and calling the `new` function.

```sway
    let mut i8_value = I8::new();
```

this newly initialized variable represents the value of `0`.

The `new` function is functionally equivalent to the `zero` function.

```sway
    let zero = I8::zero();
    let zero = I8::from_uint(128u8);
```

#### Positive and Negative Values

As the signed variants can only represent half as high a number as the unsigned variants (but with either a positive or negative sign), the `try_from` and `neg_try_from` functions will only work with half of the maximum value of the unsigned variant.

You can use the `try_from` function to create a new positive `Signed Integer` from a its unsigned variant.

```sway
    let one = I8::try_from(1u8).unwrap();
```

You can use the `neg_try_from` function to create a new negative `Signed Integer` from a its unsigned variant.

```sway
    let negative_one = I8::neg_try_from(1u8).unwrap();
```

#### With underlying value

As mentioned previously, the signed integers are internally represented by an unsigned integer, with its values divided into two halves, the bottom half of the values represent the negative values and the top half represent the positive values, and the middle value represents zero.

Therefore, for the lowest value representable by a i8, `-128`, the underlying value would be `0`.

```sway
    let neg_128 = I8::from_uint(0u8);
```

For the zero value, the underlying value would be `128`.

```sway
    let zero = I8::from_uint(128u8);
```

And for the highest value representable by a i8, `127`, the underlying value would be `255`.

```sway
    let pos_127 = I8::from_uint(255u8);
```

#### Minimum and Maximum Values

To get the minimum and maximum values of a signed integer, use the `min` and `max` functions.

```sway
    let min = I8::MIN;
```

```sway
    let max = I8::MAX;
```

### Basic Mathematical Functions

Basic arithmetic operations are working as usual.

```sway
fn add_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 + val2;
}

fn subtract_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 - val2;
}

fn multiply_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 * val2;
}

fn divide_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 / val2;
}
```

#### Checking if a Signed Integer is Zero

The library also provides a helper function to easily check if a `Signed Integer` is zero.

```sway
fn is_zero() {
    let i8 = I8::zero();
    assert(i8.is_zero());
}
```

## Known Issues

The current implementation of `U128` will compile large bytecode sizes when performing mathematical computations. As a result, `I128` and `I256` inherit the same issue and could cause high transaction costs. This should be resolved with future optimizations of the Sway compiler.


---

### File: docs/nightly/sway-libs/docs/book/src/upgradability/index.md

# Upgradability Library

The Upgradability Library provides functions that can be used to implement contract upgrades via simple upgradable proxies. The Upgradability Library implements the required and optional functionality from [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) as well as additional functionality for ownership of the proxy contract.

For implementation details on the Upgradability Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/upgradability/upgradability/).

## Importing the Upgradability Library

In order to use the Upgradability Library, the Upgradability Library and the [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Upgradability Library and the [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add upgradability@0.26.0
forc add src14@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Upgradability Library and  Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use upgradability::*;
use src14::*;
use src5::*;
```

## Integrating the Upgradability Library into the SRC-14 Standard

To implement the [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) standard with the Upgradability library, be sure to add the Sway Standards dependency to your contract. The following demonstrates the integration of the Ownership library with the SRC-14 standard.

```sway
use upgradability::{_proxy_owner, _proxy_target, _set_proxy_target};
use src14::{SRC14, SRC14Extension};
use src5::State;

storage {
    SRC14 {
        /// The [ContractId] of the target contract.
        ///
        /// # Additional Information
        ///
        /// `target` is stored at sha256("storage_SRC14_0")
        target in 0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55: Option<ContractId> = None,
        /// The [State] of the proxy owner.
        ///
        /// # Additional Information
        ///
        /// `proxy_owner` is stored at sha256("storage_SRC14_1")
        proxy_owner in 0xbb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea754: State = State::Uninitialized,
    },
}

impl SRC14 for Contract {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId) {
        _set_proxy_target(new_target);
    }

    #[storage(read)]
    fn proxy_target() -> Option<ContractId> {
        _proxy_target()
    }
}

impl SRC14Extension for Contract {
    #[storage(read)]
    fn proxy_owner() -> State {
        _proxy_owner()
    }
}
```

> **NOTE** An initialization method must be implemented to initialize the proxy target or proxy owner.

## Basic Functionality

### Setting and getting a Proxy Target

Once imported, the Upgradability Library's functions will be available. Use them to change the proxy target for your contract by calling the `set_proxy_target()` function.

```sway
#[storage(read, write)]
fn set_proxy_target(new_target: ContractId) {
    _set_proxy_target(new_target);
}
```

Use the `proxy_target()` method to get the current proxy target.

```sway
#[storage(read)]
fn proxy_target() -> Option<ContractId> {
    _proxy_target()
}
```

### Setting and getting a Proxy Owner

To change the proxy target for your contract use the `set_proxy_owner()` function.

```sway
#[storage(write)]
fn set_proxy_owner(new_proxy_owner: State) {
    _set_proxy_owner(new_proxy_owner);
}
```

Use the `proxy_owner()` method to get the current proxy owner.

```sway
#[storage(read)]
fn proxy_owner() -> State {
    _proxy_owner()
}
```

### Proxy access control

To restrict a function to only be callable by the proxy's owner, call the `only_proxy_owner()` function.

```sway
#[storage(read)]
fn only_proxy_owner_may_call() {
    only_proxy_owner();
    // Only the proxy's owner may reach this line.
}
```


---

### File: docs/nightly/sway-standards/docs/src/index.md

# Sway Standards

The purpose of the Sway Standards [repository](https://github.com/FuelLabs/sway-standards) is to contain standards for the Sway Language which users can import and use.

Standards in this repository may be in various stages of development. Use of draft standards and feedback on the proposed standards is encouraged. To use a draft, search for a standard using the appropriate GitHub label and implement the standard ABI into your contract.

If you don't find what you're looking for, feel free to create an issue and propose a new standard!

> **Note**
> All standards currently use `forc v0.68.1`.

## Using a standard

To import a standard the following should be added to the project's `Forc.toml` file under `[dependencies]` with the most recent release:

```toml
standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.7.1" }
```

> **NOTE:**
> Be sure to set the tag to the latest release.

You may then import your desired standard in your Sway Smart Contract as so:

```sway
use standards::<standard>::<standard_abi>;
```

For example, to import the SRC-20 Native Asset Standard use the following statement in your Sway Smart Contract file:

```sway
use standards::src20::SRC20;
```

## Standards

### Native Assets

- [SRC-20; Native Asset Standard](./src-20-native-asset.md) defines the implementation of a standard API for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) using the Sway Language.
- [SRC-3; Mint and Burn](./src-3-minting-and-burning.md) is used to enable mint and burn functionality for fungible assets.
- [SRC-6; Vault Standard](./src-6-vault.md) defines the implementation of a standard API for asset vaults developed in Sway.
- [SRC-13; Soulbound Address](./src-13-soulbound-address.md) defines the implementation of a soulbound address.

### Onchain Data

- [SRC-7; Onchain Asset Metadata Standard](./src-7-asset-metadata.md) is used to store metadata for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets).
- [SRC-9; Metadata Keys Standard](./src-9-metadata-keys.md) is used to store standardized metadata keys for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) in combination with the SRC-7 standard.

### Offchain Data

- [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md) is used to associated metadata with [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) offchain.
- [SRC-17; Naming Verification Standard](./src-17-naming-verification.md) defines a naming verification standard for onchain identities using offchain data.

### Security and Access Control

- [SRC-5; Ownership Standard](./src-5-ownership.md) is used to restrict function calls to admin users in contracts.
- [SRC-11; Security Information Standard](./src-11-security-information.md) is used to make communication information readily available in the case white hat hackers find a vulnerability in a contract.

### Contracts

- [SRC-12; Contract Factory](./src-12-contract-factory.md) defines the implementation of a standard API for contract factories.
- [SRC-14; Simple Upgradeable Proxies](./src-14-simple-upgradeable-proxies.md) defines the implementation of an upgradeable proxy contract.

### Bridge

- [SRC-8; Bridged Asset](./src-8-bridged-asset.md) defines the metadata required for an asset bridged to the Fuel Network.
- [SRC-10; Native Bridge Standard](./src-10-native-bridge.md) defines the standard API for the Native Bridge between the Fuel Chain and the canonical base chain.

### Encoding and hashing

- [SRC-16; Typed Structured Data](./src-16-typed-structured-data.md) defines standard encoding and hashing of typed structured data.

### Documentation

- [SRC-2; Inline Documentation](./src-2-inline-documentation.md) defines how to document your Sway files.


---

### File: docs/nightly/sway-standards/docs/src/src-10-native-bridge.md

# SRC-10: Native Bridge

The following standard allows for the implementation of a standard API for Native Bridges using the Sway Language. The standardized design has the bridge contract send a message to the origin chain to register which token it accepts to prevent a loss of funds.

## Motivation

A standard interface for bridges intends to provide a safe and efficient bridge between the settlement or canonical chain and the Fuel Network.

## Prior Art

The standard is centered on Fuel’s [Bridge Architecture](https://github.com/FuelLabs/fuel-bridge/blob/main/docs/ARCHITECTURE.md). Fuel's bridge system is built on a message protocol that allows to send (and receive) messages between entities located in two different blockchains.

The following standard takes reference from the [`FungibleBridge`](https://github.com/FuelLabs/fuel-bridge/blob/3971081850e7961d9b649edda4cad8a848ee248e/packages/fungible-token/bridge-fungible-token/src/interface.sw#L22) ABI defined in the fuel-bridge repository.

## Specification

The following functions MUST be implemented to follow the SRC-10; Native Bridge Standard:

### Required Functions

**`fn process_message(message_index: u64)`**

The `process_message()` function accepts incoming deposit messages from the canonical chain and issues the corresponding bridged asset.

- This function MUST parse a message at the given `message_index` index.
- This function SHALL mint an asset that follows the [SRC-8; Bridged Asset Standard](./src-8-bridged-asset.md).
- This function SHALL issue a refund if there is an error in the bridging process.

**`fn withdraw(to_address: b256)`**

The `withdraw()` function accepts and burns a bridged Native Asset on Fuel and sends a message to the bridge contract on the canonical chain to release the originally deposited tokens to the `to_address` address.

- This function SHALL send a message to the bridge contract to release the bridged tokens to the `to_address` address on the canonical chain.
- This function MUST ensure the asset's `AssetId` sent in the transaction matches a bridged asset.
- This function SHALL burn all coins sent in the transaction.

**`fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256)`**

The `claim_refund()` function is called if something goes wrong in the bridging process and an error occurs. It sends a message to the `gateway_contract` contract on the canonical chain to release the `token_address` token with token id `token_id` to the `to_address` address.

- This function SHALL send a message to the `gateway_contract` contract to release the `token_address` token with id `token_id` to the `to_address` address on the canonical chain.
- This function MUST ensure a refund was issued.

### Required Data Types

#### `DepositType`

The `DepositType` enum describes whether the bridged deposit is made to a address, contract, or contract and contains additional metadata. There MUST be the following variants in the `DepositType` enum:

**`Address`: `()`**

The `Address` variant MUST represent when the deposit is made to an address on the Fuel chain.

**`Contract`: `()`**

The `Contract` variant MUST represent when the deposit is made to an contract on the Fuel chain.

**`ContractWithData`: `()`**

The `ContractWithData` variant MUST represent when the deposit is made to an contract and contains additional metadata for the Fuel chain.

##### Example Deposit Type

```sway
pub enum DepositType {
    Address: (),
    Contract: (),
    ContractWithData: (),
}
```

#### `DepositMessage`

The following describes a struct that encapsulates various deposit message metadata to a single type. There MUST be the following fields in the `DepositMessage` struct:

**`amount`: `u256`**

The `amount` field MUST represent the number of tokens.

**`from`: `b256`**

The `from` field MUST represent the bridging user’s address on the canonical chain.

**`to`: `Identity`**

The `to` field MUST represent the bridging target destination `Address` or `ContractId` on the Fuel Chain.

**`token_address`: `b256`**

The `token_address` field MUST represent the bridged token's address on the canonical chain.

**`token_id`: `b256`**

The `token_id` field MUST represent the token's ID on the canonical chain. The `b256::zero()` MUST be used if this is a fungible token and no token ID exists.

**`decimals`: `u8`**

The `decimals` field MUST represent the bridged token's decimals on the canonical chain.

**`deposit_type`: `DepositType`**

The `deposit_type` field MUST represent the type of bridge deposit made on the canonical chain.

##### Example Deposit Message

```sway
pub struct DepositMessage {
    pub amount: b256,
    pub from: b256,
    pub to: Identity,
    pub token_address: b256,
    pub token_id: b256,
    pub decimals: u8,
    pub deposit_type: DepositType,
}
```

#### `MetadataMessage`

The following describes a struct that encapsulates the metadata of token on the canonical chain to a single type. There MUST be the following fields in the `MetadataMessage` struct:

**`token_address`: `b256`**

The `token_address` field MUST represent the bridged token's address on the canonical chain.

**`token_id`: `b256`**

The `token_id` field MUST represent the token's ID on the canonical chain. The `b256::zero()` MUST be used if this is a fungible token and no token ID exists.

**`name`: `String`**

The `name` field MUST represent the bridged token's name field on the canonical chain.

**`symbol`: `String`**

The `symbol` field MUST represent the bridged token's symbol field on the canonical chain.

##### Example Metadata Message

```sway
pub struct MetadataMessage {
    pub token_address: b256,
    pub token_id: b256,
    pub name: String,
    pub symbol: String,
}
```

## Required Standards

Any contract that implements the SRC-10; Native Bridge Standard MUST implement the [SRC-8; Bridged Asset Standard](./src-8-bridged-asset.md) for all bridged assets.

## Rationale

The SRC-10; Native Bridge Standard is designed to standardize the native bridge interface between all Fuel instances.

## Backwards Compatibility

This standard is compatible with the SRC-20 and SRC-8 standards.

## Example ABI

```sway
abi SRC10 {
     fn process_message(message_index: u64);
     fn withdraw(to_address: b256);
     fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256);
}
```


---

### File: docs/nightly/sway-standards/docs/src/src-11-security-information.md

# SRC-11: Security Information

The following standard allows for contract creators to make communication information readily available to everyone, with the primary purpose of allowing white hat hackers to coordinate a bug-fix or securing of funds.

## Motivation

White hat hackers may find bugs or exploits in contracts that they want to report to the project for safeguarding of funds. It is not immediately obvious from a `ContractId`, who the right person to contact is. This standard aims to make the process of bug reporting as smooth as possible.

## Prior Art

The [`security.txt`](https://github.com/neodyme-labs/solana-security-txt) library for Solana has explored this idea. This standard takes inspiration from the library, with some changes.

## Specification

### Security Information Type

The following describes the `SecurityInformation` type.

- The struct MAY contain `None` for `Option<T>` type fields, if they are deemed unnecessary.
- The struct MUST NOT contain empty `String` or `Vec` fields.
- The struct MAY contain a URL or the information directly for the following fields: `project_url`, `policy`, `encryption`, `source_code`, `auditors`, `acknowledgments`, `additional_information`.
- The struct MUST contain the information directly for the following fields: `name`, `contact_information`, `preferred_languages`, `source_release`, and `source_revision`.
- The struct MUST contain at least one item in the `preferred_languages` field's `Vec`, if it is not `None`. Furthermore, the string should only contain the [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) language code and nothing else.
- The struct MUST contain at least one item in the `contact_information` field's `Vec`. Furthermore, the string should follow the following format `<contact_type>:<contact_information>`. Where `contact_type` describes the method of contact (e.g. `email` or `discord`) and `contact_information` describes the information needed to contact (e.g. `example@example.com` or `@EXAMPLE`).

#### `name: String`

The name of the project that the contract is associated with.

#### `project_url: Option<String>`

The website URL of the project that the contract is associated with.

#### `contact_information: Vec<String>`

A list of contact information to contact developers of the project. Should be in the format `<contact_type>:<contact_information>`. You should include contact types that will not change over time.

#### `policy: String`

Text describing the project's security policy, or a link to it. This should describe what kind of bounties your project offers and the terms under which you offer them.

#### `preferred_languages: Option<Vec<String>>`

A list of preferred languages [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes).
If the field is not `None`, it MUST contain at least one item.

#### `encryption: Option<String>`

A PGP public key block (or similar) or a link to one.

#### `source_code: Option<String>`

A URL to the project's source code.

#### `source_release: Option<String>`

The release identifier of this build, ideally corresponding to a tag on git that can be rebuilt to reproduce the same binary. 3rd party build verification tools will use this tag to identify a matching GitHub release.

#### `source_revision: Option<String>`

The revision identifier of this build, usually a git commit hash that can be rebuilt to reproduce the same binary. 3rd party build verification tools will use this tag to identify a matching GitHub release.

#### `auditors: Option<Vec<String>>`

A list of people or entities that audited this smart contract, or links to pages where audit reports are hosted. Note that this field is self-reported by the author of the program and might not be accurate.

#### `acknowledgments: Option<String>`

Text containing acknowledgments to security researchers who have previously found vulnerabilities in the project, or a link to it.

#### `additional_information: Option<String>`

Text containing any additional information you want to provide, or a link to it.

### Required Functions

The following function MUST be implemented to follow the SRC-11 standard.

#### `fn security_information() -> SecurityInformation;`

This function takes no input parameters and returns a struct containing contact information for the project owners, information regarding the bug bounty program, other information related to security, and any other information that the developers find relevant.

- This function MUST return accurate and up to date information.
- This function's return values MUST follow the specification for the `SecurityInformation` type.
- This function MUST NOT revert under any circumstances.

## Rationale

The return structure discussed covers most information that may want to be conveyed regarding the security of the contract, with an additional field to convey any additional information. This should allow easy communication between the project owners and any white hat hackers if necessary.

## Backwards Compatibility

This standard does not face any issues with backward compatibility.

## Security Considerations

The information is entirely self reported and as such might not be accurate. Accuracy of information cannot be enforced and as such, anyone using this information should be aware of that.

## Example ABI

```sway
abi SRC11 {
    #[storage(read)]
    fn security_information() -> SecurityInformation;
}
```

## Example Implementation

### Hard coded information

A basic implementation of the security information standard demonstrating how to hardcode information to be returned.

```sway
contract;

use standards::src11::{SecurityInformation, SRC11};

use std::{string::String, vec::Vec};

/// The name of the project
const NAME: str[7] = __to_str_array("Example");
/// The URL of the project
const PROJECT_URL: str[19] = __to_str_array("https://example.com");
/// The contact information of the project
const CONTACT1: str[25] = __to_str_array("email:example@example.com");
const CONTACT2: str[41] = __to_str_array("link:https://example.com/security_contact");
const CONTACT3: str[20] = __to_str_array("discord:example#1234");
/// The security policy of the project
const POLICY: str[35] = __to_str_array("https://example.com/security_policy");
/// The preferred languages of the project
const PREFERRED_LANGUAGES1: str[2] = __to_str_array("en");
const PREFERRED_LANGUAGES2: str[2] = __to_str_array("ja");
const PREFERRED_LANGUAGES3: str[2] = __to_str_array("zh");
const PREFERRED_LANGUAGES4: str[2] = __to_str_array("hi");
/// The encryption key of the project
const ENCRYPTION: str[751] = __to_str_array(
    "-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: Alice's OpenPGP certificate
Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html

mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE
ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy
MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO
dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4
OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s
E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb
DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn
0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=
=iIGO
-----END PGP PUBLIC KEY BLOCK-----",
);
/// The URL of the project's source code
const SOURCE_CODE: str[31] = __to_str_array("https://github.com/example/test");
/// The release identifier of this build
const SOURCE_RELEASE: str[6] = __to_str_array("v1.0.0");
/// The revision identifier of this build
const SOURCE_REVISION: str[12] = __to_str_array("a1b2c3d4e5f6");
/// The URL of the project's auditors
const AUDITORS: str[28] = __to_str_array("https://example.com/auditors");
/// The URL of the project's acknowledgements
const ACKNOWLEDGEMENTS: str[36] = __to_str_array("https://example.com/acknowledgements");
/// The URL of the project's additional information
const ADDITIONAL_INFORMATION: str[42] = __to_str_array("https://example.com/additional_information");

impl SRC11 for Contract {
    #[storage(read)]
    fn security_information() -> SecurityInformation {
        let mut contact_information = Vec::new();
        contact_information.push(String::from_ascii_str(from_str_array(CONTACT1)));
        contact_information.push(String::from_ascii_str(from_str_array(CONTACT2)));
        contact_information.push(String::from_ascii_str(from_str_array(CONTACT3)));

        let mut preferred_languages = Vec::new();
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES1))); // English
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES2))); // Japanese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES3))); // Chinese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES4))); // Hindi
        let mut auditors = Vec::new();
        auditors.push(String::from_ascii_str(from_str_array(AUDITORS)));

        SecurityInformation {
            name: String::from_ascii_str(from_str_array(NAME)),
            project_url: Some(String::from_ascii_str(from_str_array(PROJECT_URL))),
            contact_information: contact_information,
            policy: String::from_ascii_str(from_str_array(POLICY)),
            preferred_languages: Some(preferred_languages),
            encryption: Some(String::from_ascii_str(from_str_array(ENCRYPTION))),
            source_code: Some(String::from_ascii_str(from_str_array(SOURCE_CODE))),
            source_release: Some(String::from_ascii_str(from_str_array(SOURCE_RELEASE))),
            source_revision: Some(String::from_ascii_str(from_str_array(SOURCE_REVISION))),
            auditors: Some(auditors),
            acknowledgments: Some(String::from_ascii_str(from_str_array(ACKNOWLEDGEMENTS))),
            additional_information: Some(String::from_ascii_str(from_str_array(ADDITIONAL_INFORMATION))),
        }
    }
}

```

### Variable information

A basic implementation of the security information standard demonstrating how to return variable information that can be edited to keep it up to date. In this example only the contact_information field is variable, but the same method can be applied to any field which you wish to update.

```sway
contract;

use standards::src11::{SecurityInformation, SRC11};

use std::{storage::{storage_string::*, storage_vec::*}, string::String, vec::Vec};

/// The name of the project
const NAME: str[7] = __to_str_array("Example");
/// The URL of the project
const PROJECT_URL: str[19] = __to_str_array("https://example.com");
/// The security policy of the project
const POLICY: str[35] = __to_str_array("https://example.com/security_policy");
/// The preferred languages of the project
const PREFERRED_LANGUAGES1: str[2] = __to_str_array("en");
const PREFERRED_LANGUAGES2: str[2] = __to_str_array("ja");
const PREFERRED_LANGUAGES3: str[2] = __to_str_array("zh");
const PREFERRED_LANGUAGES4: str[2] = __to_str_array("hi");
/// The encryption key of the project
const ENCRYPTION: str[751] = __to_str_array(
    "-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: Alice's OpenPGP certificate
Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html

mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE
ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy
MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO
dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4
OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s
E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb
DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn
0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=
=iIGO
-----END PGP PUBLIC KEY BLOCK-----",
);
/// The URL of the project's source code
const SOURCE_CODE: str[31] = __to_str_array("https://github.com/example/test");
/// The release identifier of this build
const SOURCE_RELEASE: str[6] = __to_str_array("v1.0.0");
/// The revision identifier of this build
const SOURCE_REVISION: str[12] = __to_str_array("a1b2c3d4e5f6");
/// The URL of the project's auditors
const AUDITORS: str[28] = __to_str_array("https://example.com/auditors");
/// The URL of the project's acknowledgements
const ACKNOWLEDGEMENTS: str[36] = __to_str_array("https://example.com/acknowledgements");
/// The URL of the project's additional information
const ADDITIONAL_INFORMATION: str[42] = __to_str_array("https://example.com/additional_information");

storage {
    /// The contact information for the security contact.
    contact_information: StorageVec<StorageString> = StorageVec {},
}

abi StorageInformation {
    #[storage(read, write)]
    fn store_contact_information(input: String);
}

impl StorageInformation for Contract {
    #[storage(read, write)]
    fn store_contact_information(input: String) {
        storage.contact_information.push(StorageString {});
        let storage_string = storage.contact_information.get(storage.contact_information.len() - 1).unwrap();
        storage_string.write_slice(input);
    }
}

#[storage(read)]
fn get_contact_information() -> Vec<String> {
    let mut contact_information = Vec::new();

    let mut i = 0;
    while i < storage.contact_information.len() {
        let storage_string = storage.contact_information.get(i).unwrap();
        contact_information.push(storage_string.read_slice().unwrap());
        i += 1;
    }

    contact_information
}

impl SRC11 for Contract {
    #[storage(read)]
    fn security_information() -> SecurityInformation {
        let mut preferred_languages = Vec::new();
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES1))); // English
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES2))); // Japanese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES3))); // Chinese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES4))); // Hindi
        let mut auditors = Vec::new();
        auditors.push(String::from_ascii_str(from_str_array(AUDITORS)));

        SecurityInformation {
            name: String::from_ascii_str(from_str_array(NAME)),
            project_url: Some(String::from_ascii_str(from_str_array(PROJECT_URL))),
            // Use stored variable contact information instead of hardcoded contact information.
            contact_information: get_contact_information(),
            policy: String::from_ascii_str(from_str_array(POLICY)),
            preferred_languages: Some(preferred_languages),
            encryption: Some(String::from_ascii_str(from_str_array(ENCRYPTION))),
            source_code: Some(String::from_ascii_str(from_str_array(SOURCE_CODE))),
            source_release: Some(String::from_ascii_str(from_str_array(SOURCE_RELEASE))),
            source_revision: Some(String::from_ascii_str(from_str_array(SOURCE_REVISION))),
            auditors: Some(auditors),
            acknowledgments: Some(String::from_ascii_str(from_str_array(ACKNOWLEDGEMENTS))),
            additional_information: Some(String::from_ascii_str(from_str_array(ADDITIONAL_INFORMATION))),
        }
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-12-contract-factory.md

# SRC-12: Contract Factory

The following standard allows for the implementation of a standard ABI for Contract Factories using the Sway Language. The standardized design designates how verification of newly deployed child contracts are handled.

## Motivation

A standard interface for Contract Factories provides a safe and effective method of ensuring contracts can verify the validity of another contract as a child of a factory. This is critical on the Fuel Network as contracts cannot deploy other contracts and verification must be done after deployment.

## Prior Art

A Contract Factory is a design where a template contract is used and deployed repeatedly with different configurations. These configurations are often minor changes such as pointing to a different asset. All base functionality remains the same.

On Fuel, contracts cannot deploy other contracts. As a result, a Contract Factory on Fuel must register and verify that the bytecode root of a newly deployed child contract matches the expected bytecode root.

When changing something such as a configurable in Sway, the bytecode root is recalculated. The [Bytecode Library](https://docs.fuel.network/docs/sway-libs/bytecode/) has been developed to calculate the bytecode root of a contract with different configurables.

## Specification

The following functions MUST be implemented to follow the SRC-12; Contract Factory Standard:

### Required Functions

#### `fn register_contract(child_contract: ContractId, configurables: Option<Vec<(u64, Vec<u8>)>>) -> Result<b256, str>`

The `register_contract()` function verifies that a newly deployed contract is the child of a contract factory.

- This function MUST verify that the bytecode root of the `child_contract` contract matches the expected bytecode root.
- This function MUST calculate the bytecode root IF `configurables` is `Some`.
- This function MUST not revert.
- This function MUST return a `Result` containing the `b256` bytecode root of the newly registered contract or an `str` error message.
- This function MAY add arbitrary conditions checking a contract factory child’s validity, such as verifying storage variables or initialized values.

#### `fn is_valid(child_contract: ContractId) -> bool`

The `is_valid()` function returns a boolean representing the state of whether a contract is registered as a valid child of the contract factory.

- This function MUST return `true` if this is a valid and registered child, otherwise `false`.

#### `fn factory_bytecode_root() -> Option<b256>`

The `factory_bytecode_root()` function returns the bytecode root of the default template contract.

- This function MUST return the bytecode root of the template contract.

### Optional Functions

The following are functions that may enhance the use of the SRC-12 standard but ARE NOT required.

#### `fn get_contract_id(configurables: Option<Vec<(u64, Vec<u8>)>>) -> Option<ContractId>`

The `get_contract_id()` function returns a registered contract factory child contract with specific implementation details specified by `configurables`.

This function MUST return `Some(ContractId)` IF a contract that follows the specified `configurables` has been registered with the SRC-12 Contract Factory contract, otherwise `None`.

## Rationale

The SRC-12; Contract Factory Standard is designed to standardize the contract factory design implementation interface between all Fuel instances.

## Backwards Compatibility

There are no other standards that the SRC-12 requires compatibility.

## Security Considerations

This standard takes into consideration child contracts that are deployed with differentiating configurable values, however individual contract behaviours may be dependent on storage variables. As storage variables may change after the contract has been registered with the SRC-12 compliant contract, the standard suggests to check these values upon registration however it is not enforced.

## Example ABI

```sway
abi SRC12 {
    #[storage(read, write)]
    fn register_contract(child_contract: ContractId, configurables: Option<Vec<(u64, Vec<u8>)>>) -> Result<b256, str>;
    #[storage(read)]
    fn is_valid(child_contract: ContractId) -> bool;
    #[storage(read)]
    fn factory_bytecode_root() -> Option<b256>;
}

abi SRC12_Extension {
    #[storage(read)]
    fn get_contract_id(configurables: Option<Vec<(u64, Vec<u8>)>>) -> Option<ContractId>;
}
```

## Example Implementation

### With Configurables

Example of the SRC-12 implementation where contract deployments contain configurable values that differentiate the bytecode root from other contracts with the same bytecode.

```sway
contract;

mod utils;

use utils::{_compute_bytecode_root, _swap_configurables};
use standards::src12::*;
use std::{external::bytecode_root, hash::{Hash, sha256}, storage::storage_vec::*};

configurable {
    TEMPLATE_BYTECODE_ROOT: b256 = b256::zero(),
}

storage {
    /// Contracts that have registered with this contract.
    registered_contracts: StorageMap<ContractId, bool> = StorageMap {},
    /// Maps the hash digest of configurables to the contract id.
    contract_configurables: StorageMap<b256, ContractId> = StorageMap {},
    /// The template contract's bytecode
    bytecode: StorageVec<u8> = StorageVec {},
}

abi MyRegistryContract {
    #[storage(read, write)]
    fn set_bytecode(bytecode: Vec<u8>);
}

impl MyRegistryContract for Contract {
    /// Special helper function to store the template contract's bytecode
    ///
    /// # Additional Information
    ///
    /// Real world implementations should apply restrictions on this function such that it cannot
    /// be changed by anyone or can only be changed once.
    #[storage(read, write)]
    fn set_bytecode(bytecode: Vec<u8>) {
        storage.bytecode.store_vec(bytecode);
    }
}

impl SRC12 for Contract {
    /// Verifies that a newly deployed contract is the child of a contract factory and registers it.
    ///
    /// # Additional Information
    ///
    /// This example does not check whether a contract has already been registered and will overwrite any values.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to verify the bytecode root.
    /// * `configurables`: [Option<ContractConfigurables>] - The configurables value set for the `child_contract`.
    ///
    /// # Returns
    ///
    /// * [Result<BytecodeRoot, str>] - Either the bytecode root of the newly registered contract or a `str` error message.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Writes: `2`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read, write)]
    fn register_contract(
        child_contract: ContractId,
        configurables: Option<ContractConfigurables>,
    ) -> Result<BytecodeRoot, str> {
        let returned_root = bytecode_root(child_contract);

        // If there are no configurables just use the default template
        let computed_root = match configurables {
            Some(config) => {
                let bytecode = storage.bytecode.load_vec();
                compute_bytecode_root(bytecode, config)
            },
            None => {
                TEMPLATE_BYTECODE_ROOT
            }
        };

        // Verify the roots match
        if returned_root != computed_root {
            return Result::Err(
                "The deployed contract's bytecode root and expected contract bytecode root do not match",
            );
        }

        storage.registered_contracts.insert(child_contract, true);
        storage
            .contract_configurables
            .insert(sha256(configurables.unwrap_or(Vec::new())), child_contract);

        return Result::Ok(computed_root)
    }

    /// Returns a boolean representing the state of whether a contract is a valid child of the contract factory.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to check the registry status.
    ///
    /// # Returns
    ///
    /// * [bool] - `true` if the contract has registered and is valid, otherwise `false`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read)]
    fn is_valid(child_contract: ContractId) -> bool {
        storage.registered_contracts.get(child_contract).try_read().unwrap_or(false)
    }

    /// Returns the bytecode root of the default template contract.
    ///
    /// # Returns
    ///
    /// * [Option<BytecodeRoot>] - The bytecode root of the default template contract.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     let root = src_12_contract_abi.factory_bytecode_root();
    ///     assert(root.unwrap() != b256::zero());
    /// }
    /// ```
    #[storage(read)]
    fn factory_bytecode_root() -> Option<BytecodeRoot> {
        Some(TEMPLATE_BYTECODE_ROOT)
    }
}

impl SRC12_Extension for Contract {
    /// Return a registered contract factory child contract with specific implementation details specified by it's configurables.
    ///
    /// # Arguments
    ///
    /// * `configurables`: [Option<ContractConfigurables>] - The configurables value set for the `child_contract`.
    ///
    /// # Returns
    ///
    /// * [Option<ContractId>] - The id of the contract which has registered with the specified configurables.
    ///
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12_Extension;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12_Extension, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     let result_contract_id = src_12_contract_abi.get_contract_id(my_configurables);
    ///     assert(result_contract_id.unwrap() == my_deployed_contract);
    /// }
    /// ```
    #[storage(read)]
    fn get_contract_id(configurables: Option<ContractConfigurables>) -> Option<ContractId> {
        storage.contract_configurables.get(sha256(configurables.unwrap_or(Vec::new()))).try_read()
    }
}

/// This function is copied and can be imported from the Sway Libs Bytecode Library.
/// https://github.com/FuelLabs/sway-libs/tree/master/libs/bytecode
fn compute_bytecode_root(bytecode: Vec<u8>, configurables: Vec<(u64, Vec<u8>)>) -> b256 {
    let mut bytecode_slice = bytecode.as_raw_slice();
    _swap_configurables(bytecode_slice, configurables);
    _compute_bytecode_root(bytecode_slice)
}

```

### Without Configurables

Example of the SRC-12 implementation where all contract deployments are identical and thus have the same bytecode and root.

```sway
contract;

use standards::src12::*;
use std::{external::bytecode_root, hash::Hash};

configurable {
    TEMPLATE_BYTECODE_ROOT: b256 = b256::zero(),
}

storage {
    /// Contracts that have registered with this contract.
    registered_contracts: StorageMap<ContractId, bool> = StorageMap {},
}

impl SRC12 for Contract {
    /// Verifies that a newly deployed contract is the child of a contract factory and registers it.
    ///
    /// # Additional Information
    ///
    /// This example does not check whether a contract has already been registered and will overwrite any values.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to verify the bytecode root.
    /// * `configurables`: [Option<ContractConfigurables>] - The configurables value set for the `child_contract`.
    ///
    /// # Returns
    ///
    /// * [Result<BytecodeRoot, str>] - Either the bytecode root of the newly registered contract or a `str` error message.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Writes: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read, write)]
    fn register_contract(
        child_contract: ContractId,
        configurables: Option<ContractConfigurables>,
    ) -> Result<BytecodeRoot, str> {
        if configurables.is_some() {
            return Result::Err(
                "This SRC-12 implementation only registers contracts without configurable values",
            );
        }

        let returned_root = bytecode_root(child_contract);
        if returned_root != TEMPLATE_BYTECODE_ROOT {
            return Result::Err(
                "The deployed contract's bytecode root and template contract bytecode root do not match",
            );
        }

        storage.registered_contracts.insert(child_contract, true);
        return Result::Ok(returned_root)
    }

    /// Returns a boolean representing the state of whether a contract is a valid child of the contract factory.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to check the registry status.
    ///
    /// # Returns
    ///
    /// * [bool] - `true` if the contract has registered and is valid, otherwise `false`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read)]
    fn is_valid(child_contract: ContractId) -> bool {
        storage.registered_contracts.get(child_contract).try_read().unwrap_or(false)
    }

    /// Returns the bytecode root of the default template contract.
    ///
    /// # Returns
    ///
    /// * [Option<BytecodeRoot>] - The bytecode root of the default template contract.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     let root = src_12_contract_abi.factory_bytecode_root();
    ///     assert(root.unwrap() != b256::zero());
    /// }
    /// ```
    #[storage(read)]
    fn factory_bytecode_root() -> Option<BytecodeRoot> {
        Some(TEMPLATE_BYTECODE_ROOT)
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-13-soulbound-address.md

# SRC-13: Soulbound Address

The following standard allows for the implementation of Soulbound Address on the Fuel Network. Soulbound Assets are [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) sent to the Soulbound Address and cannot be transferred. As Native Assets on the Fuel Network do not require approvals to be spent, any asset sent to an `Address` may be transferable. The SRC-13 standard provides a predicate interface to lock Native Assets as soulbound.

## Motivation

This standard enables soulbound assets on Fuel and allows external applications to query and provide soulbound assets, whether that be decentralized exchanges, wallets, or other external applications.

## Prior Art

[Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on the Fuel Network do not require the implementation of certain functions such as transfer or approval. This is done directly within the FuelVM and there is no smart contract that requires updating of balances. As such, any assets sent to an `Address` may be spendable and ownership of that asset may be transferred. For any soulbound assets, spending must be restricted.

Predicates are programs that return a Boolean value and which represent ownership of some resource upon execution to true. All predicates evaluate to an `Address` based on their bytecode root. A predicate must evaluate to true such that the assets may be spent.

The SRC-13 Soulbound Asset Standard naming pays homage to the [ERC-5192: Minimal Soulbound NFTs](https://eips.ethereum.org/EIPS/eip-5192) seen on Ethereum. While there is functionality we may use as a reference, it is noted that Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) are fundamentally different than Ethereum's tokens.

## Specification

### Overview

To ensure that some asset shall never be spent, we must apply spending conditions. This can be done with Predicates on Fuel. Any asset sent to a Predicate `Address` shall never be spent if the predicate never evaluates to true.

We must also ensure every `Address` on Fuel has its own Predicate. This can be guaranteed by using a `configurable` where an `Address` is defined.

### Definitions

- **Soulbound Address Predicate** - The resulting predicate which owns assets on behalf of an `Address`.
- **Soulbound Address** - The computed `Address` of the _Soulbound Asset Predicate_.
- **Soulbound Asset** - Any [Native Asset](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) sent to the _Soulbound Address_.

### Soulbound Address Predicate Specification

- The _Soulbound Address Predicate_ SHALL never spend the assets sent to its computed predicate `Address` or _Soulbound Address_.
- The _Soulbound Address Predicate_ SHALL encode an `Address` of which it represents the soulbound address.

Below we define the _Soulbound Address Predicate_ where `ADDRESS` MUST be replaced with the `Address` of which the _Soulbound Address Predicate_ represents.

```sway
predicate;

configurable {
    ADDRESS: Address = Address::from(0x0000000000000000000000000000000000000000000000000000000000000000),
}

fn main() -> bool {
    asm (address: ADDRESS) { address: b256 };
    false
}
```

### Soulbound Address

The _Soulbound Address_ is the _Soulbound Address Predicate_'s predicate address. A predicate's address(the bytecode root) is defined [here](https://github.com/FuelLabs/fuel-specs/blob/master/src/identifiers/predicate-id.md).

The _Soulbound Address_ may be computed from the _Soulbound Address Predicate_'s bytecode both on-chain or off-chain. For off-chain computation, please refer to the fuels-rs [predicate docs](https://docs.fuel.network/docs/fuels-rs/predicates/). For on-chain computation, please refer to Sway-Lib's [Bytecode Library](https://docs.fuel.network/docs/sway-libs/bytecode/).

## Rationale

On the Fuel Network, the process for sending any [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) is the same and does not require any approval. This means that any assets sent to an Address may be spendable and does not require any external spending conditions. In the case of a soulbound asset, we need to ensure the asset cannot be spent.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) and the [SRC-20](./src-20-native-asset.md) standard.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

It should however be noted that any Native Asset on the Fuel Network is not a Soulbound Asset until it is sent to a _Soulbound Address_.

## Example

The following example shows the _Soulbound Address Predicate_ for the `0xe033369a522e3cd2fc19a5a705a7f119938027e8e287c0ec35b784e68dab2be6` `Address`.

The resulting _Soulbound Address_ is `0x7f28a538d06788a3d98bb72f4b41012d86abc4b0369ee5dedf56cfbaf245d609`. Any Native Assets sent to this address will become Soulbound Assets.

```sway
predicate;

configurable {
    ADDRESS: Address = Address::from(0xe033369a522e3cd2fc19a5a705a7f119938027e8e287c0ec35b784e68dab2be6),
}

fn main() -> bool {
    asm (address: ADDRESS) { address: b256 };
    false
}
```


---

### File: docs/nightly/sway-standards/docs/src/src-14-simple-upgradeable-proxies.md

# SRC-14: Simple Upgradeable Proxies

The following proposes a standard for simple upgradeable proxies.

## Motivation

We seek to standardize a proxy implementation to improve developer experience and enable tooling to automatically deploy or update proxies as needed.

## Prior Art

[This OpenZeppelin blog post](https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades#proxies-and-implementations) is a good survey of the state of the art at this time.

Proxy designs fall into three essential categories:

1. Immutable proxies which are lightweight clones of other contracts but can't change targets
2. Upgradeable proxies such as [UUPS](https://eips.ethereum.org/EIPS/eip-1822) which store a target in storage and delegate all calls to it
3. [Diamonds](https://eips.ethereum.org/EIPS/eip-2535) which are both upgradeable and can point to multiple targets on a per method basis

This document falls in the second category. We want to standardize the implementation of simple upgradeable pass-through contracts.

The FuelVM provides an `LDC` instruction that is used by Sway's `std::execution::run_external` to provide a similar behavior to EVM's `delegatecall` and execute instructions from another contract while retaining one's own storage context. This is the intended means of implementation of this standard.

## Specification

### Required Behavior

The proxy contract MUST maintain the address of its target in its storage at slot `0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55` (equivalent to `sha256("storage_SRC14_0")`).
It SHOULD base other proxy specific storage fields in the `SRC14` namespace to avoid collisions with target storage.
It MAY have its storage definition overlap with that of its target if necessary.

The proxy contract MUST delegate any method call not part of its interface to the target contract.

This delegation MUST retain the storage context of the proxy contract.

### Required Public Functions

The following functions MUST be implemented by a proxy contract to follow the SRC-14 standard:

#### `fn set_proxy_target(new_target: ContractId);`

If a valid call is made to this function it MUST change the target contract of the proxy to `new_target`.
This method SHOULD implement access controls such that the target can only be changed by a user that possesses the right permissions (typically the proxy owner).

#### `fn proxy_target() -> Option<ContractId>;`

This function MUST return the target contract of the proxy as `Some`. If no proxy is set then `None` MUST be returned.

### Optional Public Functions

The following functions are RECOMMENDED to be implemented by a proxy contract to follow the SRC-14 standard:

#### `fn proxy_owner() -> State;`

This function SHALL return the current state of ownership for the proxy contract where the `State` is either `Uninitialized`, `Initialized`, or `Revoked`. `State` is defined in the [SRC-5; Ownership Standard](./src-5-ownership.md).

## Rationale

This standard is meant to provide simple upgradeability, it is deliberately minimalistic and does not provide the level of functionality of diamonds.

Unlike in [UUPS](https://eips.ethereum.org/EIPS/eip-1822), this standard requires that the upgrade function is part of the proxy and not its target.
This prevents irrecoverable updates if a proxy is made to point to another proxy and no longer has access to upgrade logic.

## Backwards Compatibility

SRC-14 is intended to be compatible with SRC-5 and other standards of contract functionality.

As it is the first attempt to standardize proxy implementation, we do not consider interoperability with other proxy standards.

## Security Considerations

Permissioning proxy target changes is the primary consideration here.
Use of the [SRC-5; Ownership Standard](./src-5-ownership.md) is discouraged. If both the target and proxy contracts implement the [SRC-5](./src-5-ownership.md) standard, the `owner()` function in the target contract is unreachable through the proxy contract. Use of the `proxy_owner()` function in the proxy contract should be used instead.

## Example ABI

```sway
abi SRC14 {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId);
    #[storage(read)]
    fn proxy_target() -> Option<ContractId>;
}

abi SRC14Extension {
    #[storage(read)]
    fn proxy_owner() -> State;
}
```

## Example Implementation

### Minimal Proxy

Example of a minimal SRC-14 implementation with no access control.

```sway
contract;

use std::execution::run_external;
use standards::src14::{SRC14, SRC14_TARGET_STORAGE};

storage {
    SRC14 {
        /// The [ContractId] of the target contract.
        ///
        /// # Additional Information
        ///
        /// `target` is stored at sha256("storage_SRC14_0")
        target in 0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55: ContractId = ContractId::zero(),
    },
}

impl SRC14 for Contract {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId) {
        storage::SRC14.target.write(new_target);
    }

    #[storage(read)]
    fn proxy_target() -> Option<ContractId> {
        storage::SRC14.target.try_read()
    }
}

#[fallback]
#[storage(read)]
fn fallback() {
    // pass through any other method call to the target
    run_external(storage::SRC14.target.read())
}

```

### Owned Proxy

Example of a SRC-14 implementation that also implements `proxy_owner()`.

```sway
contract;

use std::execution::run_external;
use standards::src5::{AccessError, State};
use standards::src14::{SRC14, SRC14_TARGET_STORAGE, SRC14Extension};

/// The owner of this contract at deployment.
#[allow(dead_code)]
const INITIAL_OWNER: Identity = Identity::Address(Address::zero());

storage {
    SRC14 {
        /// The [ContractId] of the target contract.
        ///
        /// # Additional Information
        ///
        /// `target` is stored at sha256("storage_SRC14_0")
        target in 0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55: ContractId = ContractId::zero(),
        /// The [State] of the proxy owner.
        owner: State = State::Initialized(INITIAL_OWNER),
    },
}

impl SRC14 for Contract {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId) {
        only_owner();
        storage::SRC14.target.write(new_target);
    }

    #[storage(read)]
    fn proxy_target() -> Option<ContractId> {
        storage::SRC14.target.try_read()
    }
}

impl SRC14Extension for Contract {
    #[storage(read)]
    fn proxy_owner() -> State {
        storage::SRC14.owner.read()
    }
}

#[fallback]
#[storage(read)]
fn fallback() {
    // pass through any other method call to the target
    run_external(storage::SRC14.target.read())
}

#[storage(read)]
fn only_owner() {
    require(
        storage::SRC14
            .owner
            .read() == State::Initialized(msg_sender().unwrap()),
        AccessError::NotOwner,
    );
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-15-offchain-asset-metadata.md

# SRC-15: Off-Chain Native Asset Metadata

The following standard attempts to define arbitrary metadata for any [Native Asset](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) that is not required by other contracts onchain, in a stateless manner. Any contract that implements the SRC-15 standard MUST implement the [SRC-20](./src-20-native-asset.md) standard.

## Motivation

The SRC-15 standard seeks to enable data-rich assets on the Fuel Network while maintaining a stateless solution. All metadata queries are done off-chain using the indexer.

## Prior Art

The SRC-7 standard exists prior to the SRC-15 standard and is a stateful solution. The SRC-15 builds off the SRC-7 standard by using the `Metadata` enum however provides a stateless solution.

The use of generic metadata was originally found in the Sway-Lib's [NFT Library](https://github.com/FuelLabs/sway-libs/tree/v0.12.0/libs/nft) which did not use Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). This library has since been deprecated.

A previous definition for a metadata standard was written in the original edit of the now defunct [SRC-721](https://github.com/FuelLabs/sway-standards/issues/2). This has since been replaced with the [SRC-20](./src-20-native-asset.md) standard as `SubId` was introduced to enable multiple assets to be minted from a single contract.

## Specification

### Metadata Type

The `Metadata` enum from the SRC-7 standard is also used to represent the metadata in the SRC-15 standard.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-15 standard. Logging MUST be emitted from the contract which minted the asset.

#### SRC15MetadataEvent

The `SRC15MetadataEvent` MUST be emitted at least once for each distinct piece of metadata. The latest emitted `SRC15MetadataEvent` is determined to be the current metadata.

There SHALL be the following fields in the `SRC15MetadataEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` for the metadata.
* `metadata`: The `metadata` field SHALL be used for the corresponding `Metadata` which represents the metadata of the asset.

Example:

```sway
pub struct SRC15MetadataEvent {
    pub asset: AssetId,
    pub metadata: Metadata,
}
```

## Rationale

The SRC-15 standard allows for data-rich assets in a stateless manner by associating an asset with some metadata that may later be fetched by the indexer.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) and the [SRC-20](./src-20-native-asset.md) standard. This standard is also compatible with the SRC-7 standard which defines a stateful solution. It also maintains compatibility with existing standards in other ecosystems.

## Security Considerations

When indexing for SRC-15 metadata, developers should confirm that the contract that emitted the `SRC15MetadataEvent` is also the contract that minted the asset that the metadata associates with. Additionally, restrictions via access control on who may emit the Metadata should be considered.

## Example Implementation

### Single Native Asset

Example of the SRC-15 implementation where metadata exists for only a single asset with one `SubId`.

```sway
contract;

use standards::{
    src15::{
        SRC15MetadataEvent,
    },
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src7::{
        Metadata,
    },
};

use std::string::String;

configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
    /// The metadata for the "attr:health" key.
    ATTR_HEALTH: u64 = 100,
}

abi EmitSRC15Events {
    fn emit_src15_events();
}

impl EmitSRC15Events for Contract {
    fn emit_src15_events() {
        // NOTE: There are no checks for if the caller has permissions to emit the metadata.
        // NOTE: Nothing is stored in storage and there is no method to retrieve the configurables.
        let asset = AssetId::default();
        let metadata_1 = Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X)));
        let metadata_2 = Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM)));
        let metadata_3 = Metadata::Int(ATTR_HEALTH);

        SRC15MetadataEvent::new(asset, metadata_1).log();
        SRC15MetadataEvent::new(asset, metadata_2).log();
        SRC15MetadataEvent::new(asset, metadata_3).log();
    }
}

// SRC15 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable must be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, TOTAL_SUPPLY, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-15 implementation where metadata exists for multiple assets with differing `SubId` values.

```sway
contract;

use standards::{
    src15::{
        SRC15MetadataEvent,
    },
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src7::{
        Metadata,
    },
};

use std::{hash::Hash, storage::storage_string::*, string::String};

// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
    /// The decimals of every asset minted by this contract.
    DECIMALS: u8 = 0u8,
    /// The name of every asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of every asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYAST"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
}

storage {
    /// The total number of distinguishable assets this contract has minted.
    total_assets: u64 = 0,
    /// The total supply of a particular asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}

abi EmitSRC15Events {
    #[storage(read)]
    fn emit_src15_events(asset: AssetId, svg_image: String, health_attribute: u64);
}

impl EmitSRC15Events for Contract {
    #[storage(read)]
    fn emit_src15_events(asset: AssetId, svg_image: String, health_attribute: u64) {
        // NOTE: There are no checks for if the caller has permissions to emit the metadata
        // NOTE: Nothing is stored in storage and there is no method to retrieve the configurables.

        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }

        let metadata_1 = Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X)));
        let metadata_2 = Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM)));
        let metadata_3 = Metadata::String(svg_image);
        let metadata_4 = Metadata::Int(health_attribute);

        SRC15MetadataEvent::new(asset, metadata_1).log();
        SRC15MetadataEvent::new(asset, metadata_2).log();
        SRC15MetadataEvent::new(asset, metadata_3).log();
        SRC15MetadataEvent::new(asset, metadata_4).log();
    }
}

// SRC15 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(NAME))),
            None => None,
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(SYMBOL))),
            None => None,
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(DECIMALS),
            None => None,
        }
    }
}

abi EmitSRC20Data {
    fn emit_src20_data(asset: AssetId, total_supply: u64);
}

impl EmitSRC20Data for Contract {
    fn emit_src20_data(asset: AssetId, supply: u64) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, supply, sender).log();
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-16-typed-structured-data.md

# SRC-16: Typed Structured Data

The following standard sets out to standardize encoding and hashing of typed structured data. This enables secure off-chain message signing with human-readable data structures.

## Motivation

As the Fuel ecosystem expands, there's an increasing need for applications to handle complex, human-readable data structures rather than raw bytes. When users sign messages or transactions, they should be able to clearly understand what they're signing, whether it's a simple asset transfer, or a complex DeFi interaction. Without a standard method for hashing structured data, developers risk implementing their own solutions, which could lead to confusion or compromise security. This standard provides a secure and consistent way to handle encoding and hashing of structured data, ensuring both safety and usability within ecosystem.

This standard aims to:

* Provide a secure, standardized method for hashing structured data
* Enable clear presentation of structured data for user verification during signing
* Support complex data types that mirror Sway structs
* Enable domain separation to prevent cross-protocol replay attacks
* Define a consistent encoding scheme for structured data types
* Remain stateless, not requiring any storage attributes to enable use across all Fuel program types.

## Prior Art

This standard uses ideas from [Ethereum's EIP-712 standard](https://eips.ethereum.org/EIPS/eip-712), adapting its concepts for the Fuel ecosystem. EIP-712 has proven successful in enabling secure structured data signing for applications like the various browser based wallets and signers that are utilized throughout various DeFi protocols.

## Specification

### Definition of Typed Structured Data 𝕊

The set of structured data 𝕊 consists of all instances of struct types that can be composed from the following types:

Atomic Types:

```sway
u8 to u256
bool
b256 (hash)
```

Dynamic Types:

```sway
Bytes   // Variable-length byte sequences
String  // Variable-length strings
```

Reference Types:

Arrays (both fixed size and dynamic)
Structs (reference to other struct types)

Example struct definition:

```sway
struct Mail {
    from: Address,
    to: Address,
    contents: String,
}
```

### Domain Separator Encoding

The domain separator provides context for the signing operation, preventing cross-protocol replay attacks. It is computed as hash_struct(domain) where domain is defined as:

```sway
pub struct SRC16Domain {
    name: String,                   // The protocol name (e.g., "MyProtocol")
    version: String,                // The protocol version (e.g., "1")
    chain_id: u64,                  // The Fuel chain ID
    verifying_contract: ContractId, // The contract id that will verify the signature
}
```

The `chain_id` field is a u64 that must be encoded by left-padding with zeros and packed in big-endian order to fill a 32-byte value.

The domain separator encoding follows this scheme:

* Add SRC16_DOMAIN_TYPE_HASH
* Add Keccak256 hash of name string
* Add Keccak256 hash of version string
* Add chain ID as 32-byte big-endian
* Add verifying contract id as 32 bytes

## Type Encoding

Each struct type is encoded as name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")" where each member is written as type ‖ " " ‖ name.

Example:

```sway
Mail(address from,address to,string contents)
```

## Data Encoding

### Definition of hash_struct

The hash_struct function is defined as:

hash_struct(s : 𝕊) = keccak256(type_hash ‖ encode_data(s))
where:

* type_hash = keccak256(encode_type(type of s))
* ‖ represents byte concatenation
* encode_type and encode_data are defined below

### Definition of encode_data

The encoding of a struct instance is enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ), the concatenation of the encoded member values in the order they appear in the type. Each encoded member value is exactly 32 bytes long.

The values are encoded as follows:

Atomic Values:

* Boolean false and true are encoded as u64 values 0 and 1, padded to 32 bytes
* `Address`, `ContractId`, `Identity`, and `b256` are encoded directly as 32 bytes
* Unsigned Integer values (u8 to u256) are encoded as big-endian bytes, padded to 32 bytes

Dynamic Types:

* `Bytes` and `String` are encoded as their Keccak256 hash

Reference Types:

* Arrays (both fixed and dynamic) are encoded as the Keccak256 hash of their concatenated encodings
* Struct values are encoded recursively as hash_struct(value)

The implementation of `TypedDataHash` for `𝕊` SHALL utilize the `DataEncoder` for encoding each element of the struct based on its type.

## Final Message Encoding

The encoding of structured data follows this pattern:

encode(domain_separator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ `domain_separator` ‖ `hash_struct`(message)

where:

* \x19\x01 is a constant prefix
* ‖ represents byte concatenation
* `domain_separator` is the 32-byte hash of the domain parameters
* `hash_struct`(message) is the 32-byte hash of the structured data

## Example implementation

```sway
const MAIL_TYPE_HASH: b256 = 0x536e54c54e6699204b424f41f6dea846ee38ac369afec3e7c141d2c92c65e67f;

impl TypedDataHash for Mail {

    fn type_hash() -> b256 {
        MAIL_TYPE_HASH
    }

    fn struct_hash(self) -> b256 {
        let mut encoded = Bytes::new();
        encoded.append(
            MAIL_TYPE_HASH.to_be_bytes()
        );
        encoded.append(
            DataEncoder::encode_address(self.from).to_be_bytes()
        );
        encoded.append(
            DataEncoder::encode_address(self.to).to_be_bytes()
        );
        encoded.append(
            DataEncoder::encode_string(self.contents).to_be_bytes()
        );

        keccak256(encoded)
    }
}
```

## Rationale

* Domain separators provides protocol-specific context to prevent signature replay across different protocols and chains.
* Type hashes ensure type safety and prevent collisions between different data structures
* The encoding scheme is designed to be deterministic and injective
* The standard maintains compatibility with existing Sway types and practices

## Backwards Compatibility

This standard is compatible with existing Sway data structures and can be implemented alongside other Fuel standards. It does not conflict with existing signature verification methods.

### Type System Compatibility Notes

When implementing SRC16 in relation to EIP712, the following type mappings and considerations apply:

#### String Encoding

* Both standards use the same String type and encoding
* SRC16 specifically uses String type only (not Sway's `str` or `str[]`)
* String values are encoded identically in both standards using keccak256 hash

#### Fixed Bytes

* EIP712's `bytes32` maps directly to Sway's `b256`
* Encoded using `encode_b256` in the `DataEncoder`
* Both standards handle 32-byte values identically
* Smaller fixed byte arrays (`bytes1` to `bytes31`) are not supported in SRC16

#### Address Types

* EIP712 uses 20-byte Ethereum addresses
* When encoding an EIP712 address, SRC16:
  * Takes only rightmost 20 bytes from a 32-byte Fuel Address
  * Pads with zeros on the left for EIP712 compatibility
  * Example: Fuel `Address` of 32 bytes becomes rightmost 20 bytes in EIP712 encoding

#### ContractId Handling

* `ContractId` is unique to Fuel/SRC16 (no equivalent in EIP712)
* When encoding for EIP712 compatibility:
  * Uses rightmost 20 bytes of `ContractId`
  * Particularly important in domain separators where EIP712 expects a 20-byte address

#### Domain Separator Compatibility

```sway
// SRC16 Domain (Fuel native)
pub struct SRC16Domain {
    name: String,                   // Same as EIP712
    version: String,                // Same as EIP712
    chain_id: u64,                  // Fuel chain ID
    verifying_contract: ContractId, // Full 32-byte ContractId
}

// EIP712 Domain (Ethereum compatible)
pub struct EIP712Domain {
    name: String,
    version: String,
    chain_id: u256,
    verifying_contract: b256,      // Only rightmost 20 bytes used
}
```

Note on `verifying_contract` field; When implementing EIP712 compatibility within SRC16, the `verifying_contract` address in the `EIP712Domain` must be constructed by taking only the rightmost 20 bytes from either a Fuel `ContractId`. This ensures proper compatibility with Ethereum's 20-byte addressing scheme in the domain separator.

```sway
// Example ContractId conversion:
// Fuel ContractId (32 bytes):
//   0x000000000000000000000000a2233d3bf2aa3f0cbbe824eb04afc1acc84c364c
//                            └─────────────── 20 bytes ───────────────┘
//
// EIP712 Address (20 bytes):
//   0xa2233d3bf2aa3f0cbbe824eb04afc1acc84c364c
//    └─────────────── 20 bytes ───────────────┘
```

Note on EIP712 Domain Separator `salt`; Within EIP712 the field `salt` is an optional field to be used at the discretion of the protocol designer. Within SRC16 the `EIP712Domain` does not use the `salt` field. The other fields in `EIP712Domain` are mandatory within SRC16.

## Security Considerations

### Replay Attacks

Implementations must ensure signatures cannot be replayed across:

Different chains (prevented by chain_id)
Different protocols (prevented by domain separator)
Different contracts (prevented by verifying_contract)

### Type Safety

Implementations must validate all type information and enforce strict encoding rules to prevent type confusion attacks.

## Example Implementation

Example of the SRC16 implementation where a contract utilizes the encoding scheme to produce a typed structured data hash of the Mail type.

```sway
contract;

use standards::src16::{
    DataEncoder,
    DomainHash,
    SRC16,
    SRC16Base,
    SRC16Domain,
    SRC16Encode,
    SRC16Payload,
    TypedDataHash,
};
use std::{bytes::Bytes, contract_id::*, hash::*, string::String};

configurable {
    /// The name of the signing domain.
    DOMAIN: str[8] = __to_str_array("MyDomain"),
    /// The current major version for the signing domain.
    VERSION: str[1] = __to_str_array("1"),
    /// The active chain ID where the signing is intended to be used. Cast to u256 in domain_hash
    CHAIN_ID: u64 = 9889u64,
}

/// A demo struct representing a mail message
pub struct Mail {
    /// The sender's address
    pub from: Address,
    /// The recipient's address
    pub to: Address,
    /// The message contents
    pub contents: String,
}

/// The Keccak256 hash of the type Mail as UTF8 encoded bytes.
///
/// "Mail(address from,address to,string contents)"
///
/// 536e54c54e6699204b424f41f6dea846ee38ac369afec3e7c141d2c92c65e67f
///
const MAIL_TYPE_HASH: b256 = 0x536e54c54e6699204b424f41f6dea846ee38ac369afec3e7c141d2c92c65e67f;

impl TypedDataHash for Mail {
    fn type_hash() -> b256 {
        MAIL_TYPE_HASH
    }

    fn struct_hash(self) -> b256 {
        let mut encoded = Bytes::new();
        // Add the Mail type hash.
        encoded.append(MAIL_TYPE_HASH.to_be_bytes());
        // Use the DataEncoder to encode each field for known types
        encoded.append(DataEncoder::encode_address(self.from).to_be_bytes());
        encoded.append(DataEncoder::encode_address(self.to).to_be_bytes());
        encoded.append(DataEncoder::encode_string(self.contents).to_be_bytes());

        keccak256(encoded)
    }
}

/// Implement the encode function for Mail using SRC16Payload
///
/// # Additional Information
///
/// 1. Get the encodeData hash of the Mail typed data using
///    <Mail>..struct_hash();
/// 2. Obtain the payload to by populating the SRC16Payload struct
///    with the domain separator and data_hash from the previous step.
/// 3. Obtain the final_hash [Some(b256)] or None using the function
///    SRC16Payload::encode_hash()
///
impl SRC16Encode<Mail> for Mail {
    fn encode(s: Mail) -> b256 {
        // encodeData hash
        let data_hash = s.struct_hash();
        // setup payload
        let payload = SRC16Payload {
            domain: _get_domain_separator(),
            data_hash: data_hash,
        };

        // Get the final encoded hash
        match payload.encode_hash() {
            Some(hash) => hash,
            None => revert(0),
        }
    }
}

impl SRC16Base for Contract {
    fn domain_separator_hash() -> b256 {
        _get_domain_separator().domain_hash()
    }

    fn data_type_hash() -> b256 {
        MAIL_TYPE_HASH
    }
}

impl SRC16 for Contract {
    fn domain_separator() -> SRC16Domain {
        _get_domain_separator()
    }
}

abi MailMe {
    fn send_mail_get_hash(from_addr: Address, to_addr: Address, contents: String) -> b256;
}

impl MailMe for Contract {
    /// Sends a some mail and returns its encoded hash
    ///
    /// # Arguments
    ///
    /// * `from_addr`: [Address] - The sender's address
    /// * `to_addr`: [Address] - The recipient's address
    /// * `contents`: [String] - The message contents
    ///
    /// # Returns
    ///
    /// * [b256] - The encoded hash of the mail data
    ///
    fn send_mail_get_hash(from_addr: Address, to_addr: Address, contents: String) -> b256 {
        // Create the mail struct from data passed in call
        let some_mail = Mail {
            from: from_addr,
            to: to_addr,
            contents: contents,
        };

        Mail::encode(some_mail)
    }
}

/// A program specific implementation to get the Fuel SRC16Domain
///
/// In a Contract the ContractID can be obtain with ContractId::this()
///
/// In a Predicate or Script it is at the implementors discretion to
/// use the code root if they wish to contrain the validation to a
/// specifc program.
///
fn _get_domain_separator() -> SRC16Domain {
    SRC16Domain::new(
        String::from_ascii_str(from_str_array(DOMAIN)),
        String::from_ascii_str(from_str_array(VERSION)),
        CHAIN_ID,
        ContractId::this(),
    )
}

```

```sway
contract;

use standards::src16::{
    DataEncoder,
    DomainHash,
    EIP712,
    EIP712Domain,
    SRC16Base,
    SRC16Encode,
    SRC16Payload,
    TypedDataHash,
};
use std::{bytes::Bytes, contract_id::*, hash::*, string::String};

configurable {
    /// The name of the signing domain.
    DOMAIN: str[8] = __to_str_array("MyDomain"),
    /// The current major version for the signing domain.
    VERSION: str[1] = __to_str_array("1"),
    /// The active chain ID where the signing is intended to be used. Cast to u256 in domain_hash
    CHAIN_ID: u64 = 9889u64,
}

/// A demo struct representing a mail message
pub struct Mail {
    /// The sender's address
    pub from: b256,
    /// The recipient's address
    pub to: b256,
    /// The message contents
    pub contents: String,
}

/// The Keccak256 hash of the type Mail as UTF8 encoded bytes.
///
/// "Mail(bytes32 from,bytes32 to,string contents)"
///
/// cfc972d321844e0304c5a752957425d5df13c3b09c563624a806b517155d7056
///
const MAIL_TYPE_HASH: b256 = 0xcfc972d321844e0304c5a752957425d5df13c3b09c563624a806b517155d7056;

impl TypedDataHash for Mail {
    fn type_hash() -> b256 {
        MAIL_TYPE_HASH
    }

    fn struct_hash(self) -> b256 {
        let mut encoded = Bytes::new();

        // Add the Mail type hash.
        encoded.append(MAIL_TYPE_HASH.to_be_bytes());
        // Use the DataEncoder to encode each field for known types
        encoded.append(DataEncoder::encode_b256(self.from).to_be_bytes());
        encoded.append(DataEncoder::encode_b256(self.to).to_be_bytes());
        encoded.append(DataEncoder::encode_string(self.contents).to_be_bytes());

        keccak256(encoded)
    }
}

/// Implement the encode function for Mail using SRC16Payload
///
/// # Additional Information
///
/// 1. Get the encodeData hash of the Mail typed data using
///    <Mail>..struct_hash();
/// 2. Obtain the payload to by populating the SRC16Payload struct
///    with the domain separator and data_hash from the previous step.
/// 3. Obtain the final_hash [Some(b256)] or None using the function
///    SRC16Payload::encode_hash()
///
impl SRC16Encode<Mail> for Mail {
    fn encode(s: Mail) -> b256 {
        // encodeData hash
        let data_hash = s.struct_hash();
        // setup payload
        let payload = SRC16Payload {
            domain: _get_domain_separator(),
            data_hash: data_hash,
        };

        // Get the final encoded hash
        match payload.encode_hash() {
            Some(hash) => hash,
            None => revert(0),
        }
    }
}

impl SRC16Base for Contract {
    fn domain_separator_hash() -> b256 {
        _get_domain_separator().domain_hash()
    }

    fn data_type_hash() -> b256 {
        MAIL_TYPE_HASH
    }
}

impl EIP712 for Contract {
    fn domain_separator() -> EIP712Domain {
        _get_domain_separator()
    }
}

abi MailMe {
    fn send_mail_get_hash(from_addr: b256, to_addr: b256, contents: String) -> b256;
}

impl MailMe for Contract {
    /// Sends a some mail and returns its encoded hash
    ///
    /// # Arguments
    ///
    /// * `from_addr`: [b256] - The sender's address
    /// * `to_addr`: [b256] - The recipient's address
    /// * `contents`: [String] - The message contents
    ///
    /// # Returns
    ///
    /// * [b256] - The encoded hash of the mail data
    ///
    fn send_mail_get_hash(from_addr: b256, to_addr: b256, contents: String) -> b256 {
        // Create the mail struct from data passed in call
        let some_mail = Mail {
            from: from_addr,
            to: to_addr,
            contents: contents,
        };

        Mail::encode(some_mail)
    }
}

/// A program specific implementation to get the Ethereum EIP712Domain
///
/// In a Contract the ContractID can be obtain with ContractId::this()
///
/// In a Predicate or Script it is at the implementors discretion to
/// use the code root if they wish to contrain the validation to a
/// specifc program.
///
fn _get_domain_separator() -> EIP712Domain {
    EIP712Domain::new(
        String::from_ascii_str(from_str_array(DOMAIN)),
        String::from_ascii_str(from_str_array(VERSION)),
        (asm(r1: (0, 0, 0, CHAIN_ID)) {
                r1: u256
            }),
        ContractId::this(),
    )
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-17-naming-verification.md

# SRC-17: Naming Verification Standard

The following standard defines a naming verification standard for onchain identities using offchain data.

## Motivation

A standard interface for names on Fuel allows external applications to verify and determine the resolver of a name, whether that be decentralized exchanges frontends, wallets, explorers, or other infrastructure providers.

## Prior Art

A number of existing name service platforms already existed prior to the development of this standard. Notably the most well-known on the Ethereum Blockchain is the [Ethereum Name Service(ENS)](https://ens.domains/). This domain service has a major influence on other name services across multiple platforms. ENS pioneered name service platforms and this standard takes some inspiration from their resolver design.

On Fuel, we have 2 existing name service platforms. These are [Bako ID](https://www.bako.id/) and [Fuel Name Service(FNS)](https://fuelname.com/). This standard was developed in close collaboration with these two platforms to ensure compatibility and ease of upgrade.

## Specification

### Type Aliases

#### `AltBn128Proof` Type Alias

The following describes a type alias for AltBn128 proofs. The `AltBn128Proof` SHALL be defined as the fixed length array `[u8; 288]`.

```sway
pub type AltBn128Proof = [u8; 288];
```

#### `SparseMerkleProof` Type Alias

The following describes a type alias for Sparse Merkle Tree proofs. The `SparseMerkleProof` SHALL be defined as the `Proof` type from the Sway-Libs Sparse Merkle Tree Library.

```sway
pub type SparseMerkleProof = Proof;
```

### Enums

#### `SRC17VerificationError` Enum

The following describes an enum that is used when verification of a name fails. There SHALL be the following variants in the `SRC17VerificationError` type:

##### `VerificationFailed`

The `VerificationFailed` variant SHALL be used when verification of a name fails for ANY reason.

```sway
pub enum SRC17VerificationError {
    VerificationFailed: (),
}
```

#### `SRC17Proof` Enum

The following describes an enum that wraps various proof types into a single input type. There SHALL be the following variants in the `SRC17Proof` type:

##### `AltBn128Proof`

The `AltBn128Proof` variant SHALL be used for AltBn128 proofs.

##### `SparseMerkleProof`

The `SparseMerkleProof` variant SHALL be used for Sparse Merkle Tree proofs.

```sway
pub enum SRC17Proof {
    AltBn128Proof: AltBn128Proof,
    SparseMerkleProof: SparseMerkleProof,
}
```

### Required Public Functions

The following functions MUST be implemented to follow the SRC-17 standard:

#### `fn verify(proof: SRC17Proof, name: String, resolver: Identity, asset: AssetId, metadata: Option<Bytes>) -> Result<(), SRC17VerificationError>`

- This function MUST return `Ok(())` if the proof verification was successful. Otherwise, it MUST return `Err(SRC17VerificationError::VerificationFailed)`.
- The `proof` argument MUST be an `SRC17Proof` which proves the `name`, `asset`, `resolver`, and `metadata` are valid and included in the data.
- The `name` argument MUST the corresponding `String` for the onchain human-readable identity.
- The `resolver` argument MUST be the identity which the name is pointing to.
- The `asset` argument MUST be the asset that represents ownership of a name.
- The `metadata` argument MUST contain `Some` bytes associated with the name or MUST be `None`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-17 standard. Logs MUST be emitted if there are changes that update ANY proof.

#### SRC17NameEvent

The `SRC17NameEvent` MUST be emitted when ANY data changes occur.

There SHALL be the following fields in the `SRC17UpdateEvent` struct:

- `name`: The `name` field SHALL be used for the corresponding `String` which represents the name.
- `resolver`: The `resolver` field SHALL be used for the corresponding `Identity` to which the name points.
- `asset`: The `asset` field SHALL be used for the corresponding `AssetId` that represents ownership of a name.
- `metadata`: The `metadata` field MUST contain `Some` bytes associated with the name or MUST be `None`.

Example:

```sway
pub struct SRC17NameEvent {
    pub name: String,
    pub resolver: Identity,
    pub asset: AssetId,
    pub metadata: Option<Bytes>
}
```

## Rationale

The development and implementation of this standard should enable the verification of names for infrastructure providers such as explorers, wallets, and more. Standardizing the verification method and leaving the implementation up to interpretation shall leave room for experimentation and differentiating designs between projects.

Additionally, the use of proofs should reduce the onchain footprint and minimize state. This standard notably has no expiry, a feature of most name service platforms. Should a project wish to implement an expiry, it should be included as part of the metadata.

## Backwards Compatibility

This standard is compatible with the existing name standards in the Fuel ecosystem, namely Bako ID and Fuel Name Service(FNS). There are no other standards that require compatibility.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

## Example ABI

```sway
pub type AltBn128Proof = [u8; 288];
pub type SparseMerkleProof = Proof;

pub enum SRC17Proof {
    AltBn128Proof: AltBn128Proof,
    SparseMerkleProof: SparseMerkleProof,
}

pub enum SRC17VerificationError {
    VerificationFailed: (),
}

abi SRC17 {
    #[storage(read)]
    fn verify(proof: SRC17Proof, name: String, resolver: Identity, asset: AssetId, metadata: Option<Bytes>) -> Result<(), SRC17VerificationError>;
}
```

## Example Implementation

### Sparse Merkle Verification Example

An example of the SRC-17 implementation where a Sparse Merkle Tree is used to verify the validity of names. In the example, the `name` is the key in the Sparse Merkle Tree and the `asset`, `resolver`, and `metadata` are the data which make up the leaf. The example supports both inclusion and exclusion proofs. If an AltBn128 proof is provided instead, the verification fails.

```sway
contract;

use std::{bytes::Bytes, hash::{Hash, sha256}, string::String};
use standards::src17::*;
use sway_libs::merkle::{common::MerkleRoot, sparse::*};

storage {
    merkle_root: MerkleRoot = MerkleRoot::zero(),
}

impl SRC17 for Contract {
    #[storage(read)]
    fn verify(
        proof: SRC17Proof,
        name: String,
        resolver: Identity,
        asset: AssetId,
        metadata: Option<Bytes>,
    ) -> Result<(), SRC17VerificationError> {
        match proof {
            SRC17Proof::AltBn128Proof(_) => Err(SRC17VerificationError::VerificationFailed),
            SRC17Proof::SparseMerkleProof(proof) => {
                let key: MerkleTreeKey = sha256(name);

                match proof {
                    Proof::Inclusion => {
                        // Combine the resolver, asset, and metadata into to a single Byte array.
                        let mut leaf_bytes = Bytes::new();
                        leaf_bytes.append(resolver.bits().into());
                        leaf_bytes.append(asset.bits().into());
                        match metadata {
                            Some(metadata_bytes) => {
                                leaf_bytes.append(metadata_bytes);
                            },
                            None => (),
                        }

                        if proof.verify(storage.merkle_root.read(), key, Some(leaf_bytes))
                        {
                            Ok(())
                        } else {
                            Err(SRC17VerificationError::VerificationFailed)
                        }
                    },
                    Proof::Exclusion => {
                        if proof.verify(storage.merkle_root.read(), key, None) {
                            Ok(())
                        } else {
                            Err(SRC17VerificationError::VerificationFailed)
                        }
                    }
                }
            }
        }
    }
}

abi UpdateData {
    fn data_updated(
        name: String,
        resolver: Identity,
        asset: AssetId,
        metadata: Option<Bytes>,
    );
}

impl UpdateData for Contract {
    fn data_updated(
        name: String,
        resolver: Identity,
        asset: AssetId,
        metadata: Option<Bytes>,
    ) {
        // NOTE: There are no checks for whether someone has the permission to do this. 
        // It is suggested to add some administrative controls such as the Sway-Libs Ownership Library.
        let event = SRC17NameEvent::new(name, resolver, asset, metadata);
        event.log();
    }
}

abi SetupExample {
    #[storage(write)]
    fn initialize(root: MerkleRoot);
}

impl SetupExample for Contract {
    #[storage(write)]
    fn initialize(root: MerkleRoot) {
        // NOTE: There are no checks for whether someone has the permission to do this. 
        // It is suggested to add some administrative controls such as the Sway-Libs Ownership Library.
        storage.merkle_root.write(root);
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-2-inline-documentation.md

# SRC-2: Inline Documentation

The following standard intends to define the structure and organization of inline documentation for functions, structs, enums, storage, configurables, and more within the Sway Language. This is a living standard.

## Motivation

The standard seeks to provide a better developer experience using Fuel's tooling and the Language Server. This will allow for better interoperability between applications and enable developers to quickly understand any external code they are using or implementing.

## Prior Art

A number of pre-existing functions in the [sway standard library](https://fuellabs.github.io/sway/master/std/), [sway-applications](https://github.com/FuelLabs/sway-applications), and [sway-libs](https://docs.fuel.network/docs/sway-libs/) repositories have inline documentation. The inline documentation for these is already compatible with Fuel's VS Code extension. These however do not all follow the same structure and outline.

## Specification

### Functions

The following describes the structure and order of inline documentation for functions. Some sections MAY NOT apply to each function. When a section is not relevant it SHALL be omitted.

#### Functions: Description

This section has no header.
A simple explanation of the function's intent or functionality.
Example:

```sway
/// This function computes the hash of two numbers.
```

#### Functions: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the function's intent or functionality.
Example:

```sway
/// # Additional Information
///
/// This function also has some complex behaviors.
```

#### Functions: Arguments

This section has a `h1` header.
Lists the arguments of the function's definition with the `*` symbol and describes each one. The list SHALL provide the name, type, and description. The argument SHALL be encapsulated between two backticks: `argument`. The type SHALL be encapsulated between two square brackets: [type].
Example:

```sway
/// # Arguments
///
/// * `argument_1`: [Identity] - This argument is a user to be hashed.
```

#### Functions: Returns

This section has a `h1` header.
Lists the return values of the function with the `*` symbol and describes each one. This list SHALL be in the order of the return index and provide the type and description. The type SHALL be encapsulated between two square brackets: [type].
Example:

```sway
/// # Returns
///
/// * [u64] - The number of hashes performed.
```

#### Functions: Reverts

This section has a `h1` header.
Lists the cases in which the function will revert starting with the `*` symbol. The list SHALL be in the order of occurrence within the function.
Example:

```sway
/// # Reverts
///
/// * When `argument_1` or `argument_2` are a zero [b256].
```

#### Functions: Number of Storage Accesses

This section has a `h1` header.
Provides information on how many storage reads, writes, and clears occur within the function.
Example:

```sway
/// # Number of Storage Accesses
///
/// * Reads: `1`
/// * Clears: `2`
```

#### Functions: Examples

This section has a `h1` header.
This section provides an example of the use of the function. This section is not required to follow the SRC-2 standard however encouraged for auxiliary and library functions.
Example:

```sway
/// # Examples
///
/// ```sway
/// fn foo(argument_1: b256, argument_2: b256) {
///     let result = my_function(argument_1, argument_2);
/// }
```

### Structs

The following describes the structure and order of inline documentation for structs. Some sections MAY NOT apply to each struct. When a section is not relevant it SHALL be omitted.

#### Structs: Description

This section has no header.
A simple explanation of the struct's purpose or functionality.
Example:

```sway
/// This struct contains information on an NFT.
```

#### Structs: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the struct's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This struct also has some complex behaviors.
```

### Fields

The following describes the structure and order of inline documentation for fields within structs. Some sections MAY NOT apply to each field. When a section is not relevant it SHALL be omitted.

#### Fields: Description

This section has no header.
Each field SHALL have its own description with a simple explanation of the field's purpose or functionality.
Example:

```sway
/// This field represents an owner.
field_1: Identity,
```

#### Fields: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the field's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This field also has some complex behaviors.
```

### Enums

The following describes the structure and order of inline documentation for enums. Some sections MAY NOT apply to each enum. When a section is not relevant it SHALL be omitted.

#### Enums: Description

This section has no header.
A simple explanation of the enum's purpose or functionality.
Example:

```sway
/// This enum holds the state of a contract.
```

#### Enums: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the enum's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This enum also has some complex behaviors.
```

### Variant

The following describes the structure and order of inline documentation for fields within enums. Some sections MAY NOT apply to each field. When a section is not relevant it SHALL be omitted.

#### Variant: Description

This section has no header.
Each variant SHALL have its own description with a simple explanation of the variant's purpose or functionality.
Example:

```sway
/// This variant represents the uninitialized state of a contract.
variant_1: (),
/// This variant represents the initialized state of a contract.
variant_2: Identity,
```

#### Variant: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the variant's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This variant also has some complex behaviors.
```

### Errors

In Sway, errors are recommended to be enums. They SHALL follow the same structure and order for inline documentation as described above for enums. Some sections MAY NOT apply to each error. When a section is not relevant it SHALL be omitted.

### Logs

In Sway, logs are recommended to be structs. They SHALL follow the same structure and order for inline documentation as described above for structs. Some sections MAY NOT apply to each log. When a section is not relevant it SHALL be omitted.

### Storage

The following describes the structure and order of inline documentation for variables within the storage block. Some sections MAY NOT apply to each storage variable. When a section is not relevant it SHALL be omitted.

#### Storage: Description

This section has no header.
A simple explanation of the storage variable's purpose or functionality.
Example:

```sway
/// This storage variable is used for state.
```

#### Storage: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the storage variable's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This storage variable maps a user to a state.
```

### Configurable

The following describes the structure and order of inline documentation for variables in the configurable block. Some sections MAY NOT apply to each storage variable. When a section is not relevant it SHALL be omitted.

#### Configurable: Description

This section has no header.
A simple explanation of the configurable variable's purpose or functionality.
Example:

```sway
/// This configurable variable is used for an address.
```

#### Configurable: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the configurable variable's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This configurable variable makes security assumptions.
```

### Other Sections

If the above described sections are not relevant for the information that needs to documented, a custom section with a arbitrary `h1` header may be utilized.

Example:

```sway
/// # Recommended Message Style
///
/// We recommend that `expect` messages are used to describe the reason you *expect* the `Option` should be `Some`.
```

## Rationale

The SRC-2 standard should help provide developers with an easy way to both quickly write inline documentation and get up to speed on other developers' code. This standard in combination with Fuel's VS Code extension provides readily accessible information on functions, structs, and enums

![Screenshot 2023-05-10 125656](https://github.com/FuelLabs/sway-standards/assets/54727135/f03073b9-2a28-44d1-b12a-5603a0738fee)

## Backwards Compatibility

There are no standards that the SRC-2 standard requires to be backward compatible with.

## Security Considerations

This standard will improve security by providing developers with relevant information such as revert cases.

## Examples

### Function Example

```sway
/// Ensures that the sender is the owner.
///
/// # Arguments
///
/// * `number`: [u64] - A value that is checked to be 5.
///
/// # Returns
///
/// * [bool] - Determines whether `number` is or is not 5.
///
/// # Reverts
///
/// * When the sender is not the owner.
///
/// # Number of Storage Accesses
///
/// * Reads: `1`
///
/// # Examples
///
/// ```sway
/// use ownable::Ownership;
///
/// storage {
///     owner: Ownership = Ownership::initialized(Identity::Address(Address::zero())),
/// }
///
/// fn foo() {
///     storage.owner.only_owner();
///     // Do stuff here
/// }
#[storage(read)]
pub fn only_owner(self, number: u64) -> bool {
    require(self.owner() == State::Initialized(msg_sender().unwrap()), AccessError::NotOwner);
    number == 5
}
```

### Struct Examples

```sway
/// Metadata that is tied to an asset.
pub struct NFTMetadata {
    /// Represents the ID of this NFT.
    value: u64,
}
```

```sway
/// Log of a bid.
pub struct Bid {
    /// The number of coins that were bid.
    amount: u64,
    /// The user which placed this bid.
    bidder: Identity,
}
```

### Enum Examples

```sway
/// Determines the state of ownership.
pub enum State {
    /// The ownership has not been set.
    Uninitialized: (),
    /// The user who has been given ownership.
    Initialized: Identity,
    /// The ownership has been given up and can never be set again.
    Revoked: (),
}
```

```sway
/// Error log for when access is denied.
pub enum AccessError {
    /// Emitted when the caller is not the owner of the contract.
    NotOwner: (),
}
```

### Storage Examples

```sway
storage {
    /// An asset which is to be distributed.
    asset: Option<AssetId> = Option::None,
    /// Stores the ClaimState of users that have interacted with the Airdrop Distributor contract.
    ///
    /// # Additional Information
    ///
    /// Maps (user => claim)
    claims: StorageMap<Identity, ClaimState> = StorageMap {},
}
```

### Configurable Example

```sway
configurable {
    /// The threshold required for activation.
    THRESHOLD: u64 = 5,
}
```


---

### File: docs/nightly/sway-standards/docs/src/src-20-native-asset.md

# SRC-20: Native Asset

The following standard allows for the implementation of a standard API for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) using the Sway Language. This standard provides basic functionality as well as on-chain metadata for other applications to use.

## Motivation

A standard interface for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on Fuel allows external applications to interact with the native asset, whether that be decentralized exchanges, wallets, or Fuel's [Scripts](https://docs.fuel.network/docs/sway/sway-program-types/scripts/) and [Predicates](https://docs.fuel.network/docs/sway/sway-program-types/predicates/).

## Prior Art

The SRC-20 Native Asset Standard naming pays homage to the [ERC-20 Token Standard](https://eips.ethereum.org/EIPS/eip-20) seen on Ethereum. While there is functionality we may use as a reference, it is noted that Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) are fundamentally different than Ethereum's tokens.

There has been a discussion of the Fungible Token Standard on the [Fuel Forum](https://forum.fuel.network/). This discussion can be found [here](https://forum.fuel.network/t/src-20-fungible-token-standard/186).

There has also been a Fungible Token Standard and Non-Fungible Token Standard implementations added to the [Sway-Libs](https://github.com/FuelLabs/sway-libs) repository before the creation of the [Sway-Standards](https://github.com/FuelLabs/sway-standards) repository. The introduction of this standard in the [Sway-Standards](https://github.com/FuelLabs/sway-standards) repository will deprecate the Sway-Libs Fungible Token Standard.

## Specification

### Required Public Functions

The following functions MUST be implemented to follow the SRC-20 standard:

#### `fn total_assets() -> u64`

This function MUST return the total number of individual assets for a contract.

#### `fn total_supply(asset: AssetId) -> Option<u64>`

This function MUST return the total supply of coins for an asset. This function MUST return `Some` for any assets minted by the contract.

#### `fn name(asset: AssetId) -> Option<String>`

This function MUST return the name of the asset, such as “Ether”. This function MUST return `Some` for any assets minted by the contract.

#### `fn symbol(asset: AssetId) -> Option<String>`

This function must return the symbol of the asset, such as “ETH”. This function MUST return `Some` for any assets minted by the contract.

#### `fn decimals(asset: AssetId) -> Option<u8>`

This function must return the number of decimals the asset uses - e.g. 8, which means to divide the coin amount by 100000000 to get its user representation. This function MUST return `Some` for any assets minted by the contract.

### Non-Fungible Asset Restrictions

Non-Fungible Tokens (NFT) or Non-Fungible Assets on Fuel are Native Assets and thus follow the same standard as Fungible Native Assets with some restrictions. For a Native Asset on Fuel to be deemed an NFT, the following must be applied:

* Non-Fungible Assets SHALL have a total supply of one per asset.
* Non-Fungible Assets SHALL have a decimal of `0u8`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-20 standard.

* IF a value is updated via a function call, a log MUST be emitted.
* IF a value is embedded in a contract as a constant, configurable, or other manner, an event MUST be emitted at least once.

#### SetNameEvent

The `SetNameEvent` MUST be emitted when the name of an asset has updated.

There SHALL be the following fields in the `SetNameEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `name`: The `name` field SHALL be used for the corresponding `Option<String>` which represents the name of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the name of the asset.

Example:

```sway
pub struct SetNameEvent {
    pub asset: AssetId,
    pub name: Option<String>,
    pub sender: Identity,
}
```

#### SetSymbolEvent

The `SetSymbolEvent` MUST be emitted when the symbol of an asset has updated.

There SHALL be the following fields in the `SetSymbolEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `symbol`: The `symbol` field SHALL be used for the corresponding `Option<String>` which represents the symbol of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the symbol of the asset.

Example:

```sway
pub struct SetSymbolEvent {
    pub asset: AssetId,
    pub symbol: Option<String>,
    pub sender: Identity,
}
```

#### SetDecimalsEvent

The `SetDecimalsEvent` MUST be emitted when the decimals of an asset has updated.

There SHALL be the following fields in the `SetDecimalsEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `decimals`: The `decimals` field SHALL be used for the corresponding `u8` which represents the decimals of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the decimals of the asset.

Example:

```sway
pub struct SetDecimalsEvent {
    pub asset: AssetId,
    pub decimals: u8,
    pub sender: Identity,
}
```

#### UpdateTotalSupplyEvent

The `UpdateTotalSupplyEvent` MUST be emitted when the total supply of an asset has updated.

There SHALL be the following fields in the `UpdateTotalSupplyEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `supply`: The `supply` field SHALL be used for the corresponding `u64` which represents the total supply of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the total supply of the asset.

Example:

```sway
pub struct UpdateTotalSupplyEvent {
    pub asset: AssetId,
    pub supply: u64,
    pub sender: Identity,
}
```

## Rationale

As the SRC-20 Native Asset Standard leverages Native Assets on Fuel, we do not require the implementation of certain functions such as transfer or approval. This is done directly within the FuelVM and there is no smart contract that requires updating of balances. As Fuel is UTXO based, any transfer events may be indexed on transaction receipts.

Following this, we have omitted the inclusion of any transfer functions or events. The provided specification outlines only the functions necessary to implement fully functional native assets on the Fuel Network. Additional functionality and properties may be added as needed.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). There are no other standards that require compatibility.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

## Example ABI

```sway
abi SRC20 {
    #[storage(read)]
    fn total_assets() -> u64;
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64>;
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8>;
}
```

## Example Implementation

### Single Native Asset

Example of the SRC-20 implementation where a contract contains a single asset with one `SubId`. This implementation is recommended for users that intend to deploy a single asset with their contract.

```sway
contract;

use standards::src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use std::{hash::Hash, storage::storage_string::*, string::String};

storage {
    /// The total number of distinguishable assets minted by this contract.
    total_assets: u64 = 0,
    /// The total supply of coins for a specific asset minted by this contract.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// The name of a specific asset minted by this contract.
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    /// The symbol of a specific asset minted by this contract.
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    /// The decimals of a specific asset minted by this contract.
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC20 for Contract {
    /// Returns the total number of individual assets minted  by this contract.
    ///
    /// # Additional Information
    ///
    /// For this single asset contract, this is always one.
    ///
    /// # Returns
    ///
    /// * [u64] - The number of assets that this contract has minted.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let assets = src_20_abi.total_assets();
    ///     assert(assets == 1);
    /// }
    /// ```
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    /// Returns the total supply of coins for an asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the total supply.
    ///
    /// # Returns
    ///
    /// * [Option<u64>] - The total supply of an `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let supply = src_20_abi.total_supply(DEFAULT_SUB_ID);
    ///     assert(supply.unwrap() != 0);
    /// }
    /// ```
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    /// Returns the name of an asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the name.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The name of `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let name = src_20_abi.name(DEFAULT_SUB_ID);
    ///     assert(name.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }

    /// Returns the symbol of am asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the symbol.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The symbol of `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let symbol = src_20_abi.symbol(DEFAULT_SUB_ID);
    ///     assert(symbol.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    /// Returns the number of decimals an asset uses.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the decimals.
    ///
    /// # Returns
    ///
    /// * [Option<u8>] - The decimal precision used by `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let decimals = src_20_abi.decimals(DEFAULT_SUB_ID);
    ///     assert(decimals.unwrap() == 9u8);
    /// }
    /// ```
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        total_supply: u64,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        supply: u64,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.get(asset).write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.get(asset).clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.get(asset).write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.get(asset).clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.get(asset).write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();

        storage.total_supply.get(asset).write(supply);
        TotalSupplyEvent::new(asset, supply, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-20 implementation where a contract contains multiple assets with differing `SubId`s. This implementation is recommended for users that intend to deploy multiple assets with their contract.

```sway
contract;

use standards::src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use std::{auth::msg_sender, string::String};

configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

impl SRC20 for Contract {
    /// Returns the total number of individual assets minted by a contract.
    ///
    /// # Additional Information
    ///
    /// For this single asset contract, this is always one.
    ///
    /// # Returns
    ///
    /// * [u64] - The number of assets that this contract has minted.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let assets = src_20_abi.total_assets();
    ///     assert(assets == 1);
    /// }
    /// ```
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    /// Returns the total supply of coins for the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the total supply, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u64>] - The total supply of an `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let supply = src_20_abi.total_supply(DEFAULT_SUB_ID);
    ///     assert(supply.unwrap() != 0);
    /// }
    /// ```
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }

    /// Returns the name of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the name, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The name of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let name = src_20_abi.name(DEFAULT_SUB_ID);
    ///     assert(name.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    /// Returns the symbol of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the symbol, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The symbol of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let symbol = src_20_abi.symbol(DEFAULT_SUB_ID);
    ///     assert(symbol.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    /// Returns the number of decimals the asset uses.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the decimals, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u8>] - The decimal precision used by `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let decimals = src_20_abi.decimals(DEFAULT_SUB_ID);
    ///     assert(decimals.unwrap() == 9u8);
    /// }
    /// ```
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, TOTAL_SUPPLY, sender).log();
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-3-minting-and-burning.md

# SRC-3: Minting and Burning Native Assets

The following standard enables the minting and burning of native assets for any fungible assets within the Sway Language. It seeks to define mint and burn functions defined separately from the [SRC-20](./src-20-native-asset.md) standard.

## Motivation

The intent of this standard is to separate the extensions of minting and burning from the [SRC-20](./src-20-native-asset.md) standard.

## Prior Art

Minting and burning were initially added to the [SRC-20](./src-20-native-asset.md) standard.

## Specification

### Required Public Functions

The following functions MUST be implemented to follow the SRC-3 standard:

#### `fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64)`

This function MUST mint `amount` coins with a sub-identifier and transfer them to the `recipient`.
This function MUST use the `sub_id` as the sub-identifier IF `sub_id` is `Some`, otherwise this function MUST assign a `SubId` if the `sub_id` argument is `None`.
This function MAY contain arbitrary conditions for minting, and revert if those conditions are not met.

##### Mint Arguments

* `recipient` - The `Identity` to which the newly minted asset is transferred to.
* `sub_id` - The sub-identifier of the asset to mint. If this is `None`, a `SubId` MUST be assigned.
* `amount` - The quantity of coins to mint.

#### `fn burn(sub_id: SubId, amount: u64)`

This function MUST burn `amount` coins with the sub-identifier `sub_id` and MUST ensure the `AssetId` of the asset is the sha-256 hash of `(ContractId, SubId)` for the implementing contract.
This function MUST ensure at least `amount` coins have been transferred to the implementing contract.
This function MUST update the total supply defined in the [SRC-20](./src-20-native-asset.md) standard.
This function MAY contain arbitrary conditions for burning, and revert if those conditions are not met.

##### Burn Arguments

* `sub_id` - The sub-identifier of the asset to burn.
* `amount` - The quantity of coins to burn.

## Rationale

This standard has been added to enable compatibility between applications and allow minting and burning native assets per use case. This standard has been separated from the [SRC-20](./src-20-native-asset.md) standard to allow for the minting and burning for all fungible assets, irrelevant of whether they are [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) or not.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) ensuring its compatibility with the [SRC-20](./src-20-native-asset.md) standard.

## Security Considerations

This standard may introduce security considerations if no checks are implemented to ensure the calling of the `mint()` function is deemed valid or permitted. Checks are highly encouraged.
The burn function may also introduce a security consideration if the total supply within the [SRC-20](./src-20-native-asset.md) standard is not modified.

## Example ABI

```sway
abi SRC3 {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64);
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64);
}
```

## Example Implementation

### Single Native Asset

Example of the SRC-3 implementation where a contract only mints a single asset with one `SubId`.

```sway
contract;

use standards::{
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src3::SRC3,
};
use std::{
    asset::{
        burn,
        mint_to,
    },
    auth::msg_sender,
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    string::String,
};

configurable {
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

storage {
    /// The total supply of the asset minted by this contract.
    total_supply: u64 = 0,
}

impl SRC3 for Contract {
    /// Unconditionally mints new assets using the default SubId.
    ///
    /// # Arguments
    ///
    /// * `recipient`: [Identity] - The user to which the newly minted asset is transferred to.
    /// * `sub_id`: [SubId] - The default SubId.
    /// * `amount`: [u64] - The quantity of coins to mint.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    ///
    /// # Reverts
    ///
    /// * When the `sub_id` is not the default SubId.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let contract_abi = abi(SRC3, contract);
    ///     contract_abi.mint(Identity::ContractId(contract_id), Some(DEFAULT_SUB_ID), 100);
    /// }
    /// ```
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        require(
            sub_id
                .is_some() && sub_id
                .unwrap() == DEFAULT_SUB_ID,
            "Incorrect Sub Id",
        );

        // Increment total supply of the asset and mint to the recipient.
        let new_supply = amount + storage.total_supply.read();
        storage.total_supply.write(new_supply);

        mint_to(recipient, DEFAULT_SUB_ID, amount);

        TotalSupplyEvent::new(AssetId::default(), new_supply, msg_sender().unwrap())
            .log();
    }

    /// Unconditionally burns assets sent with the default SubId.
    ///
    /// # Arguments
    ///
    /// * `sub_id`: [SubId] - The default SubId.
    /// * `amount`: [u64] - The quantity of coins to burn.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    ///
    /// # Reverts
    ///
    /// * When the `sub_id` is not the default SubId.
    /// * When the transaction did not include at least `amount` coins.
    /// * When the transaction did not include the asset minted by this contract.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId, asset_id: AssetId) {
    ///     let contract_abi = abi(SRC3, contract_id);
    ///     contract_abi {
    ///         gas: 10000,
    ///         coins: 100,
    ///         asset_id: asset_id,
    ///     }.burn(DEFAULT_SUB_ID, 100);
    /// }
    /// ```
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        require(sub_id == DEFAULT_SUB_ID, "Incorrect Sub Id");
        require(msg_amount() >= amount, "Incorrect amount provided");
        require(
            msg_asset_id() == AssetId::default(),
            "Incorrect asset provided",
        );

        // Decrement total supply of the asset and burn.
        let new_supply = storage.total_supply.read() - amount;
        storage.total_supply.write(new_supply);

        burn(DEFAULT_SUB_ID, amount);

        TotalSupplyEvent::new(AssetId::default(), new_supply, msg_sender().unwrap())
            .log();
    }
}

// SRC3 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(storage.total_supply.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-3 implementation where a contract mints multiple assets with differing `SubId` values.

```sway
contract;

use standards::{
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src3::SRC3,
};
use std::{
    asset::{
        burn,
        mint_to,
    },
    auth::msg_sender,
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    hash::Hash,
    storage::storage_string::*,
    string::String,
};

// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
    /// The decimals of every asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of every asset minted by this contract.
    NAME: str[12] = __to_str_array("ExampleAsset"),
    /// The symbol of every asset minted by this contract.
    SYMBOL: str[2] = __to_str_array("EA"),
}

storage {
    /// The total number of distinguishable assets this contract has minted.
    total_assets: u64 = 0,
    /// The total supply of a particular asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}

impl SRC3 for Contract {
    /// Unconditionally mints new assets using the `sub_id` sub-identifier.
    ///
    /// # Arguments
    ///
    /// * `recipient`: [Identity] - The user to which the newly minted asset is transferred to.
    /// * `sub_id`: [Option<SubId>] - The sub-identifier of the newly minted asset.
    /// * `amount`: [u64] - The quantity of coins to mint.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `2`
    /// * Writes: `2`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let contract_abi = abi(SRC3, contract_id);
    ///     contract_abi.mint(Identity::ContractId(contract_id), Some(DEFAULT_SUB_ID), 100);
    /// }
    /// ```
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        let sub_id = match sub_id {
            Some(s) => s,
            None => DEFAULT_SUB_ID,
        };
        let asset_id = AssetId::new(ContractId::this(), sub_id);

        // If this SubId is new, increment the total number of distinguishable assets this contract has minted.
        let asset_supply = storage.total_supply.get(asset_id).try_read();
        match asset_supply {
            None => {
                storage.total_assets.write(storage.total_assets.read() + 1)
            },
            _ => {},
        }

        // Increment total supply of the asset and mint to the recipient.
        let new_supply = amount + asset_supply.unwrap_or(0);
        storage.total_supply.insert(asset_id, new_supply);

        mint_to(recipient, sub_id, amount);

        TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
            .log();
    }

    /// Unconditionally burns assets sent with the `sub_id` sub-identifier.
    ///
    /// # Arguments
    ///
    /// * `sub_id`: [SubId] - The sub-identifier of the asset to burn.
    /// * `amount`: [u64] - The quantity of coins to burn.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    ///
    /// # Reverts
    ///
    /// * When the transaction did not include at least `amount` coins.
    /// * When the asset included in the transaction does not have the SubId `sub_id`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId, asset_id: AssetId) {
    ///     let contract_abi = abi(SRC3, contract_id);
    ///     contract_abi {
    ///         gas: 10000,
    ///         coins: 100,
    ///         asset_id: asset_id,
    ///     }.burn(DEFAULT_SUB_ID, 100);
    /// }
    /// ```
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        let asset_id = AssetId::new(ContractId::this(), sub_id);
        require(msg_amount() == amount, "Incorrect amount provided");
        require(msg_asset_id() == asset_id, "Incorrect asset provided");

        // Decrement total supply of the asset and burn.
        let new_supply = storage.total_supply.get(asset_id).read() - amount;
        storage.total_supply.insert(asset_id, new_supply);

        burn(sub_id, amount);

        TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
            .log();
    }
}

// SRC3 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(NAME))),
            None => None,
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(SYMBOL))),
            None => None,
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(DECIMALS),
            None => None,
        }
    }
}

abi SetSRC20Data {
    #[storage(read)]
    fn set_src20_data(asset: AssetId);
}

impl SetSRC20Data for Contract {
    #[storage(read)]
    fn set_src20_data(asset: AssetId) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-5-ownership.md

# SRC-5: Ownership

The following standard intends to enable the use of administrators or owners in Sway contracts.

## Motivation

The standard seeks to provide a method for restricting access to particular users within a Sway contract.

## Prior Art

The [sway-libs](https://docs.fuel.network/docs/sway-libs/ownership/) repository contains a pre-existing Ownership library.

Ownership libraries exist for other ecosystems such as OpenZeppelin's [Ownership library](https://docs.openzeppelin.com/contracts/2.x/api/ownership).

## Specification

### State

There SHALL be 3 states for any library implementing an ownership module in the following order:

#### `Uninitialized`

The `Uninitialized` state SHALL be set as the initial state if no owner or admin is set. The `Uninitialized` state MUST be used when an owner or admin MAY be set in the future.

#### `Initialized`

The `Initialized` state SHALL be set as the state if an owner or admin is set with an associated `Identity` type.

#### `Revoked`

The `Revoked` state SHALL be set when there is no owner or admin and there SHALL NOT be one set in the future.

Example:

```sway
pub enum State {
    Uninitialized: (),
    Initialized: Identity,
    Revoked: (),
}
```

### Functions

The following functions MUST be implemented to follow the SRC-5 standard:

#### `fn owner() -> State`

This function SHALL return the current state of ownership for the contract where `State` is either `Uninitialized`, `Initialized`, or `Revoked`.

### Errors

There SHALL be error handling.

#### `NotOwner`

This error MUST be emitted when `only_owner()` reverts.

## Rationale

In order to provide a universal method of administrative capabilities, SRC-5 will further enable interoperability between applications and provide safeguards for smart contract security.

## Backwards Compatibility

The SRC-5 standard is compatible with the [sway-libs](https://github.com/FuelLabs/sway-libs) repository pre-existing Ownership library. Considerations should be made to best handle multiple owners or admins.

There are no standards that SRC-5 requires to be compatible with.

## Security Considerations

The SRC-5 standard should help improve the security of Sway contracts and their interoperability.

## Example ABI

```sway
abi SRC5 {
    #[storage(read)]
    fn owner() -> State;
}
```

## Example Implementation

### Uninitialized

Example of the SRC-5 implementation where a contract does not have an owner set at compile time with the intent to set it during runtime.

```sway
contract;

use standards::src5::{SRC5, State};

storage {
    /// The owner in storage.
    owner: State = State::Uninitialized,
}

impl SRC5 for Contract {
    /// Returns the owner.
    ///
    /// # Return Values
    ///
    /// * [State] - Represents the state of ownership for this contract.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src5::SRC5;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let ownership_abi = abi(contract_id, SRC_5);
    ///
    ///     match ownership_abi.owner() {
    ///         State::Uninitialized => log("The ownership is uninitialized"),
    ///         _ => log("This example will never reach this statement"),
    ///     }
    /// }
    /// ```
    #[storage(read)]
    fn owner() -> State {
        storage.owner.read()
    }
}

```

### Initialized

Example of the SRC-5 implementation where a contract has an owner set at compile time.

```sway
contract;

use standards::src5::{SRC5, State};

/// The owner of this contract at deployment.
#[allow(dead_code)]
const INITIAL_OWNER: Identity = Identity::Address(Address::zero());

storage {
    /// The owner in storage.
    owner: State = State::Initialized(INITIAL_OWNER),
}

impl SRC5 for Contract {
    /// Returns the owner.
    ///
    /// # Return Values
    ///
    /// * [State] - Represents the state of ownership for this contract.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src5::SRC5;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let ownership_abi = abi(contract_id, SRC_5);
    ///
    ///     match ownership_abi.owner() {
    ///         State::Initialized(owner) => log("The ownership is initialized"),
    ///         _ => log("This example will never reach this statement"),
    ///     }
    /// }
    /// ```
    #[storage(read)]
    fn owner() -> State {
        storage.owner.read()
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-6-vault.md

# SRC-6: Vault

The following standard allows for the implementation of a standard API for asset vaults such as yield-bearing asset vaults or asset wrappers. This standard is an optional add-on to the [SRC-20](./src-20-native-asset.md) standard.

## Motivation

Asset vaults allow users to own shares of variable amounts of assets, such as lending protocols which may have growing assets due to profits from interest. This pattern is highly useful and would greatly benefit from standardization.

## Prior Art

Asset vaults have been thoroughly explored on Ethereum and with [EIP 4626](https://eips.ethereum.org/EIPS/eip-4626) they have their own standard for it. However as Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) are fundamentally different from Ethereum's ERC-20 tokens, the implementation will differ, but the interface may be used as a reference.

## Specification

### Required public functions

The following functions MUST be implemented to follow the SRC-6 standard. Any contract that implements the SRC-6 standard MUST implement the SRC-20 standard.

#### `fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64`

This function takes the `receiver` Identity and the SubId `vault_sub_id` of the sub-vault as an argument and returns the amount of shares minted to the `receiver`.

- This function MUST allow for depositing of the underlying asset in exchange for pro-rata shares of the vault.
- This function MAY reject arbitrary assets based on implementation and MUST revert if unaccepted assets are forwarded.
- This function MAY reject any arbitrary `receiver` based on implementation and MUST revert in the case of a blacklisted or non-whitelisted `receiver`.
- This function MUST mint an asset representing the pro-rata share of the vault, with the SubId of the `sha256((underlying_asset, vault_sub_id))` digest, where `underlying_asset` is the `AssetId` of the deposited asset and the `vault_sub_id` is the id of the vault.
- This function MUST emit a `Deposit` log.
- This function MUST return the amount of minted shares.

#### `fn withdraw(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> u64`

This function takes the `receiver` Identity, the `underlying_asset` `AssetId`, and the `vault_sub_id` of the sub vault, as arguments and returns the amount of assets transferred to the `receiver`.

- This function MUST allow for redeeming of the vault shares in exchange for a pro-rata amount of the underlying assets.
- This function MUST revert if any `AssetId` other than the `AssetId` representing the underlying asset's shares for the given sub vault at `vault_sub_id` is forwarded. (i.e. transferred share's `AssetId` must be equal to `AssetId::new(ContractId::this(), sha256((underlying_asset, vault_sub_id))`)
- This function MUST burn the received shares.
- This function MUST emit a `Withdraw` log.
- This function MUST return amount of assets transferred to the receiver.

#### `fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64`

This function returns the total assets under management by vault. Includes assets controlled by the vault but not directly possessed by vault. It takes the `underlying_asset` `AssetId` and the `vault_sub_id` of the sub vault as arguments and returns the total amount of assets of `AssetId` under management by vault.

- This function MUST return total amount of assets of `underlying_asset` `AssetId` under management by vault.
- This function MUST return 0 if there are no assets of `underlying_asset` `AssetId` under management by vault.
- This function MUST NOT revert under any circumstances.

#### `fn max_depositable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>`

This is a helper function for getting the maximum amount of assets that can be deposited. It takes the hypothetical `receiver` `Identity`, the `underlying_asset` `AssetId`, and the `vault_sub_id` `SubId` of the sub vault as an arguments and returns the maximum amount of assets that can be deposited into the contract, for the given asset.

- This function MUST return the maximum amount of assets that can be deposited into the contract, for the given `underlying_asset`, if the given `vault_sub_id` vault exists.
- This function MUST return an `Some(amount)` if the given `vault_sub_id` vault exists.
- This function MUST return an `None` if the given `vault_sub_id` vault does not exist.
- This function MUST account for both global and user specific limits. For example: if deposits are disabled, even temporarily, MUST return 0.

#### `fn max_withdrawable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>`

This is a helper function for getting maximum withdrawable. It takes the hypothetical `receiver` `Identity`, the `underlying_asset` `AssetId`, and the `vault_sub_id` SubId of the sub vault as an argument and returns the maximum amount of assets that can be withdrawn from the contract, for the given asset.

- This function MUST return the maximum amount of assets that can be withdrawn from the contract, for the given `underlying_asset`, if the given `vault_sub_id` vault exists.
- This function MUST return an `Some(amount)` if the given `vault_sub_id` vault exists.
- This function MUST return an `None` if the given `vault_sub_id` vault does not exist.
- This function MUST account for global limits. For example: if withdrawals are disabled, even temporarily, MUST return 0.

### Required logs

The following logs MUST be emitted at the specified occasions.

#### `Deposit`

`caller` has called the `deposit()` method sending `deposited_amount` assets of the `underlying_asset` Asset to the subvault of `vault_sub_id`, in exchange for `minted_shares` shares sent to the receiver `receiver`.

The `Deposit` struct MUST be logged whenever new shares are minted via the `deposit()` method.

The `Deposit` log SHALL have the following fields.

**`caller`: `Identity`**

The `caller` field MUST represent the `Identity` which called the deposit function.

**`receiver`: `Identity`**

The `receiver` field MUST represent the `Identity` which received the vault shares.

**`underlying_asset`: `AssetId`**

The `underlying_asset` field MUST represent the `AssetId` of the asset which was deposited into the vault.

**`vault_sub_id`: `SubId`**

The `vault_sub_id` field MUST represent the `SubId` of the vault which was deposited into.

**`deposited_amount`: `u64`**

The `deposited_amount` field MUST represent the `u64` amount of assets deposited into the vault.

**`minted_shares`: `u64`**

The `minted_shares` field MUST represent the `u64` amount of shares minted.

#### `Withdraw`

`caller` has called the `withdraw()` method sending `burned_shares` shares in exchange for `withdrawn_amount` assets of the `underlying_asset` Asset from the subvault of `vault_sub_id` to the receiver `receiver`.

The `Withdraw` struct MUST be logged whenever shares are redeemed for assets via the `withdraw()` method.

The `Withdraw` log SHALL have the following fields.

**`caller`: `Identity`**

The `caller` field MUST represent the Identity which called the withdraw function.

**`receiver`: `Identity`**

The `receiver` field MUST represent the Identity which received the withdrawn assets.

**`underlying_asset`: `AssetId`**

The `underlying_asset` field MUST represent the `AssetId` of the asset that was withdrawn.

**`vault_sub_id`: `SubId`**

The `vault_sub_id` field MUST represent the SubId of the vault from which was withdrawn.

**`withdrawn_amount`: `u64`**

The `withdrawn_amount` field MUST represent the `u64` amount of coins withdrawn.

**`burned_shares`: `u64`**

The `burned_shares` field MUST represent the `u64` amount of shares burned.

## Rationale

The ABI discussed covers the known use cases of asset vaults while allowing safe implementations.

## Backwards Compatibility

This standard is fully compatible with the [SRC-20 standard](./src-20-native-asset.md).

## Security Considerations

Incorrect implementation of asset vaults could allow attackers to steal underlying assets. It is recommended to properly audit any code using this standard to ensure exploits are not possible.

## Example ABI

```sway
abi SRC6 {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64;

    #[payable]
    #[storage(read, write)]
    fn withdraw(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> u64;

    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64;

    #[storage(read)]
    fn max_depositable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>;

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>;
}
```

## Example Implementation

### Multi Asset Vault

A basic implementation of the vault standard that supports any number of sub vaults being created for every `AssetId`.

```sway
contract;

use std::{
    asset::transfer,
    call_frames::msg_asset_id,
    context::msg_amount,
    hash::{
        Hash,
        sha256,
    },
    storage::storage_string::*,
    string::String,
};

use standards::{
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src6::{
        Deposit,
        SRC6,
        Withdraw,
    },
};

pub struct VaultInfo {
    /// Amount of assets currently managed by this vault
    managed_assets: u64,
    /// The vault_sub_id of this vault.
    vault_sub_id: SubId,
    /// The asset being managed by this vault
    asset: AssetId,
}

storage {
    /// Vault share AssetId -> VaultInfo.
    vault_info: StorageMap<AssetId, VaultInfo> = StorageMap {},
    /// Number of different assets managed by this contract.
    total_assets: u64 = 0,
    /// Total supply of shares for each asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// Asset name.
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset symbol.
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset decimals.
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC6 for Contract {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64 {
        let asset_amount = msg_amount();
        require(asset_amount != 0, "ZERO_ASSETS");

        let underlying_asset = msg_asset_id();
        let (shares, share_asset, share_asset_vault_sub_id) = preview_deposit(underlying_asset, vault_sub_id, asset_amount);

        _mint(receiver, share_asset, share_asset_vault_sub_id, shares);

        let mut vault_info = match storage.vault_info.get(share_asset).try_read() {
            Some(vault_info) => vault_info,
            None => VaultInfo {
                managed_assets: 0,
                vault_sub_id,
                asset: underlying_asset,
            },
        };
        vault_info.managed_assets = vault_info.managed_assets + asset_amount;
        storage.vault_info.insert(share_asset, vault_info);

        Deposit::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            asset_amount,
            shares,
        )
            .log();

        shares
    }

    #[payable]
    #[storage(read, write)]
    fn withdraw(
        receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> u64 {
        let shares = msg_amount();
        require(shares != 0, "ZERO_SHARES");

        let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

        require(msg_asset_id() == share_asset_id, "INVALID_ASSET_ID");
        let assets = preview_withdraw(share_asset_id, shares);

        let mut vault_info = storage.vault_info.get(share_asset_id).read();
        vault_info.managed_assets = vault_info.managed_assets - shares;
        storage.vault_info.insert(share_asset_id, vault_info);

        _burn(share_asset_id, share_asset_vault_sub_id, shares);

        transfer(receiver, underlying_asset, assets);

        Withdraw::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            assets,
            shares,
        )
            .log();

        assets
    }
    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64 {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
        // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
        managed_assets(vault_share_asset)
    }

    #[storage(read)]
    fn max_depositable(
        _receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
        // This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
        match storage.vault_info.get(vault_share_asset).try_read() {
            Some(vault_info) => Some(u64::max() - vault_info.managed_assets),
            None => None,
        }
    }

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
        // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, total_assets should be greater than max_withdrawable.
        match storage.vault_info.get(vault_share_asset).try_read() {
            Some(vault_info) => Some(vault_info.managed_assets),
            None => None,
        }
    }
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.try_read().unwrap_or(0)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.get(asset).write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.get(asset).clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.get(asset).write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.get(asset).clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.get(asset).write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();
    }
}

/// Returns the vault shares assetid and subid for the given assets assetid and the vaults sub id
fn vault_asset_id(asset: AssetId, vault_sub_id: SubId) -> (AssetId, SubId) {
    let share_asset_vault_sub_id = sha256((asset, vault_sub_id));
    let share_asset_id = AssetId::new(ContractId::this(), share_asset_vault_sub_id);
    (share_asset_id, share_asset_vault_sub_id)
}

#[storage(read)]
fn managed_assets(vault_share_asset_id: AssetId) -> u64 {
    match storage.vault_info.get(vault_share_asset_id).try_read() {
        Some(vault_info) => vault_info.managed_assets,
        None => 0,
    }
}

#[storage(read)]
fn preview_deposit(
    underlying_asset: AssetId,
    vault_sub_id: SubId,
    assets: u64,
) -> (u64, AssetId, SubId) {
    let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

    let shares_supply = storage.total_supply.get(share_asset_id).try_read().unwrap_or(0);
    if shares_supply == 0 {
        (assets, share_asset_id, share_asset_vault_sub_id)
    } else {
        (
            assets * shares_supply / managed_assets(share_asset_id),
            share_asset_id,
            share_asset_vault_sub_id,
        )
    }
}

#[storage(read)]
fn preview_withdraw(share_asset_id: AssetId, shares: u64) -> u64 {
    let supply = storage.total_supply.get(share_asset_id).read();
    if supply == shares {
        managed_assets(share_asset_id)
    } else {
        shares * (managed_assets(share_asset_id) / supply)
    }
}

#[storage(read, write)]
pub fn _mint(
    recipient: Identity,
    asset_id: AssetId,
    vault_sub_id: SubId,
    amount: u64,
) {
    use std::asset::mint_to;

    let supply = storage.total_supply.get(asset_id).try_read();
    // Only increment the number of assets minted by this contract if it hasn't been minted before.
    if supply.is_none() {
        storage.total_assets.write(storage.total_assets.read() + 1);
    }
    let new_supply = supply.unwrap_or(0) + amount;
    storage.total_supply.insert(asset_id, new_supply);
    mint_to(recipient, vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

#[storage(read, write)]
pub fn _burn(asset_id: AssetId, vault_sub_id: SubId, amount: u64) {
    use std::{asset::burn, context::this_balance};

    require(
        this_balance(asset_id) >= amount,
        "BurnError::NotEnoughCoins",
    );
    // If we pass the check above, we can assume it is safe to unwrap.
    let supply = storage.total_supply.get(asset_id).try_read().unwrap();
    let new_supply = supply - amount;
    storage.total_supply.insert(asset_id, new_supply);
    burn(vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

```

### Single Asset Vault

A basic implementation of the vault standard demonstrating how to restrict deposits and withdrawals to a single `AssetId`.

```sway
contract;

use std::{
    asset::transfer,
    call_frames::msg_asset_id,
    context::msg_amount,
    hash::{
        Hash,
        sha256,
    },
    storage::storage_string::*,
    string::String,
};

use standards::{
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src6::{
        Deposit,
        SRC6,
        Withdraw,
    },
};

pub struct VaultInfo {
    /// Amount of assets currently managed by this vault
    managed_assets: u64,
    /// The vault_sub_id of this vault.
    vault_sub_id: SubId,
    /// The asset being managed by this vault
    asset: AssetId,
}

storage {
    /// Vault share AssetId -> VaultInfo.
    vault_info: StorageMap<AssetId, VaultInfo> = StorageMap {},
    /// Number of different assets managed by this contract.
    total_assets: u64 = 0,
    /// Total supply of shares.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// Asset name.
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset symbol.
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset decimals.
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC6 for Contract {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64 {
        let asset_amount = msg_amount();
        let underlying_asset = msg_asset_id();

        require(underlying_asset == AssetId::base(), "INVALID_ASSET_ID");
        let (shares, share_asset, share_asset_vault_sub_id) = preview_deposit(underlying_asset, vault_sub_id, asset_amount);
        require(asset_amount != 0, "ZERO_ASSETS");

        _mint(receiver, share_asset, share_asset_vault_sub_id, shares);

        let mut vault_info = match storage.vault_info.get(share_asset).try_read() {
            Some(vault_info) => vault_info,
            None => VaultInfo {
                managed_assets: 0,
                vault_sub_id,
                asset: underlying_asset,
            },
        };
        vault_info.managed_assets = vault_info.managed_assets + asset_amount;
        storage.vault_info.insert(share_asset, vault_info);

        Deposit::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            asset_amount,
            shares,
        )
            .log();

        shares
    }

    #[payable]
    #[storage(read, write)]
    fn withdraw(
        receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> u64 {
        let shares = msg_amount();
        require(shares != 0, "ZERO_SHARES");

        let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

        require(msg_asset_id() == share_asset_id, "INVALID_ASSET_ID");
        let assets = preview_withdraw(share_asset_id, shares);

        let mut vault_info = storage.vault_info.get(share_asset_id).read();
        vault_info.managed_assets = vault_info.managed_assets - shares;
        storage.vault_info.insert(share_asset_id, vault_info);

        _burn(share_asset_id, share_asset_vault_sub_id, shares);

        transfer(receiver, underlying_asset, assets);

        Withdraw::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            assets,
            shares,
        )
            .log();

        assets
    }

    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64 {
        if underlying_asset == AssetId::base() {
            let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            managed_assets(vault_share_asset)
        } else {
            0
        }
    }

    #[storage(read)]
    fn max_depositable(
        _receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;

        match (
            underlying_asset == AssetId::base(),
            storage.vault_info.get(vault_share_asset).try_read(),
        ) {
            // This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
            (true, Some(vault_info)) => Some(u64::max() - vault_info.managed_assets),
            _ => None,
        }
    }

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;

        match (
            underlying_asset == AssetId::base(),
            storage.vault_info.get(vault_share_asset).try_read(),
        ) {
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            (true, Some(vault_info)) => Some(vault_info.managed_assets),
            _ => None,
        }
    }
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.try_read().unwrap_or(0)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.get(asset).write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.get(asset).clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.get(asset).write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.get(asset).clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.get(asset).write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();
    }
}

/// Returns the vault shares assetid and subid for the given assets assetid and the vaults sub id
fn vault_asset_id(underlying_asset: AssetId, vault_sub_id: SubId) -> (AssetId, SubId) {
    let share_asset_vault_sub_id = sha256((underlying_asset, vault_sub_id));
    let share_asset_id = AssetId::new(ContractId::this(), share_asset_vault_sub_id);
    (share_asset_id, share_asset_vault_sub_id)
}

#[storage(read)]
fn managed_assets(vault_share_asset_id: AssetId) -> u64 {
    match storage.vault_info.get(vault_share_asset_id).try_read() {
        Some(vault_info) => vault_info.managed_assets,
        None => 0,
    }
}

#[storage(read)]
fn preview_deposit(
    underlying_asset: AssetId,
    vault_sub_id: SubId,
    assets: u64,
) -> (u64, AssetId, SubId) {
    let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

    let shares_supply = storage.total_supply.get(share_asset_id).try_read().unwrap_or(0);
    if shares_supply == 0 {
        (assets, share_asset_id, share_asset_vault_sub_id)
    } else {
        (
            assets * shares_supply / managed_assets(share_asset_id),
            share_asset_id,
            share_asset_vault_sub_id,
        )
    }
}

#[storage(read)]
fn preview_withdraw(share_asset_id: AssetId, shares: u64) -> u64 {
    let supply = storage.total_supply.get(share_asset_id).read();
    if supply == shares {
        managed_assets(share_asset_id)
    } else {
        shares * (managed_assets(share_asset_id) / supply)
    }
}

#[storage(read, write)]
pub fn _mint(
    recipient: Identity,
    asset_id: AssetId,
    vault_sub_id: SubId,
    amount: u64,
) {
    use std::asset::mint_to;

    let supply = storage.total_supply.get(asset_id).try_read();
    // Only increment the number of assets minted by this contract if it hasn't been minted before.
    if supply.is_none() {
        storage.total_assets.write(storage.total_assets.read() + 1);
    }
    let new_supply = supply.unwrap_or(0) + amount;
    storage.total_supply.insert(asset_id, new_supply);
    mint_to(recipient, vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

#[storage(read, write)]
pub fn _burn(asset_id: AssetId, vault_sub_id: SubId, amount: u64) {
    use std::{asset::burn, context::this_balance};

    require(
        this_balance(asset_id) >= amount,
        "BurnError::NotEnoughCoins",
    );
    // If we pass the check above, we can assume it is safe to unwrap.
    let supply = storage.total_supply.get(asset_id).try_read().unwrap();
    let new_supply = supply - amount;
    storage.total_supply.insert(asset_id, new_supply);
    burn(vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

```

## Single Asset Single Sub Vault

A basic implementation of the vault standard demonstrating how to restrict deposits and withdrawals to a single `AssetId`, and to a single Sub vault.

```sway
contract;

use std::{
    asset::transfer,
    call_frames::msg_asset_id,
    context::msg_amount,
    hash::{
        Hash,
        sha256,
    },
    storage::storage_string::*,
    string::String,
};

use standards::{
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src6::{
        Deposit,
        SRC6,
        Withdraw,
    },
};

configurable {
    /// The only sub vault that can be deposited and withdrawn from this vault.
    ACCEPTED_SUB_VAULT: SubId = SubId::zero(),
    PRE_CALCULATED_SHARE_VAULT_SUB_ID: SubId = 0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b,
}

storage {
    /// The total amount of assets managed by this vault.
    managed_assets: u64 = 0,
    /// The total amount of shares minted by this vault.
    total_supply: u64 = 0,
    /// The name of a specific asset minted by this contract.
    name: StorageString = StorageString {},
    /// The symbol of a specific asset minted by this contract.
    symbol: StorageString = StorageString {},
    /// The decimals of a specific asset minted by this contract.
    decimals: u8 = 9,
}

impl SRC6 for Contract {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64 {
        require(vault_sub_id == ACCEPTED_SUB_VAULT, "INVALID_vault_sub_id");

        let underlying_asset = msg_asset_id();
        require(underlying_asset == AssetId::base(), "INVALID_ASSET_ID");

        let asset_amount = msg_amount();
        require(asset_amount != 0, "ZERO_ASSETS");
        let shares = preview_deposit(asset_amount);

        _mint(receiver, shares);

        storage
            .managed_assets
            .write(storage.managed_assets.read() + asset_amount);

        Deposit::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            asset_amount,
            shares,
        )
            .log();

        shares
    }

    #[payable]
    #[storage(read, write)]
    fn withdraw(
        receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> u64 {
        require(underlying_asset == AssetId::base(), "INVALID_ASSET_ID");
        require(vault_sub_id == ACCEPTED_SUB_VAULT, "INVALID_vault_sub_id");

        let shares = msg_amount();
        require(shares != 0, "ZERO_SHARES");

        let share_asset_id = vault_assetid();

        require(msg_asset_id() == share_asset_id, "INVALID_ASSET_ID");
        let assets = preview_withdraw(shares);

        storage
            .managed_assets
            .write(storage.managed_assets.read() - shares);

        _burn(share_asset_id, shares);

        transfer(receiver, underlying_asset, assets);

        Withdraw::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            assets,
            shares,
        )
            .log();

        assets
    }

    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64 {
        if underlying_asset == AssetId::base() && vault_sub_id == ACCEPTED_SUB_VAULT {
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            storage.managed_assets.read()
        } else {
            0
        }
    }

    #[storage(read)]
    fn max_depositable(
        _receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> Option<u64> {
        if underlying_asset == AssetId::base() && vault_sub_id == ACCEPTED_SUB_VAULT {
            // This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
            Some(u64::max() - storage.managed_assets.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64> {
        if underlying_asset == AssetId::base() && vault_sub_id == ACCEPTED_SUB_VAULT {
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            Some(storage.managed_assets.read())
        } else {
            None
        }
    }
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == vault_assetid() {
            Some(storage.total_supply.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == vault_assetid() {
            match storage.name.read_slice() {
                Some(name) => Some(name),
                None => None,
            }
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == vault_assetid() {
            match storage.symbol.read_slice() {
                Some(symbol) => Some(symbol),
                None => None,
            }
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == vault_assetid() {
            Some(storage.decimals.read())
        } else {
            None
        }
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        require(asset == vault_assetid(), "INVALID_ASSET_ID");
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();
    }
}

/// Returns the vault shares assetid for the given assets assetid and the vaults sub id
fn vault_assetid() -> AssetId {
    let share_asset_id = AssetId::new(ContractId::this(), PRE_CALCULATED_SHARE_VAULT_SUB_ID);
    share_asset_id
}

#[storage(read)]
fn preview_deposit(assets: u64) -> u64 {
    let shares_supply = storage.total_supply.try_read().unwrap_or(0);
    if shares_supply == 0 {
        assets
    } else {
        assets * shares_supply / storage.managed_assets.try_read().unwrap_or(0)
    }
}

#[storage(read)]
fn preview_withdraw(shares: u64) -> u64 {
    let supply = storage.total_supply.read();
    if supply == shares {
        storage.managed_assets.read()
    } else {
        shares * (storage.managed_assets.read() / supply)
    }
}

#[storage(read, write)]
pub fn _mint(recipient: Identity, amount: u64) {
    use std::asset::mint_to;

    let supply = storage.total_supply.read();
    let new_supply = supply + amount;
    storage.total_supply.write(new_supply);
    mint_to(recipient, PRE_CALCULATED_SHARE_VAULT_SUB_ID, amount);
    TotalSupplyEvent::new(vault_assetid(), new_supply, msg_sender().unwrap())
        .log();
}

#[storage(read, write)]
pub fn _burn(asset_id: AssetId, amount: u64) {
    use std::{asset::burn, context::this_balance};

    require(
        this_balance(asset_id) >= amount,
        "BurnError::NotEnoughCoins",
    );
    // If we pass the check above, we can assume it is safe to unwrap.
    let supply = storage.total_supply.read();
    let new_supply = supply - amount;
    storage.total_supply.write(new_supply);
    burn(PRE_CALCULATED_SHARE_VAULT_SUB_ID, amount);
    TotalSupplyEvent::new(vault_assetid(), new_supply, msg_sender().unwrap())
        .log();
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-7-asset-metadata.md

# SRC-7: Onchain Native Asset Metadata

The following standard attempts to define the retrieval of on-chain arbitrary metadata for any [Native Asset](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). This standard should be used if a stateful approach is needed. Any contract that implements the SRC-7 standard MUST implement the [SRC-20](./src-20-native-asset.md) standard.

## Motivation

The SRC-7 standard seeks to enable stateful data-rich assets on the Fuel Network while maintaining compatibility between multiple assets minted by the same contract. The standard ensures type safety with the use of an `enum` and an `Option`. All metadata queries are done through a single function to facilitate cross-contract calls.

## Prior Art

The use of generic metadata was originally found in the Sway-Lib's [NFT Library](https://github.com/FuelLabs/sway-libs/tree/v0.12.0/libs/nft) which did not use Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). This library has since been deprecated.

A previous definition for a metadata standard was written in the original edit of the now defunct [SRC-721](https://github.com/FuelLabs/sway-standards/issues/2). This has since been replaced with the [SRC-20](./src-20-native-asset.md) standard as `SubId` was introduced to enable multiple assets to be minted from a single contract.

The standard takes inspiration from [ENS's public resolver](https://docs.ens.domains/contract-api-reference/publicresolver) with the use of a `String` as the key. This should enable human-readable keys to help minimize errors and enable the standardization of certain keys, such as "image" as opposed to an `enum` or `u64` representation of keys.

We also take a look at existing common metadata practices such as [OpenSea's Metadata Standards](https://docs.opensea.io/docs/metadata-standards) and seek to stay backwards compatible with them while enabling more functionality. Through the combination of `String` keys and various return types, both pre-defined URIs or specific attributes may be stored and retrieved with the SRC-7 standard.

## Specification

### Metadata Type

The following describes an enum that wraps various metadata types into a single return type. There SHALL be the following variants in the `Metadata` enum:

#### `B256`

The `B256` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `Sting` key pair is of the `b256` type.

#### `Bytes`

The `Bytes` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `String` key pair is of the `Bytes` type. The `Bytes` variant should be used when storing custom data such as but not limited to structs and enums.

#### `Int`

The `Int` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `Sting` key pair is of the `u64` type.

#### `String`

The `String` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `String` key pair is of the `String` type. The `String` variant MUST be used when a URI is required but MAY contain any arbitrary `String` data.

### Required Functions

#### `fn metadata(asset: AssetId, key: String) -> Option<Metadata>`

This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `B256`, `Bytes`, `Int`, or `String` variant. If the asset does not exist or no metadata exists, the function MUST return `None`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-7 standard.

* IF a value is updated via a function call, a log MUST be emitted.
* IF a value is embedded in a contract as a constant, configurable, or other manner, an event MUST be emitted at least once.

#### SetMetadataEvent

The `SetMetadataEvent` MUST be emitted when the metadata of an asset has updated.

There SHALL be the following fields in the `SetMetadataEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` for the asset that has been updated.
* `metadata`: The `metadata` field SHALL be used for the corresponding `Option<Metadata>` which represents the metadata of the asset.
* `key`: The `key` field SHALL be used for the corresponding `String` which represents the key used for storing the metadata.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the metadata of the asset.

Example:

```sway
pub struct SetMetadataEvent {
    pub asset: AssetId,
    pub metadata: Option<Metadata>,
    pub key: String,
    pub sender: Identity,
}
```

## Rationale

The SRC-7 standard should allow for stateful data-rich assets to interact with one another in a safe manner.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) and the [SRC-20](./src-20-native-asset.md) standard. It also maintains compatibility with existing standards in other ecosystems.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

## Example ABI

```sway
abi SRC7 {
     #[storage(read)]
     fn metadata(asset: AssetId, key: String) -> Option<Metadata>;
}
```

## Example Implementation

### Single Native Asset

Example of the SRC-7 implementation where metadata exists for only a single asset with one `SubId`.

```sway
contract;

use standards::{
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src7::{
        Metadata,
        SetMetadataEvent,
        SRC7,
    },
};

use std::string::String;

configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
    /// The metadata for the "attr:health" key.
    ATTR_HEALTH: u64 = 100,
}

impl SRC7 for Contract {
    /// Returns metadata for the corresponding `asset` and `key`.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the metadata.
    /// * `key`: [String] - The key to the specific metadata.
    ///
    /// # Returns
    ///
    /// * [Option<Metadata>] - `Some` metadata that corresponds to the `key` or `None`.
    ///
    /// # Reverts
    ///
    /// * When the AssetId provided does not match the default SubId.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src7::{SRC7, Metadata};
    /// use std::string::String;
    ///
    /// fn foo(contract_id: ContractId, asset: AssetId) {
    ///     let contract_abi = abi(SRC7, contract_id);
    ///     let key = String::from_ascii_str("social:x");
    ///     let data = contract_abi.metadata(asset, key);
    ///     assert(data.unwrap() == Metadata::String(String::from_ascii_str("fuel_network")));
    /// }
    /// ```
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        require(asset == AssetId::default(), "Invalid AssetId provided");

        if key == String::from_ascii_str("social:x") {
            Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))))
        } else if key == String::from_ascii_str("site:forum") {
            Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))))
        } else if key == String::from_ascii_str("attr:health") {
            Some(Metadata::Int(ATTR_HEALTH))
        } else {
            None
        }
    }
}

abi EmitSRC7Events {
    fn emit_src7_events();
}

impl EmitSRC7Events for Contract {
    fn emit_src7_events() {
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let metadata_1 = Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))));
        let metadata_2 = Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))));
        let metadata_3 = Some(Metadata::Int(ATTR_HEALTH));
        let key_1 = String::from_ascii_str("social:x");
        let key_2 = String::from_ascii_str("site:forum");
        let key_3 = String::from_ascii_str("attr:health");

        SetMetadataEvent::new(asset, metadata_1, key_1, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_2, key_2, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_3, key_3, sender)
            .log();
    }
}

// SRC7 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, TOTAL_SUPPLY, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-7 implementation where metadata exists for multiple assets with differing `SubId` values.

```sway
contract;

use standards::{
    src20::{
        SetDecimalsEvent,
        SetNameEvent,
        SetSymbolEvent,
        SRC20,
        TotalSupplyEvent,
    },
    src7::{
        Metadata,
        SetMetadataEvent,
        SRC7,
    },
};

use std::{hash::Hash, storage::storage_string::*, string::String};

// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
    /// The decimals of every asset minted by this contract.
    DECIMALS: u8 = 0u8,
    /// The name of every asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of every asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYAST"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
}

storage {
    /// The total number of distinguishable assets this contract has minted.
    total_assets: u64 = 0,
    /// The total supply of a particular asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// The metadata for the "image:svg" key.
    svg_images: StorageMap<AssetId, StorageString> = StorageMap {},
    /// The metadata for the "attr:health" key.
    health_attributes: StorageMap<AssetId, u64> = StorageMap {},
}

impl SRC7 for Contract {
    /// Returns metadata for the corresponding `asset` and `key`.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the metadata.
    /// * `key`: [String] - The key to the specific metadata.
    ///
    /// # Returns
    ///
    /// * [Option<Metadata>] - `Some` metadata that corresponds to the `key` or `None`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src7::{SRC7, Metadata};
    /// use std::string::String;
    ///
    /// fn foo(contract_id: ContractId, asset: AssetId) {
    ///     let contract_abi = abi(SRC7, contract_id);
    ///     let key = String::from_ascii_str("social:x");
    ///     let data = contract_abi.metadata(asset, key);
    ///     assert(data.unwrap() == Metadata::String(String::from_ascii_str("fuel_network")));
    /// }
    /// ```
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        // If this asset does not exist, return None
        if storage.total_supply.get(asset).try_read().is_none() {
            return None
        }

        if key == String::from_ascii_str("social:x") {
            // The "social:x" for all assets minted by this contract are the same.
            Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))))
        } else if key == String::from_ascii_str("site:forum") {
            // The "site:forums" for all assets minted by this contract are the same.
            Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))))
        } else if key == String::from_ascii_str("image:svg") {
            // The SVG image is stored as a String in storage for each asset
            let svg_image = storage.svg_images.get(asset).read_slice();

            match svg_image {
                Some(svg) => Some(Metadata::String(svg)),
                None => None,
            }
        } else if key == String::from_ascii_str("attr:health") {
            // The health attribute is stored as a u64 in storage for each asset
            let health_attribute = storage.health_attributes.get(asset).try_read();

            match health_attribute {
                Some(health) => Some(Metadata::Int(health)),
                None => None,
            }
        } else {
            None
        }
    }
}

abi SetSRC7Events {
    #[storage(read, write)]
    fn set_src7_events(asset: AssetId, svg_image: String, health_attribute: u64);
}

impl SetSRC7Events for Contract {
    #[storage(read, write)]
    fn set_src7_events(asset: AssetId, svg_image: String, health_attribute: u64) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }

        storage.svg_images.try_insert(asset, StorageString {});
        storage.svg_images.get(asset).write_slice(svg_image);
        storage.health_attributes.insert(asset, health_attribute);

        let sender = msg_sender().unwrap();
        let metadata_1 = Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))));
        let metadata_2 = Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))));
        let metadata_3 = Some(Metadata::String(svg_image));
        let metadata_4 = Some(Metadata::Int(health_attribute));
        let key_1 = String::from_ascii_str("social:x");
        let key_2 = String::from_ascii_str("site:forum");
        let key_3 = String::from_ascii_str("image:svg");
        let key_4 = String::from_ascii_str("attr:health");

        SetMetadataEvent::new(asset, metadata_1, key_1, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_2, key_2, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_3, key_3, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_4, key_4, sender)
            .log();
    }
}

// SRC7 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(NAME))),
            None => None,
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(SYMBOL))),
            None => None,
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(DECIMALS),
            None => None,
        }
    }
}

abi SetSRC20Data {
    fn set_src20_data(asset: AssetId, total_supply: u64);
}

impl SetSRC20Data for Contract {
    fn set_src20_data(asset: AssetId, supply: u64) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, supply, sender).log();
    }
}

```


---

### File: docs/nightly/sway-standards/docs/src/src-8-bridged-asset.md

# SRC-8: Bridged Asset

The following standard attempts to define the retrieval of relevant on-chain metadata for any bridged [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). Any contract that implements the SRC-8 standard MUST implement the [SRC-7](./src-7-asset-metadata.md) and [SRC-20](./src-20-native-asset.md) standards.

## Motivation

The SRC-8 standard seeks to enable relevant data for bridged assets on the Fuel Network. This data includes the origin chain, address, ID, decimals, and any arbitrary data. All metadata queries are done through a single function to facilitate cross-contract calls.

## Prior Art

The use of generic metadata for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) is defined in the [SRC-7](./src-7-asset-metadata.md) standard. This standard integrates into the existing [SRC-7](./src-7-asset-metadata.md) standard.

## Specification

### Asset Creation

The `SubId` of the asset MUST be the digest of the `sha256(origin_chain_id, origin_asset_address, origin_asset_id)` hash where:

- `origin_chain_id` is a `String` of the chain ID where the asset was originally minted.
- `origin_asset_address` is a `b256` of the asset's address on the chain where the asset was originally minted.
- `origin_asset_id` is a `b256` of the asset's ID such as an NFT's ID on the chain where the asset was originally minted. IF there is no ID, `b256::zero()` SHALL be used.

### SRC-20 Metadata

Any bridged assets MUST use the name and symbol of the asset on the chain where the asset was originally minted.

### SRC-7 Metadata

#### `bridged:chain`

The key `bridged:chain` SHALL return an `String` variant of the chain ID where the asset was originally minted.

#### `bridged:address`

The key `bridged:address` SHALL return a `B256` variant of the asset's address on the chain where the asset was originally minted. Native assets of a chain that do not have an address such as Ether on Ethereum SHALL use `b256::zero()`.

#### `bridged:id`

The key `bridged:id` MAY return a `B256` variant of the asset's ID such as an NFT's ID on the chain where the asset was originally minted. IF there is no ID, `None` SHALL be returned.

#### `bridged:decimals`

The key `bridged:decimals` MAY return an `Int` variant of the asset's decimals on the chain where the asset was originally minted. IF there are no decimals, `None` SHALL be returned.

## Rationale

The SRC-8 standard should allow for data on any bridged assets on the Fuel Network. This standard builds off existing standards and should allow other contracts to query any relevant information on the bridged asset.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets), the [SRC-20](./src-20-native-asset.md) standard, and the [SRC-7](./src-7-asset-metadata.md) standard.

The standard is also compatible with both tokens and NFTs native to other ecosystems by introducing a token ID element of the original chain.

## Security Considerations

This standard does not call external contracts, nor does it define any mutations of the contract state.

## Example

```sway
impl SRC7 for Contract {
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        if (asset != AssetId::default()) {
            return Option::None;
        }

        match key {
            String::from_ascii_str("bridged:chain") => {
                Option::Some(String::from_ascii_str("1"))
            },
            String::from_ascii_str("bridged:address") => {
                let origin_asset_address = b256::zero();
                Option::Some(Metadata::B256(origin_asset_address))
            },
            String::from_ascii_str("bridged:id") => {
                let origin_asset_id = b256::zero();
                Option::Some(Metadata::B256(origin_asset_id))
            },
            String::from_ascii_str("bridged:decimals") => {
                Option::Some(Metadata::Int(1))
            },
            _ => Option::None,
        }
    }
}

impl SRC20 for Contract {
    fn total_assets() -> u64 {
        1
    }

    fn total_supply(asset: AssetId) -> Option<u64> {
        match asset {
            AssetId::default() => Option::Some(1),
            _ => Option::None,
        }
    }

    fn name(asset: AssetId) -> Option<String> {
        match asset {
            AssetId::default() => Option::Some(String::from_ascii_str("Name")),
            _ => Option::None,
        }
    }

    fn symbol(asset: AssetId) -> Option<String> {
        match asset {
            AssetId::default() => Option::Some(String::from_ascii_str("Symbol")),
            _ => Option::None,
        }
    }

    fn decimals(asset: AssetId) -> Option<u8> {
        match asset {
            AssetId::default() => Option::Some(0u8),
            _ => Option::None,
        }
    }
}
```


---

### File: docs/nightly/sway-standards/docs/src/src-9-metadata-keys.md

# SRC-9: Native Asset

The following standard attempts to define the keys of relevant on-chain metadata for any [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). Any contract that implements the SRC-9 standard MUST implement the [SRC-7](./src-7-asset-metadata.md) and [SRC-20](./src-20-native-asset.md) standards. This is a living standard where revisions may be made as the ecosystem evolves.

## Motivation

The SRC-9 standard seeks to enable relevant data for assets on the Fuel Network. This data may include images, text, contact, or all of the above. All metadata queries are done through a single function to facilitate cross-contract calls.

## Prior Art

The use of generic metadata for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) is defined in the [SRC-7](./src-7-asset-metadata.md) standard. This standard integrates into the existing [SRC-7](./src-7-asset-metadata.md) standard.

## Specification

The following keys are reserved for the SRC-9 standard. Use of the keys should follow the SRC-9 specification.

All keys SHALL use snake case.

### Social

The social prefix SHALL be used for any social media platform and SHALL return usernames.

Any social media metadata keys SHALL follow the following syntax `social:site` where:

- The `social` keyword must be prepended to denote this is a social platform
- The `site` keyword must be the website or platform of the social

#### `social:discord`

The key `social:discord` SHALL return a `String` variant of a username for the Discord platform.

#### `social:facebook`

The key `social:facebook` SHALL return a `String` variant of a username for the Facebook platform.

#### `social:farcaster`

The key `social:farcaster` SHALL return a `String` variant of a username for the Farcaster platform.

#### `social:friend.tech`

The key `social:friend.tech` SHALL return a `String` variant of a username for the Friend.tech platform.

#### `social:github`

The key `social:github` SHALL return a `String` variant of a username for the Github platform.

#### `social:instagram`

The key `social:instagram` SHALL return a `String` variant of a username for the Instagram platform.

#### `social:lens`

The key `social:lens` SHALL return a `String` variant of a username for the Lens Protocol.

#### `social:linkedin`

The key `social:linkedin` SHALL return a `String` variant of a username for the LinkedIn platform.

#### `social:reddit`

The key `social:reddit` SHALL return a `String` variant of a username for the Reddit platform.

#### `social:signal`

The key `social:signal` SHALL return a `String` variant of a username for the Signal platform.

#### `social:telegram`

The key `social:telegram` SHALL return a `String` variant of a username for the Telegram platform.

#### `social:tiktok`

The key `social:tiktok` SHALL return a `String` variant of a username for the TikTok platform.

#### `social:x`

The key `social:x` SHALL return a `String` variant of a username for the X or formerly Twitter platform.

#### `social:wechat`

The key `social:wechat` SHALL return a `String` variant of a username for the WeChat platform.

#### `social:whatsapp`

The key `social:whatsapp` SHALL return a `String` variant of a username for the WhatsApp platform.

#### `social:youtube`

The key `social:youtube` SHALL return a `String` variant of a username for the YouTube platform.

### Contact

The `contact` prefix SHALL be used for any contact information on a particular project's team for an asset.

Any contact information metadata keys SHALL follow the following syntax `contract:type` where:

- The `contact` keyword must be prepended to denote this is contact information
- The `type` keyword must be the method of contact

The key SHALL use snake case.

#### `contact:email`

The key `contact:email` SHALL return a `String` variant of an email.

#### `contact:mailing`

The key `contact:mailing` SHALL return a `String` variant of a mailing address. All mailing addresses MUST follow the UPU addressing format.

#### `contact:phone`

The key `contact:phone` SHALL return a `String` variant of a phone number. All phone numbers SHALL follow the E.164 standard.

#### `contact:company`

The key `contact:company` SHALL return a `String` variant of a company name.

### External Links

The `link` prefix SHALL be used for any external webpage hyperlink associated with an asset.

Any external webpage metadata keys SHALL follow the following syntax `link:site` where:

- The `link` keyword must be prepended to denote this is an external webpage
- The `site` keyword must be an external website

#### `link:home`

The key `link:home` SHALL return a `String` variant of the asset's project homepage.

#### `link:contact`

The key `link:contact` SHALL return a `String` variant of the asset's project contact information webpage.

#### `link:docs`

The key `link:docs` SHALL return a `String` variant of the asset's project documentation webpage.

#### `link:forum`

The key `link:forum` SHALL return a `String` variant of the asset's project forum webpage.

#### `link:blog`

The key `link:blog` SHALL return a `String` variant of the asset's project blog.

#### `link:linktree`

The key `link:linktree` SHALL return a `String` variant of the asset's project linktree information webpage.

### Resources

The `res` prefix SHALL be used for any resources or general information on an asset.

Any resource metadata keys SHALL follow the following syntax `rec:type` where:

- The `res` keyword must be prepended to denote this is a resource
- The `type` keyword must be the type of resource

#### `res:license`

The key `res:license` SHALL return a `String` variant of the asset's project license.

#### `res:tos`

The key `res:tos` SHALL return a `String` variant of the asset's project Terms of Service.

#### `res:author`

The key `res:author` SHALL return a `String` variant of the asset's project author. This MAY be a full name or pseudonym.

#### `res:about`

The key `res:about` SHALL return a `String` variant about the asset's project up to 2048 characters.

#### `res:description`

The key `res:description` SHALL return a `String` variant describing the asset's project up to 256 characters.

#### `res:date`

The key `res:date` SHALL return a `Int` variant of a UNIX timestamp.

#### `res:block`

The key `res:block` SHALL return a `Int` variant of a block number.

### Images

The `image` prefix SHALL be used for any image files associated with a singular asset.

Any image metadata keys SHALL follow the following syntax `image:type` where:

- The `image` keyword must be prepended to denote this is an image
- The `type` keyword must be the file type of the image

#### `image:svg`

The key `image:svg` SHALL return a `String` variant of an SVG image.

#### `image:png`

The key `image:png` SHALL return a `String` variant of a URI for a PNG image.

#### `image:jpeg`

The key `image:jpeg` SHALL return a `String` variant of a URI for a JPEG image.

#### `image:webp`

The key `image:webp` SHALL return a `String` variant of a URI for a WebP image.

#### `image:gif`

The key `image:gif` SHALL return a `String` variant of a URI for a GIF image.

#### `image:heif`

The key `image:heif` SHALL return a `String` variant of a URI for a HEIF image.

### Video

The `video` prefix SHALL be used for any video files associated with a singular asset.

Any video metadata keys SHALL follow the following syntax `video:type` where:

- The `video` keyword must be prepended to denote this is a video
- The `type` keyword must be the file type of the video

#### `video:mp4`

The key `video:mp4` SHALL return a `String` variant of a URI for an MP4 video.

#### `video:webm`

The key `video:webm` SHALL return a `String` variant of a URI for a WebM video.

#### `video:m4v`

The key `video:m4v` SHALL return a `String` variant of a URI for a M4V video.

#### `video:ogv`

The key `video:ogv` SHALL return a `String` variant of a URI for an OGV video.

#### `video:ogg`

The key `video:ogg` SHALL return a `String` variant of a URI for an OGG video.

### Audio

The `audio` prefix SHALL be used for any audio files associated with a singular asset.

Any audio metadata keys SHALL follow the following syntax `audio:type` where:

- The `audio` keyword must be prepended to denote this is audio metadata
- The `type` keyword must be the file type of the audio

#### `audio:mp3`

The key `audio:mp3` SHALL return a `String` variant of a URI for an MP3 file.

#### `audio:wav`

The key `audio:wav` SHALL return a `String` variant of a URI for a WAV file.

#### `audio:oga`

The key `audio:oga` SHALL return a `String` variant of a URI for an OGA file.

### Media

The `media` prefix SHALL be used for any media associated with a particular singular asset.

Any media metadata keys SHALL follow the following syntax `media:type` where:

- The `media` keyword must be prepended to denote this is a video
- The `type` keyword must be the file type of the media

#### `media:gltf`

The key `media:gltf` SHALL return a `String` variant of a URI for a glTF file.

#### `media:glb`

The key `media:glb` SHALL return a `String` variant of a URI for a GLB file.

### Logos

The `logo` prefix SHALL be used for any images associated with a particular asset or project.

Any logo metadata keys SHALL follow the following syntax `logo:type` where:

- The `logo` keyword must be prepended to denote this is a logo
- The `type` keyword must be the type of logo

#### `logo:svg`

The key `logo:svg` SHALL return a `String` variant of an SVG image of a logo.

#### `logo:svg_light`

The key `logo:svg_light` SHALL return a `String` variant of an SVG image of a logo for light themes.

#### `logo:svg_dark`

The key `logo:svg_dark` SHALL return a `String` variant of an SVG image of a logo for dark themes.

#### `logo:small_light`

The key `logo:small_light` SHALL return a `String` variant of a URI for a 32x32 PNG image of a logo for light themes.

#### `logo:small_dark`

The key `logo:small_dark` SHALL return a `String` variant of a URI for a 32x32 PNG image of a logo for dark themes.

#### `logo:medium_light`

The key `logo:medium_light` SHALL return a `String` variant of a URI for a 256x256 PNG image of a logo for light themes.

#### `logo:medium_dark`

The key `logo:medium_dark` SHALL return a `String` variant of a URI for a 256x256 PNG image of a logo for dark themes.

#### `logo:large_light`

The key `logo:large_light` SHALL return a `String` variant of a URI for a 1024x1024 PNG image of a logo for light themes.

#### `logo:large_dark`

The key `logo:large_dark` SHALL return a `String` variant of a URI for a 1024x1024 PNG image of a logo for dark themes.

### Attributes

The `attr` prefix SHALL be used for any attributes associated with a singular asset.

Any attribute metadata keys SHALL follow the following syntax `attr:type` where:

- The `attr` keyword must be prepended to denote this is an attribute
- The `type` keyword must be the type of attribute

There are no standardized types of attributes.
Example: `attr:eyes`.

## Rationale

The SRC-9 standard should allow for standardized keys for metadata on the Fuel Network. This standard builds off existing standards and should allow other contracts to query any relevant information on the asset.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets), the [SRC-20](./src-20-native-asset.md) standard, and the [SRC-7](./src-7-asset-metadata.md) standard.

## Security Considerations

This standard does not call external contracts, nor does it define any mutations of the contract state.

## Example

```sway
impl SRC7 for Contract {
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        if (asset != AssetId::default()) {
            return Option::None;
        }

        match key {
            String::from_ascii_str("social:x") => {
                let social = String::from_ascii_str("fuel_network");
                Option::Some(Metadata::String(social))
            },
            _ => Option::None,
        }
    }
}
```


---

### File: docs/nightly/sway/docs/book/src/advanced/advanced_storage.md

# Advanced Storage

## Nested Storage Collections

Through the use of `StorageKey`s, you may have nested storage collections such as storing a `StorageString` in a `StorageMap<K, V>`.

For example, here we have a few common nested storage types declared in a `storage` block:

```sway
storage {
    nested_map_vec: StorageMap<u64, StorageVec<u8>> = StorageMap {},
    nested_map_string: StorageMap<u64, StorageString> = StorageMap {},
    nested_vec_bytes: StorageVec<StorageBytes> = StorageVec {},
}
```

Please note that storage initialization is needed to do this.

> **NOTE**: When importing a storage type, please be sure to use the glob operator i.e. `use std::storage::storage_vec::*`.

### Storing a `StorageVec<T>` in a `StorageMap<K, V>`

The following demonstrates how to write to a `StorageVec<T>` that is nested in a `StorageMap<T, V>`:

```sway
        // Setup and initialize storage for the StorageVec.
        storage.nested_map_vec.try_insert(10, StorageVec {});

        // Method 1: Push to the vec directly
        storage.nested_map_vec.get(10).push(1u8);
        storage.nested_map_vec.get(10).push(2u8);
        storage.nested_map_vec.get(10).push(3u8);

        // Method 2: First get the storage key and then push the values.
        let storage_key_vec: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        storage_key_vec.push(4u8);
        storage_key_vec.push(5u8);
        storage_key_vec.push(6u8);
        // Setup Bytes to store
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Setup and initialize storage for the StorageBytes.
        storage.nested_vec_bytes.push(StorageBytes {});

        // Method 1: Store the bytes by accessing StorageBytes directly.
        storage
            .nested_vec_bytes
            .get(0)
            .unwrap()
            .write_slice(my_bytes);

        // Method 2: First get the storage key and then write the bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        storage_key.write_slice(my_bytes);
```

The following demonstrates how to read from a `StorageVec<T>` that is nested in a `StorageMap<T, V>`:

```sway
        // Method 1: Access the StorageVec directly.
        let stored_val1: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val2: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val3: u8 = storage.nested_map_vec.get(10).pop().unwrap();

        // Method 2: First get the storage key and then access the value.
        let storage_key: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        let stored_val4: u8 = storage_key.pop().unwrap();
        let stored_val5: u8 = storage_key.pop().unwrap();
        let stored_val6: u8 = storage_key.pop().unwrap();
        // Method 1: Access the stored bytes directly.
        let stored_bytes: Bytes = storage.nested_vec_bytes.get(0).unwrap().read_slice().unwrap();

        // Method 2: First get the storage key and then access the stored bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        let stored_bytes: Bytes = storage_key.read_slice().unwrap();
```

### Storing a `StorageString` in a `StorageMap<K, V>`

The following demonstrates how to write to a `StorageString` that is nested in a `StorageMap<T, V>`:

```sway
        // Setup and initialize storage for the StorageString.
        storage.nested_map_string.try_insert(10, StorageString {});

        // Method 1: Store the string directly.
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.nested_map_string.get(10).write_slice(my_string);

        // Method 2: First get the storage key and then write the value.
        let my_string = String::from_ascii_str("Fuel is modular");
        let storage_key: StorageKey<StorageString> = storage.nested_map_string.get(10);
        storage_key.write_slice(my_string);
```

The following demonstrates how to read from a `StorageString` that is nested in a `StorageMap<T, V>`:

```sway
        // Method 1: Access the string directly.
        let stored_string: String = storage.nested_map_string.get(10).read_slice().unwrap();

        // Method 2: First get the storage key and then access the value.
        let storage_key: StorageKey<StorageString> = storage.nested_map_string.get(10);
        let stored_string: String = storage_key.read_slice().unwrap();
```

### Storing a `StorageBytes` in a `StorageVec<T>`

The following demonstrates how to write to a `StorageBytes` that is nested in a `StorageVec<T>`:

```sway
        // Setup and initialize storage for the StorageVec.
        storage.nested_map_vec.try_insert(10, StorageVec {});

        // Method 1: Push to the vec directly
        storage.nested_map_vec.get(10).push(1u8);
        storage.nested_map_vec.get(10).push(2u8);
        storage.nested_map_vec.get(10).push(3u8);

        // Method 2: First get the storage key and then push the values.
        let storage_key_vec: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        storage_key_vec.push(4u8);
        storage_key_vec.push(5u8);
        storage_key_vec.push(6u8);
        // Setup Bytes to store
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Setup and initialize storage for the StorageBytes.
        storage.nested_vec_bytes.push(StorageBytes {});

        // Method 1: Store the bytes by accessing StorageBytes directly.
        storage
            .nested_vec_bytes
            .get(0)
            .unwrap()
            .write_slice(my_bytes);

        // Method 2: First get the storage key and then write the bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        storage_key.write_slice(my_bytes);
```

The following demonstrates how to read from a `StorageBytes` that is nested in a `StorageVec<T>`:

```sway
        // Method 1: Access the StorageVec directly.
        let stored_val1: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val2: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val3: u8 = storage.nested_map_vec.get(10).pop().unwrap();

        // Method 2: First get the storage key and then access the value.
        let storage_key: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        let stored_val4: u8 = storage_key.pop().unwrap();
        let stored_val5: u8 = storage_key.pop().unwrap();
        let stored_val6: u8 = storage_key.pop().unwrap();
        // Method 1: Access the stored bytes directly.
        let stored_bytes: Bytes = storage.nested_vec_bytes.get(0).unwrap().read_slice().unwrap();

        // Method 2: First get the storage key and then access the stored bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        let stored_bytes: Bytes = storage_key.read_slice().unwrap();
```

## Storage Namespace

If you want the values in storage to be positioned differently, for instance to avoid collisions with storage from another contract when loading code, you can use the namespace annotation to add a salt to the slot calculations.

```sway
storage {
    example_namespace {
        foo: u64 = 0,
    },
```

## Manual Storage Management

It is possible to leverage FuelVM storage operations directly using the `std::storage::storage_api::write` and `std::storage::storage_api::read` functions provided in the standard library. With this approach, you will have to manually assign the internal key used for storage. An example is as follows:

```sway
contract;

use std::storage::storage_api::{read, write};

abi StorageExample {
    #[storage(write)]
    fn store_something(amount: u64);

    #[storage(read)]
    fn get_something() -> u64;
}

const STORAGE_KEY: b256 = 0x0000000000000000000000000000000000000000000000000000000000000000;

impl StorageExample for Contract {
    #[storage(write)]
    fn store_something(amount: u64) {
        write(STORAGE_KEY, 0, amount);
    }

    #[storage(read)]
    fn get_something() -> u64 {
        let value: Option<u64> = read::<u64>(STORAGE_KEY, 0);
        value.unwrap_or(0)
    }
}

```

> **Note**: Though these functions can be used for any data type, they should mostly be used for arrays because arrays are not yet supported in `storage` blocks. Note, however, that _all_ data types can be used as types for keys and/or values in `StorageMap<K, V>` without any restrictions.


---

### File: docs/nightly/sway/docs/book/src/advanced/advanced_types.md

# Advanced Types

## Creating Type Synonyms with Type Aliases

Sway provides the ability to declare a type alias to give an existing type another name. For this we use the `type` keyword. For example, we can create the alias `Kilometers` to `u64` like so:

```sway
type Kilometers = u64;
```

Now, the alias `Kilometers` is a _synonym_ for `u64`. Note that `Kilometers` is **not** a separate new type. Values that have the type `Kilometers` will be treated the same as values of type `u64`:

```sway
    let x: u64 = 5;
    let y: Kilometers = 5;
    assert(x + y == 10);
```

Because `Kilometers` and `u64` are the same type, we can add values of both types and we can pass `Kilometers` values to functions that take `u64` parameters. However, using this method, we don’t get the type checking benefits that we get from introducing a _separate_ new type called `Kilometers`. In other words, if we mix up `Kilometers` and `i32` values somewhere, the compiler will not give us an error.

The main use case for type synonyms is to reduce repetition. For example, we might have a lengthy array type like this:

```sway
[MyStruct<u64, b256>; 5]
```

Writing this lengthy type in function signatures and as type annotations all over the code can be tiresome and error prone. Imagine having a project full of code like this:

```sway
fn foo_long(array: [MyStruct<u64, b256>; 5]) -> [MyStruct<u64, b256>; 5] {
    array
}
type MyArray = [MyStruct<u64, b256>; 5];

fn foo_shorter(array: MyArray) -> MyArray {
    array
}
```

A type alias makes this code more manageable by reducing the repetition. Below, we’ve introduced an alias named `MyArray` for the verbose type and can replace all uses of the type with the shorter alias `MyArray`:

```sway
type MyArray = [MyStruct<u64, b256>; 5];

fn foo_shorter(array: MyArray) -> MyArray {
    array
}
```

This code is much easier to read and write! Choosing a meaningful name for a type alias can help communicate your intent as well.


---

### File: docs/nightly/sway/docs/book/src/advanced/assembly.md

# Inline Assembly in Sway

While many users will never have to touch assembly language while writing Sway code, it is a powerful tool that enables many advanced use-cases (e.g., optimizations, building libraries, etc).

## ASM Block

In Sway, the way we use assembly inline is to declare an `asm` block like this:

```sway
asm() {...}
```

Declaring an `asm` block is similar to declaring a function.
We can specify register names to operate on as arguments, we can perform assembly instructions within the block, and we can return a value by specifying a return register.
Here's an example showing what this might look like:

```sway
pub fn add_1(num: u32) -> u32 {
    asm(r1: num, r2) {
        add r2 r1 one;
        r2: u32
    }
}
```

The return register is specified at the end of the `asm` block, after all the assembly instructions. It consists of the register name and an optional return type. In the above example, the return register name is `r2` and the return type is `u32`.
If the return type is omitted, it is `u64` by default.

The return register itself is optional. If it is not specified, similar to functions, the returned value from the `asm` block will be [unit](../basics/built_in_types.md#unit-type), `()`.

An `asm` block can only return a single register. If you really need to return more than one value, you can modify a tuple. Here's an example showing how you can implement this for `(u64, u64)`:

```sway
script;

fn adder(a: u64, b: u64, c: u64) -> (u64, u64) {
    let empty_tuple = (0u64, 0u64);
    asm(output: empty_tuple, r1: a, r2: b, r3: c, r4, r5) {
        add r4 r1 r2; // add a & b and put the result in r4
        add r5 r2 r3; // add b & c and put the result in r5
        sw output r4 i0; // store the word in r4 in output + 0 words
        sw output r5 i1; // store the word in r5 in output + 1 word
        output: (u64, u64) // return both values
    }
}

fn main() -> bool {
    let (first, second) = adder(1, 2, 3);
    assert(first == 3);
    assert(second == 5);
    true
}

```

Note that this is contrived example meant to demonstrate the syntax; there's absolutely no need to use assembly to add integers!

Note that in the above example:

- we initialized the register `r1` with the value of `num`.
- we declared a second register `r2` (you may choose any register names you want).
- we use the `add` opcode to add `one` to the value of `r1` and store it in `r2`.
- `one` is an example of a "reserved register", of which there are 16 in total. Further reading on this is linked below under "Semantics".
- we return `r2` and specify the return type as being `u32`.

An important note is that the `ji` and `jnei` opcodes are not available within an `asm` block. For those looking to introduce control flow to `asm` blocks, it is recommended to surround smaller chunks of `asm` with control flow (`if`, `else`, and `while`).

## Helpful Links

For examples of assembly in action, check out the [Sway standard library](https://github.com/FuelLabs/sway/tree/master/sway-lib-std).

For a complete list of all instructions supported in the FuelVM: [Instructions](https://fuellabs.github.io/fuel-specs/master/vm/instruction_set).

And to learn more about the FuelVM semantics: [Semantics](https://fuellabs.github.io/fuel-specs/master/vm#semantics).


---

### File: docs/nightly/sway/docs/book/src/advanced/associated_types.md

# Associated Types

Associated types in Sway allow you to define placeholder types within a trait, which can be customized by concrete
implementations of that trait. These associated types are used to specify the return types of trait methods or to
define type relationships within the trait.

Associated types are a powerful feature of Sway's trait system, enabling generic programming and abstraction over
types. They help improve code clarity and maintainability by allowing you to define generic traits without committing
to specific types.

## Declaring Associated Types

Associated types are declared within a trait using the type keyword. Here's the syntax for declaring an associated type:

```sway
trait MyTrait {
    type AssociatedType;
}
```

## Implementing Associated Types

Concrete implementations of a trait with associated types must provide a specific type for each associated type
defined in the trait. Here's an example of implementing a trait with an associated type:

```sway
struct MyStruct;

impl MyTrait for MyStruct {
    type AssociatedType = u32; // Implementing the associated type with u32
}
```

In this example, `MyStruct` implements `MyTrait` and specifies that the associated type `AssociatedType` is `u32`.

## Using Associated Types

Associated types are used within trait methods or where the trait is used as a bound for generic functions or
structs. You can use the associated type like any other type. Here's an example:

```sway
trait MyTrait {
    type AssociatedType;
    
    fn get_value(self) -> Self::AssociatedType;
}

struct MyStruct;

impl MyTrait for MyStruct {
    type AssociatedType = u32;

    fn get_value(self) -> Self::AssociatedType {
        42
    }
}
```

In this example, `get_value` is a trait method that returns an associated type `AssociatedType`.

## Use Cases

Associated types are particularly useful in scenarios where you want to define traits that work with different
types of data structures or abstractions, allowing the implementer to specify the concrete types. Some common use cases include:

- Collections: Traits for generic collections that allow users to specify the type of elements.
- Iterator Patterns: Traits for implementing iterators with varying element types.
- Serialization and Deserialization: Traits for serializing and deserializing data with different data formats.


---

### File: docs/nightly/sway/docs/book/src/advanced/generic_types.md

# Generic Types

## Basics

In Sway, generic types follow a very similar pattern to those in Rust. Let's look at some example syntax,
starting with a generic function:

```sway
fn noop<T>(argument: T) -> T {
    argument
}
```

Here, the `noop()` function trivially returns exactly what was given to it. `T` is a _type parameter_, and it says
that this function exists for all types T. More formally, this function could be typed as:

```math
noop :: ∀T. T -> T
```

Generic types are a way to refer to types _in general_, meaning without specifying a single type. Our `noop` function
would work with any type in the language, so we don't need to specify `noop(argument: u8) -> u8`, `noop(argument: u16) -> u16`, etc.

## Code Generation

One question that arises when dealing with generic types is: how does the assembly handle this? There are a few approaches to handling
generic types at the lowest level. Sway uses a technique called [monomorphization](https://en.wikipedia.org/wiki/Monomorphization). This
means that the generic function is compiled to a non-generic version for every type it is called on. In this way, generic functions are
purely shorthand for the sake of ergonomics.

## Trait Constraints

An important background to know before diving into trait constraints is that the `where` clause can be used to specify the required traits for the generic argument. So, when writing something like a `HashMap` you may
want to specify that the generic argument implements a `Hash` trait.

```sway
fn get_hashmap_key<T>(key: T) -> b256
    where T: Hash
{
    // Code within here can then call methods associated with the Hash trait on Key
}
```

Of course, our `noop()` function is not useful. Often, a programmer will want to declare functions over types which satisfy certain traits.
For example, let's try to implement the successor function, `successor()`, for all numeric types.

```sway
fn successor<T>(argument: T)
    where T: Add
{
    argument + 1
}
```

Run `forc build`, and you will get:

```console
.. |
 9 |   where T: Add
10 |   {
11 |       argument + 1                                        
   |                  ^ Mismatched types: expected type "T" but saw type "u64"
12 |   }
13 |
```

This is because we don't know for a fact that `1`, which in this case defaulted to `1u64`, actually can be added to `T`. What if `T` is `f64`? Or `b256`? What does it mean to add `1u64` in these cases?

We can solve this problem with another trait constraint. We can only find the successor of some value of type `T` if that type `T` defines some incrementor. Let's make a trait:

```sway
trait Incrementable {
    /// Returns the value to add when calculating the successor of a value.
    fn incrementor() -> Self;
}
```

Now, we can modify our `successor()` function:

```sway
fn successor<T>(argument: T)
    where T: Add,
          T: Incrementable
{
    argument + T::incrementor()
}
```

## Generic Structs and Enums

Just like functions, structs and enums can be generic. Let's take a look at the standard library version of `Option<T>`:

```sway
enum Option<T> {
    Some: T,
    None: (),
}
```

Just like an unconstrained generic function, this type exists for all (∀) types `T`. `Result<T, E>` is another example:

```sway
enum Result<T, E> {
    Ok: T,
    Err: E,
}
```

Both generic enums and generic structs can be trait constrained, as well. Consider this struct:

```sway
struct Foo<T>
    where T: Add
{
    field_one: T,
}
```

## Type Arguments

Similar to Rust, Sway has what is colloquially known as the [turbofish](https://github.com/rust-lang/rust/blob/e98309298d927307c5184f4869604bd068d26183/src/test/ui/parser/bastion-of-the-turbofish.rs). The turbofish looks like this: `::<>` (see the little fish with bubbles behind it?). The turbofish is used to annotate types in a generic context. Say you have the following function:

```sway
fn foo<T, E>(t: T) -> Result<T, E> {
    Ok(t)
}
```

In this code example, which is admittedly asinine, you can't possibly know what type `E` is. You'd need to provide the type manually, with a turbofish:

```sway
fn foo<T, E>(t: T) -> Result<T, E> {
    Ok::<T, MyErrorType>(t)
}
```

It is also common to see the turbofish used on the function itself:

```sway
fn main() {
    foo::<Bar, Baz>()
}
```


---

### File: docs/nightly/sway/docs/book/src/advanced/generics_and_trait_constraints.md

# Generics and Trait Constraints

## Generics as Constraints

At a high level, Sway allows you to define constraints, or restrictions, that
allow you to strike a balance between writing abstract and reusable code and
enforcing compile-time checks to determine if the abstract code that you've
written is correct.

The "abstract and reusable" part largely comes from [generic types](./generic_types.md) and the
"enforcing compile-time checks" part largely comes from trait constraints.
Generic types can be used with functions, structs, and enums (as we have seen in
this book), but they can also be used with traits.

## Generic Traits

Combining generic types with traits allows you to write abstract and reusable
traits that can be implemented for any number of data types.

For example, imagine that you want to write a trait for converting between
different types. This would be similar to Rust's `Into` and `From` traits. In
Sway your conversion trait would look something like:

```sway
trait Convert<T> {
    fn from(t: T) -> Self;
}
```

The trait `Convert` takes a generic type `T`. `Convert` has one method
`from`, which takes one parameter of type `T` and returns a `Self`. This means
that when you implement `Convert` for a data type, `from` will return the type
of that data type but will take as input the type that you define as `T`. Here
is an example:

```sway
struct Square {
    width: u64,
}

struct Rectangle {
    width: u64,
    length: u64,
}

impl Convert<Square> for Rectangle {
    fn from(t: Square) -> Self {
        Self {
            width: t.width,
            length: t.width,
        }
    }
}
```

In this example, you have two different data types, `Square` and `Rectangle`.
You know that all squares are rectangles and thus `Square` can convert into `Rectangle` (but not vice
versa) and thus you can implement the conversion trait for those types.

If we want to call these methods we can do so by:

```sway
fn main() {
    let s = Square { width: 5 };
    let r = Rectangle::from(s);
}
```

## Trait Constraints

Trait constraints allow you to use generic types and traits to place constraints
on what abstract code you are willing to accept in your program as correct.
These constraints take the form of compile-time checks for correctness.

If we wanted to use trait constraints with our `Convert` trait from the previous
section we could do so like so:

```sway
fn into_rectangle<T>(t: T) -> Rectangle
where
    Rectangle: Convert<T>,
{
    Rectangle::from(t)
}
```

This function allows you to take any generic data type `T` and convert it to the
type `Rectangle` _as long as `Convert<T>` is implemented for `Rectangle`_.
Calling this function with a type `T` for which `Convert<T>` is not implemented
for `Rectangle` will fail Sway's compile-time checks.


---

### File: docs/nightly/sway/docs/book/src/advanced/index.md

# Advanced Concepts

Advanced concepts.

- [Advanced Types](./advanced_types.md)
- [Advanced Storage](./advanced_storage.md)
- [Generic Types](./generic_types.md)
- [Traits](./traits.md)
- [Associated Types](./associated_types.md)
- [Generics and Trait Constraints](./generics_and_trait_constraints.md)
- [Assembly](./assembly.md)
- [Never Type](./never_type.md)


---

### File: docs/nightly/sway/docs/book/src/advanced/never_type.md

# Never Type

The Never type `!` represents the type of computations which never resolve to any value at all.

## Additional Information

`break`, `continue` and `return` expressions also have type `!`. For example we are allowed to
write:

```sway
let x: ! = {
    return 123
};
```

Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never
assigned a value (because `return` returns from the entire function), `x` can be given type
`Never`. We could also replace `return 123` with a `revert()` or a never-ending `loop` and this code
would still be valid.

A more realistic usage of `Never` is in this code:

```sway
let num: u32 = match get_a_number() {
    Some(num) => num,
    None => break,
};
```

Both match arms must produce values of type [`u32`], but since `break` never produces a value
at all we know it can never produce a value which isn't a [`u32`]. This illustrates another
behaviour of the `!` type - expressions with type `!` will coerce into any other type.

Note that `!` type coerces into any other type, another example of this would be:

```sway
let x: u32 = {
    return 123
};
```

Regardless of the type of `x`, the return block of type `Never` will always coerce into `x` type.

## Examples

```sway
fn foo() {
    let num: u64 = match Option::None::<u64> {
        Some(num) => num,
        None => return,
    };
}
```


---

### File: docs/nightly/sway/docs/book/src/advanced/traits.md

# Traits

## Declaring a Trait

A _trait_ opts a type into a certain type of behavior or functionality that can be shared among types. This allows for easy reuse of code and generic programming. If you have ever used a typeclass in Haskell, a trait in Rust, or even an interface in Java, these are similar concepts.

Let's take a look at some code:

```sway
trait Compare {
    fn equals(self, b: Self) -> bool;
} {
    fn not_equals(self, b: Self) -> bool {
        !self.equals(b)
    }
}
```

We have just declared a trait called `Compare`. After the name of the trait, there are two _blocks_ of code (a _block_ is code enclosed in `{` curly brackets `}`). The first block is the _interface surface_. The second block is the _methods_ provided by the trait. If a type can provide the methods in the interface surface, then it gets access to the methods in the trait for free! What the above trait is saying is: if you can determine if two values are equal, then for free, you can determine that they are not equal. Note that trait methods have access to the methods defined in the interface surface.

## Implementing a Trait

The example below implements a `Compare` trait for `u64` to check if two numbers are equal. Let's take a look at how that is done:

```sway
impl Compare for u64 {
    fn equals(self, b: Self) -> bool {
        self == b
    }
}
```

The above snippet declares all of the methods in the trait `Compare` for the type `u64`. Now, we have access to both the `equals` and `not_equals` methods for `u64`, as long as the trait `Compare` is in scope.

## Supertraits

When using multiple traits, scenarios often come up where one trait may require functionality from another trait. This is where supertraits come in as they allow you to require a trait when implementing another trait, i.e., a trait with a trait.
A good example of this is the `Ord` trait of the `std` library of Sway. The `Ord` trait requires the `Eq` trait, so `Eq` is kept as a separate trait as one may decide to implement `Eq`
without implementing other parts of the `Ord` trait.

```sway

trait Eq {
    fn equals(self, b: Self) -> bool;
}

trait Ord: Eq {
    fn gte(self, b: Self) -> bool;
}

impl Ord for u64 {
    fn gte(self, b: Self) -> bool {
        // As `Eq` is a supertrait of `Ord`, `Ord` can access the equals method
        self.equals(b) || self.gt(b)
    }
}
```

To require a supertrait, add a `:` after the trait name and then list the traits you would like to require and separate them with a `+`.

### ABI supertraits

ABIs can also have supertrait annotations:

```sway
contract;

struct Foo {}
impl ABIsupertrait for Foo {
    fn foo() {}
}

trait ABIsupertrait {
    fn foo();
}

abi MyAbi : ABIsupertrait {
    fn bar();
} {
    fn baz() {
        Self::foo() // supertrait method usage
    }
}

impl ABIsupertrait for Contract {
    fn foo() {}
}

// The implementation of MyAbi for Contract must also implement ABIsupertrait
impl MyAbi for Contract {
    fn bar() {
        Self::foo() // supertrait method usage
    }
}

```

The implementation of `MyAbi` for `Contract` must also implement the `ABIsupertrait` trait. Methods in `ABIsupertrait` are not available externally, i.e. they're not actually contract methods, but they can be used in the actual contract methods, as shown in the example above.

ABI supertraits are intended to make contract implementations compositional, allowing combining orthogonal contract features using, for instance, libraries.

### SuperABIs

In addition to supertraits, ABIs can have _superABI_ annotations:

```sway
contract;

abi MySuperAbi {
    fn foo();
}

abi MyAbi : MySuperAbi {
    fn bar();
}

impl MySuperAbi for Contract {
    fn foo() {}
}

// The implementation of MyAbi for Contract must also implement MySuperAbi
impl MyAbi for Contract {
    fn bar() {}
}

```

The implementation of `MyAbi` for `Contract` must also implement the `MySuperAbi` superABI. Methods in `MySuperAbi` will be part of the `MyAbi` contract interface, i.e. will be available externally (and hence cannot be called from other `MyAbi` contract methods).

SuperABIs are intended to make contract implementations compositional, allowing combining orthogonal contract features using, for instance, libraries.

## Associated Items

Traits can declare different kinds of associated items in their interface surface:

- [Functions](#associated-functions)
- [Constants](#associated-constants)
- [Types](#associated-types)

### Associated functions

Associated functions in traits consist of just function signatures. This indicates that each implementation of the trait for a given type must define all the trait functions.

```sway
trait Trait {
    fn associated_fn(self, b: Self) -> bool;
}
```

### Associated constants

Associated constants are constants associated with a type.

```sway
trait Trait {
    const ID: u32 = 0;
}
```

The initializer expression of an [associated constants](../basics/constants.md#associated-constants) in a trait definition may be omitted to indicate that each implementation of the `trait` for a given type must specify an initializer:

```sway
trait Trait {
    const ID: u32;
}
```

Check the `associated consts` section on [constants](../basics/constants.md) page.

### Associated types

Associated types in Sway allow you to define placeholder types within a trait, which can be customized by concrete
implementations of that trait. These associated types are used to specify the return types of trait methods or to
define type relationships within the trait.

```sway
trait MyTrait {
    type AssociatedType;
}
```

Check the `associated types` section on [associated types](./associated_types.md) page.

## Trait Constraints

When writing generic code, you can constraint the choice of types for a generic argument by using the `where` keyword. The `where` keyword specifies which traits the concrete generic parameter must implement. In the below example, the function `expects_some_trait` can be called only if the parameter `t` is of a type that has `SomeTrait` implemented. To call the `expects_both_traits`, parameter `t` must be of a type that implements _both_ `SomeTrait` and `SomeOtherTrait`.

```sway
trait SomeTrait { }
trait SomeOtherTrait { }

fn expects_some_trait<T>(t: T) where T: SomeTrait {
    // ...
}

fn expects_some_other_trait<T>(t: T) where T: SomeOtherTrait {
    // ...
}

fn expects_both_traits<T>(t: T) where T: SomeTrait + SomeOtherTrait {
    // ...
}
```

## Marker Traits

Sway types can be classified in various ways according to their intrinsic properties. These classifications are represented as marker traits. Marker traits are implemented by the compiler and cannot be explicitly implemented in code.

E.g., all types whose instances can be used in the `panic` expression automatically implement the `Error` marker trait. We can use that trait, e.g., to specify that a generic argument must be compatible with the `panic` expression:

```sway
fn panic_with_error<E>(err: E) where E: Error {
    panic err;
}
```

All marker traits are defined in the `std::marker` module.

## Use Cases

### Custom Types (structs, enums)

Often, libraries and APIs have interfaces that are abstracted over a type that implements a certain trait. It is up to the consumer of the interface to implement that trait for the type they wish to use with the interface. For example, let's take a look at a trait and an interface built off of it.

```sway
library;

pub enum Suit {
    Hearts: (),
    Diamonds: (),
    Clubs: (),
    Spades: (),
}

pub trait Card {
    fn suit(self) -> Suit;
    fn value(self) -> u8;
}

fn play_game_with_deck<T>(a: Vec<T>) where T: Card {
    // insert some creative card game here
}
```

Now, if you want to use the function `play_game_with_deck` with your struct, you must implement `Card` for your struct. Note that the following code example assumes a dependency _games_ has been included in the `Forc.toml` file.

```sway
script;

use games::*;

struct MyCard {
    suit: Suit,
    value: u8
}

impl Card for MyCard {
    fn suit(self) -> Suit {
        self.suit
    }
    fn value(self) -> u8 {
        self.value
    }
}

fn main() {
    let mut i = 52;
    let mut deck: Vec<MyCard> = Vec::with_capacity(50);
    while i > 0 {
        i = i - 1;
        deck.push(MyCard { suit: generate_random_suit(), value: i % 4}
    }
    play_game_with_deck(deck);
}

fn generate_random_suit() -> Suit {
  [ ... ]
}
```


---

### File: docs/nightly/sway/docs/book/src/basics/blockchain_types.md

# Blockchain Types

Sway is fundamentally a blockchain language, and it offers a selection of types tailored for the blockchain use case.

These are provided via the standard library ([`lib-std`](https://github.com/FuelLabs/sway/tree/master/sway-lib-std)) which both add a degree of type-safety, as well as make the intention of the developer more clear.

## `Address` Type

<!-- This section should explain the `Address` type -->
<!-- address:example:start -->
The `Address` type is a type-safe wrapper around the primitive `b256` type. Unlike the EVM, an address **never** refers to a deployed smart contract (see the `ContractId` type below). An `Address` can be either the hash of a public key (effectively an [externally owned account](https://ethereum.org/en/whitepaper/#ethereum-accounts) if you're coming from the EVM) or the hash of a [predicate](../sway-program-types/predicates.md). Addresses own UTXOs.
<!-- address:example:end -->

An `Address` is implemented as follows.

```sway
pub struct Address {
    value: b256,
}
```

Casting between the `b256` and `Address` types must be done explicitly:

```sway
let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_address: Address = Address::from(my_number);
let forty_two: b256 = my_address.into();
```

## `ContractId` Type

<!-- This section should explain the `ContractId` type -->
<!-- contract_id:example:start -->
The `ContractId` type is a type-safe wrapper around the primitive `b256` type. A contract's ID is a unique, deterministic identifier analogous to a contract's address in the EVM. Contracts cannot own UTXOs but can own assets.
<!-- contract_id:example:end -->

A `ContractId` is implemented as follows.

```sway
pub struct ContractId {
    value: b256,
}
```

Casting between the `b256` and `ContractId` types must be done explicitly:

```sway
let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_contract_id: ContractId = ContractId::from(my_number);
let forty_two: b256 = my_contract_id.into();
```

### Getting a Contract's `ContractId`

To get the `ContractId` of a contract in an internal context use the `ContractId::this()` function:

```sway
impl MyContract for Contract {
    fn foo() {
        let this_contract_id: ContractId = ContractId::this();
    }
}
```

## `Identity` Type

<!-- This section should explain the `Identity` type -->
<!-- identity:example:start -->
The `Identity` type is an enum that allows for the handling of both `Address` and `ContractId` types. This is useful in cases where either type is accepted, e.g., receiving funds from an identified sender, but not caring if the sender is an address or a contract.
<!-- identity:example:end -->

An `Identity` is implemented as follows.

```sway
pub enum Identity {
    Address: Address,
    ContractId: ContractId,
}
```

Casting to an `Identity` must be done explicitly:

```sway
        let raw_address: b256 = 0xddec0e7e6a9a4a4e3e57d08d080d71a299c628a46bc609aab4627695679421ca;
        let my_identity: Identity = Identity::Address(Address::from(raw_address));
```

A `match` statement can be used to return to an `Address` or `ContractId` as well as handle cases in which their execution differs.

```sway
        let my_contract_id: ContractId = match my_identity {
            Identity::ContractId(identity) => identity,
            _ => revert(0),
        };
```

```sway
        match my_identity {
            Identity::Address(address) => takes_address(address),
            Identity::ContractId(contract_id) => takes_contract_id(contract_id),
        };
```
<!-- This section should explain the use case for the `Identity` type -->
<!-- use_identity:example:start -->
A common use case for `Identity` is for access control. The use of `Identity` uniquely allows both `ContractId` and `Address` to have access control inclusively.
<!-- use_identity:example:end -->

```sway
        let sender = msg_sender().unwrap();
        require(
            sender == storage
                .owner
                .read(),
            MyError::UnauthorizedUser(sender),
        );
```


---

### File: docs/nightly/sway/docs/book/src/basics/built_in_types.md

# Built-in Types

Every value in Sway is of a certain type. Although deep down, all values are just ones and zeroes in the underlying virtual machine, Sway needs to know what those ones and zeroes actually mean. This is accomplished with _types_.

<!-- This section should explain how Sway types are inferred -->
<!-- sway_types:example:start -->
Sway is a statically typed language. At compile time, the types of every value must be known. This does not mean you need to specify every single type: usually, the type can be reasonably inferred by the compiler.
<!-- sway_types:example:end -->

## Primitive Types

<!-- This section should list the primitive types in Sway -->
<!-- prim_types:example:start -->
Sway has the following primitive types:

1. `()` (unit type)
1. `u8` (8-bit unsigned integer)
1. `u16` (16-bit unsigned integer)
1. `u32` (32-bit unsigned integer)
1. `u64` (64-bit unsigned integer)
1. `u256` (256-bit unsigned integer)
1. `str[]` (fixed-length string)
1. `str` (string slices)
1. `bool` (Boolean `true` or `false`)
1. `b256` (256 bits (32 bytes), i.e. a hash)

All other types in Sway are built up of these primitive types, or references to these primitive types. You may notice that there are no signed integers&mdash;this is by design. In the blockchain domain that Sway occupies, floating-point values and negative numbers have smaller utility, so their implementation has been left up to libraries for specific use cases.
<!-- prim_types:example:end -->

## Unit Type

The unit type, `()`, is a type that allows only one value, and thus, represents a value with no information. It is used to indicate the absence of a meaningful value, or the result of a function that performs an action, but does not return any data. The value of the unit type, called simply unit, has the same symbol as the unit type, `()`. Unit type in Sway serves a similar purpose as `void` in imperative languages like C or Java.

For example:

```Sway
fn returns_unit() -> () { // Here, `()` represent the unit type.
    ()                    // Here, `()` represents the single unit value of the unit type.
}
```

In Sway, if the function return type is not specified, it is `()` by default. Thus, the above example is semantically same as the following:

```Sway
fn returns_unit() {
}
```

## Numeric Types

All of the unsigned integer types are numeric types.

Numbers can be declared with binary syntax, hexadecimal syntax, base-10 syntax, and underscores for delineation. Let's take a look at the following valid numeric primitives:

```sway
0xffffff    // hexadecimal
0b10101010  // binary
10          // base-10
100_000     // underscore delineated base-10
0x1111_0000 // underscore delineated binary
0xfff_aaa   // underscore delineated hexadecimal
```

<!-- This section should explain the default numeric type in Sway -->
<!-- default_num:example:start -->
The default numeric type is `u64`. The FuelVM's word size is 64 bits, and the cases where using a smaller numeric type saves space are minimal.

If a 64-bit or 256-bit arithmetic operation produces an overflow or an underflow,
computation gets reverted automatically by FuelVM.

8/16/32-bit arithmetic operations are emulated using their 64-bit analogues with
additional overflow/underflow checks inserted, which generally results in
somewhat higher gas consumption.

The same does not happen with 256-bit operations, including `b256`, which uses specialized operations and are as efficient as possible.
<!-- default_num:example:end -->

## Boolean Type

<!-- This section should explain the `bool` type -->
<!-- bool:example:start -->
The boolean type (`bool`) has two potential values: `true` or `false`. Boolean values are typically used for conditional logic or validation, for example in `if` expressions. Booleans can be negated, or flipped, with the unary negation operator `!`.
<!-- bool:example:end -->

For example:

```sway
fn returns_false() -> bool {
    let boolean_value: bool = true;
    !boolean_value
}
```

## String Slices

<!-- This section should explain the string type in Sway -->
<!-- str:example:start -->
In Sway, string literals are stored as variable length string slices. Which means that they are stored as a pointer to the actual string data and its length.
<!-- str:example:end -->

```sway
let my_string: str = "fuel";
```

String slices, because they contain pointers have limited usage. They cannot be used as constants, storage fields, or configurable constants, nor as main function arguments or returns.

For these cases one must use string arrays, as described below.

## String Arrays

<!-- This section should explain the string type in Sway -->
<!-- str:example:start -->
In Sway, static-length strings are a primitive type. This means that when you declare a string array, its size is a part of its type. This is necessary for the compiler to know how much memory to give for the storage of that data. The size of the string is denoted with square brackets.
<!-- str:example:end -->

Let's take a look:

```sway
let my_string: str[4] = __to_str_array("fuel");
```

Because the string literal `"fuel"` is four letters, the type is `str[4]`, denoting a static length of 4 characters. Strings default to UTF-8 in Sway.

As above, string literals are typed as string slices. So that is why the need for `__to_str_array` that convert them to string arrays at compile time.

Conversion during runtime can be done with `from_str_array` and `try_as_str_array`. The latter can fail, given that the specified string array must be big enough for the string slice content.

```sway
let a: str = "abcd";
let b: str[4] = a.try_as_str_array().unwrap();
let c: str = from_str_array(b);
```

## Compound Types

_Compound types_ are types that group multiple values into one type. In Sway, we have arrays and tuples.

## Tuple Types

<!-- This section should explain what a tuple is -->
<!-- tuple:example:start -->
A tuple is a general-purpose static-length aggregation of types. In more plain terms, a tuple is a single type that consists of an aggregate of zero or more types. The internal types that make up a tuple, and the tuple's arity, define the tuple's type.
<!-- tuple:example:end -->

Let's take a look at some examples.

```sway
let x: (u64, u64) = (0, 0);
```

This is a tuple, denoted by parenthesized, comma-separated values. Note that the type annotation, `(u64, u64)`, is similar in syntax to the expression which instantiates that type, `(0, 0)`.

```sway
let x: (u64, bool) = (42, true);
assert(x.1);
```

In this example, we have created a new tuple type, `(u64, bool)`, which is a composite of a `u64` and a `bool`.

<!-- This section should explain how to access a value in a tuple -->
<!-- tuple_val:example:start -->
To access a value within a tuple, we use _tuple indexing_: `x.1` stands for the first (zero-indexed, so the `bool`) value of the tuple. Likewise, `x.0` would be the zeroth, `u64` value of the tuple. Tuple values can also be accessed via destructuring.
<!-- tuple_val:example:end -->

```sway
struct Foo {}
let x: (u64, Foo, bool) = (42, Foo {}, true);
let (number, foo, boolean) = x;
```

To create one-arity tuples, we will need to add a trailing comma:

```sway
let x: u64 = (42);     // x is of type u64
let y: (u64) = (42);   // y is of type u64
let z: (u64,) = (42,); // z is of type (u64), i.e. a one-arity tuple
let w: (u64) = (42,);  // type error
```

## Arrays

<!-- This section should explain what an array is -->
<!-- array:example:start -->
An array is similar to a tuple, but an array's values must all be of the same type. Arrays can hold arbitrary types including non-primitive types.
<!-- array:example:end -->

An array is written as a comma-separated list inside square brackets:

```sway
let x = [1, 2, 3, 4, 5];
```

<!-- This section should explain arrays in depth -->
<!-- array_details:example:start -->
Arrays are allocated on the stack since their size is known. An array's size is _always_ static, i.e. it cannot change. An array of five elements cannot become an array of six elements.

Arrays can be iterated over, unlike tuples. An array's type is written as the type the array contains followed by the number of elements, semicolon-separated and within square brackets, e.g., `[u64; 5]`. To access an element in an array, use the _array indexing syntax_, i.e. square brackets.
<!-- array_details:example:end -->

Array elements can also be mutated if the underlying array is declared as mutable:

```sway
let mut x = [1, 2, 3, 4, 5];
x[0] = 0;
```

```sway
script;

struct Foo {
    f1: u32,
    f2: b256,
}

fn main() {
    // Array of integers with type ascription
    let array_of_integers: [u8; 5] = [1, 2, 3, 4, 5];

    // Array of strings
    let array_of_strings = ["Bob", "Jan", "Ron"];

    // Array of structs
    let array_of_structs: [Foo; 2] = [
        Foo {
            f1: 11,
            f2: 0x1111111111111111111111111111111111111111111111111111111111111111,
        },
        Foo {
            f1: 22,
            f2: 0x2222222222222222222222222222222222222222222222222222222222222222,
        },
    ];

    // Accessing an element of an array
    let mut array_of_bools: [bool; 2] = [true, false];
    assert(array_of_bools[0]);

    // Mutating the element of an array
    array_of_bools[1] = true;
    assert(array_of_bools[1]);
}

```


---

### File: docs/nightly/sway/docs/book/src/basics/comments_and_logging.md

# Comments and Logging

## Comments

<!-- This section should explain how to add comments in Sway -->
<!-- comments:example:start -->
Comments in Sway start with two slashes and continue until the end of the line. For comments that extend beyond a single line, you'll need to include `//` on each line.
<!-- comments:example:end -->

```sway
// hello world
```

```sway
// let's make a couple of lines
// commented.
```

You can also place comments at the ends of lines containing code.

```sway
fn main() {
    let baz = 8; // Eight is a lucky number
}
```

You can also do block comments

```sway
fn main() {
    /*
    You can write on multiple lines
    like this if you want
    */
    let baz = 8;
}
```

## Logging

<!-- This section should explain logging in Sway -->
<!-- logging:example:start -->
The `logging` library provides a generic `log` function that can be imported using `use std::logging::log` and used to log variables of any type. Each call to `log` appends a `receipt` to the list of receipts. There are two types of receipts that a `log` can generate: `Log` and `LogData`.
<!-- logging:example:end -->

```sway
fn log_values(){
  // Generates a Log receipt
  log(42);

  // Generates a LogData receipt
  let string = "sway";
  log(string);
}
```

### `Log` Receipt

<!-- This section should explain when `Log` receipts are produced -->
<!-- log_rec:example:start -->
The `Log` receipt is generated for _non-reference_ types, namely `bool`, `u8`, `u16`, `u32`, and `u64`.
<!-- log_rec:example:end -->

For example, logging an integer variable `x` that holds the value `42` using `log(x)` may generate the following receipt:

```console
"Log": {
  "id": "0000000000000000000000000000000000000000000000000000000000000000",
  "is": 10352,
  "pc": 10404,
  "ra": 42,
  "rb": 1018205,
  "rc": 0,
  "rd": 0
}
```

Note that `ra` will include the value being logged. The additional registers `rc` and `rd` will be zero when using `log` while `rb` may include a non-zero value representing a unique ID for the `log` instance. The unique ID is not meaningful on its own but allows the Rust and the TS SDKs to know the type of the data being logged, by looking up the log ID in the JSON ABI file.

### `LogData` Receipt

<!-- This section should explain when `LogData` receipts are produced -->
<!-- log_data_rec:example:start -->
`LogData` is generated for _reference_ types which include all types except for _non_reference_ types; and for  _non-reference_ types bigger than 64-bit integers, for example, `u256`;
<!-- log_data_rec:example:end -->

For example, logging a `b256` variable `b` that holds the value `0x1111111111111111111111111111111111111111111111111111111111111111` using `log(b)` may generate the following receipt:

```console
"LogData": {
  "data": "1111111111111111111111111111111111111111111111111111111111111111",
  "digest": "02d449a31fbb267c8f352e9968a79e3e5fc95c1bbeaa502fd6454ebde5a4bedc",
  "id": "0000000000000000000000000000000000000000000000000000000000000000",
  "is": 10352,
  "len": 32,
  "pc": 10444,
  "ptr": 10468,
  "ra": 0,
  "rb": 1018194
}
```

Note that `data` in the receipt above will include the value being logged as a hexadecimal. Similarly to the `Log` receipt, additional registers are written: `ra` will always be zero when using `log`, while `rb` will contain a unique ID for the `log` instance.

> **Note**
> The Rust SDK exposes [APIs](https://fuellabs.github.io/fuels-rs/master/calling-contracts/logs.html#logs) that allow you to retrieve the logged values and display them nicely based on their types as indicated in the JSON ABI file.


---

### File: docs/nightly/sway/docs/book/src/basics/commonly_used_library_types.md

# Commonly Used Library Types

The Sway Standard Library is the foundation of portable Sway software, a set of minimal shared abstractions for the broader Sway ecosystem. It offers core types, library-defined operations on language primitives, native asset management, blockchain contextual operations, access control, storage management, and support for types from other VMs, among many other things. Reference the standard library docs [here](https://fuellabs.github.io/sway/master/std/index.html).

## `Result<T, E>`

<!-- This section should explain what the `Result` type is -->
<!-- result:example:start -->
Type `Result` is the type used for returning and propagating recoverable errors. It is an `enum` with two variants: `Ok(T)`, representing success and containing a value, and `Err(E)`, representing error and containing an error value. The `T` and `E` in this definition are type parameters, allowing `Result` to be generic and to be used with any types.
<!-- result:example:end -->

```sway
/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
pub enum Result<T, E> {
    /// Contains the success value.
    Ok: T,
    /// Contains the error value.
    Err: E,
}
```

<!-- This section should explain when to use the `Result` type -->
<!-- use_result:example:start -->
Functions return `Result` whenever errors are expected and recoverable.
<!-- use_result:example:end -->

Take the following example:

```sway
script;

enum MyContractError {
    DivisionByZero: (),
}

fn divide(numerator: u64, denominator: u64) -> Result<u64, MyContractError> {
    if (denominator == 0) {
        return Err(MyContractError::DivisionByZero);
    } else {
        Ok(numerator / denominator)
    }
}

fn main() -> Result<u64, str[4]> {
    let result = divide(20, 2);
    match result {
        Ok(value) => Ok(value),
        Err(MyContractError::DivisionByZero) => Err(__to_str_array("Fail")),
    }
}

```

To learn more about expressing irrecoverable errors in Sway, see the chapter on [Error Handling](error_handling.md).

## `Option<T>`

<!-- This section should explain the `Option` type -->
<!-- option:example:start -->
Type `Option` represents an optional value: every `Option` is either `Some` and contains a value, or `None`, and does not. `Option` types are very common in Sway code, as they have a number of uses:

- Initial values where `None` can be used as an initializer.
- Return value for otherwise reporting simple errors, where `None` is returned on error.

The implementation of `Option` matches on the variant: if it's `Ok` it returns the inner value, if it's `None`, it [reverts](https://github.com/FuelLabs/fuel-specs/blob/master/src/fuel-vm/instruction-set.md#rvrt-revert).
<!-- option:example:end -->

```sway
/// A type that represents an optional value, either `Some(val)` or `None`.
pub enum Option<T> {
    /// No value.
    None: (),
    /// Some value of type `T`.
    Some: T,
}
```

<!-- This section should explain when to use the `Option` type -->
<!-- use_option:example:start -->
`Option` is commonly paired with pattern matching to query the presence of a value and take action, allowing developers to choose how to handle the `None` case.
<!-- use_option:example:end -->

Below is an example that uses pattern matching to handle invalid divisions by 0 by returning an `Option`:

```sway
script;

fn divide(numerator: u64, denominator: u64) -> Option<u64> {
    if denominator == 0 {
        None
    } else {
        Some(numerator / denominator)
    }
}

fn main() {
    let result = divide(6, 2);
    // Pattern match to retrieve the value
    match result {
        // The division was valid
        Some(x) => std::logging::log(x),
        // The division was invalid
        None => std::logging::log("Cannot divide by 0"),
    }
}

```


---

### File: docs/nightly/sway/docs/book/src/basics/constants.md

# Constants

<!-- This section should explain what constants are in Sway -->
<!-- constants:example:start -->
Constants are similar to variables; however, there are a few differences:

- Constants are always evaluated at compile-time.
- Constants can be declared both inside of a [function](../index.md) and at global / `impl` scope.
- The `mut` keyword cannot be used with constants.
<!-- constants:example:end -->

```sway
const ID: u32 = 0;
```

Constant initializer expressions can be quite complex, but they cannot use, for
instance, assembly instructions, storage access, mutable variables, loops and
`return` statements. Although, function calls, primitive types and compound data
structures are perfectly fine to use:

```sway
fn bool_to_num(b: bool) -> u64 {
    if b {
        1
    } else {
        0
    }
}

fn arr_wrapper(a: u64, b: u64, c: u64) -> [u64; 3] {
    [a, b, c]
}

const ARR2 = arr_wrapper(bool_to_num(1) + 42, 2, 3);
```

## Associated Constants

<!-- This section should explain what associated constants are -->
<!-- assoc_constants:example:start -->
Associated constants are constants associated with a type and can be declared in an `impl` block or in a `trait` definition.

Associated constants declared inside a `trait` definition may omit their initializers to indicate that each implementation of the trait must specify those initializers.

The identifier is the name of the constant used in the path. The type is the type that the
definition has to implement.
<!-- assoc_constants:example:end -->

You can _define_ an associated `const` directly in the interface surface of a trait:

```sway
script;

trait ConstantId {
    const ID: u32 = 0;
}
```

Alternatively, you can also _declare_ it in the trait, and implement it in the interface of the
types implementing the trait.

```sway
script;

trait ConstantId {
    const ID: u32;
}

struct Struct {}

impl ConstantId for Struct {
    const ID: u32 = 1;
}

fn main() -> u32 {
    Struct::ID
}
```

### `impl self` Constants

Constants can also be declared inside non-trait `impl` blocks.

```sway
script;

struct Point {
    x: u64,
    y: u64,
}

impl Point {
    const ZERO: Point = Point { x: 0, y: 0 };
}

fn main() -> u64  {
    Point::ZERO.x
}
```

## Configurable Constants

<!-- This section should explain what configurable constants are in Sway -->
<!-- config_constants:example:start -->
Configurable constants are special constants that behave like regular constants in the sense that they cannot change during program execution, but they can be configured _after_ the Sway program has been built. The Rust and TS SDKs allow updating the values of these constants by injecting new values for them directly in the bytecode without having to build the program again. These are useful for contract factories and behave somewhat similarly to `immutable` variables from languages like Solidity.
<!-- config_constants:example:end -->

Configurable constants are declared inside a `configurable` block and require a type ascription and an initializer as follows:

```sway
configurable {
    U8: u8 = 8u8,
    BOOL: bool = true,
    ARRAY: [u32; 3] = [253u32, 254u32, 255u32],
    STR_4: str[4] = __to_str_array("fuel"),
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8u8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}
```

At most one `configurable` block is allowed in a Sway project. Moreover, `configurable` blocks are not allowed in libraries.

Configurable constants can be read directly just like regular constants:

```sway
    fn return_configurables() -> (u8, bool, [u32; 3], str[4], StructWithGeneric<u8>) {
        (U8, BOOL, ARRAY, STR_4, STRUCT)
    }
```


---

### File: docs/nightly/sway/docs/book/src/basics/control_flow.md

# Control Flow

## `if` expressions

<!-- This section should explain `if` expressions in Sway -->
<!-- if:example:start -->
Sway supports _if_, _else_, and _else if_ expressions that allow you to branch your code depending on conditions.
<!-- if:example:end -->

For example:

```sway
fn main() {
    let number = 6;

    if number % 4 == 0 {
        // do something
    } else if number % 3 == 0 {
        // do something else
    } else {
        // do something else
    }
}
```

### Using `if` in a `let` statement

Like Rust, `if`s are expressions in Sway. What this means is you can use `if` expressions on the right side of a `let` statement to assign the outcome to a variable.

```sway
let my_data = if some_bool < 10 { foo() } else { bar() };
```

Note that all branches of the `if` expression must return a value of the same type.

### `match` expressions

<!-- This section should explain `match` expressions in Sway -->
<!-- match:example:start -->
Sway supports advanced pattern matching through exhaustive `match` expressions. Unlike an `if` expression, a `match` expression asserts **at compile time** that all possible patterns have been matched. If you don't handle all the patterns, you will get compiler error indicating that your `match` expression is non-exhaustive.
<!-- match:example:end -->

The basic syntax of a `match` expression is as follows:

```sway
let result = match expression {
    pattern1 => code_to_execute_if_expression_matches_pattern1,
    pattern2 => code_to_execute_if_expression_matches_pattern2,
    pattern3 | pattern4 => code_to_execute_if_expression_matches_pattern3_or_pattern4
    ...
    _ => code_to_execute_if_expression_matches_no_pattern,
}
```

Some examples of how you can use a `match` expression:

```sway
script;

// helper functions for our example
fn on_even(num: u64) {
    // do something with even numbers
}
fn on_odd(num: u64) {
    // do something with odd numbers
}

fn main(num: u64) -> u64 {
    // Match as an expression
    let is_even = match num % 2 {
        0 => true,
        _ => false,
    };

    // Match as control flow
    let x = 12;
    match x {
        5 => on_odd(x),
        _ => on_even(x),
    };

    // Match an enum
    enum Weather {
        Sunny: (),
        Rainy: (),
        Cloudy: (),
        Snowy: (),
    }
    let current_weather = Weather::Sunny;
    let avg_temp = match current_weather {
        Weather::Sunny => 80,
        Weather::Rainy => 50,
        Weather::Cloudy => 60,
        Weather::Snowy => 20,
    };

    let is_sunny = match current_weather {
        Weather::Sunny => true,
        Weather::Rainy | Weather::Cloudy | Weather::Snowy => false,
    };

    // match expression used for a return
    let outside_temp = Weather::Sunny;
    match outside_temp {
        Weather::Sunny => 80,
        Weather::Rainy => 50,
        Weather::Cloudy => 60,
        Weather::Snowy => 20,
    }
}

```

## Loops

### `while`

This is what a `while` loop looks like:

```sway
while counter < 10 {
    counter = counter + 1;
}
```

You need the `while` keyword, some condition (`value < 10` in this case) which will be evaluated each iteration, and a block of code inside the curly braces (`{...}`) to execute each iteration.

### `for`

This is what a `for` loop that computes the sum of a vector of numbers looks like:

```sway
for element in vector.iter() {
    sum += element;
}
```

You need the `for` keyword, some pattern that contains variable names such as `element` in this case, the `ìn` keyword followed by an iterator, and a block of code inside the curly braces (`{...}`) to execute each iteration. `vector.iter()` in the example above returns an iterator for the `vector`. In each iteration, the value of `element` is updated with the next value in the iterator until the end of the vector is reached and the `for` loop iteration ends.

Modifying the `vector` during iteration, by e.g. adding or removing elements, is a logical error and results in an [undefined behavior](../reference/undefined_behavior.md):

```sway
// The behavior of this `for` loop is undefined because
// the `vector` gets modified within the loop.
for element in vector.iter() {
    if element == 3 {
        vector.push(6); // Modification of the vector!
    }
}
```

### `break` and `continue`

`break` and `continue` keywords are available to use inside the body of a `while` or `for` loop. The purpose of the `break` statement is to break out of a loop early:

```sway
fn break_example() -> u64 {
    let mut counter = 1;
    let mut sum = 0;
    let num = 10;
    while true {
        if counter > num {
            break;
        }
        sum += counter;
        counter += 1;
    }
    sum // 1 + 2 + .. + 10 = 55
}
```

The purpose of the `continue` statement is to skip a portion of a loop in an iteration and jump directly into the next iteration:

```sway
fn continue_example() -> u64 {
    let mut counter = 0;
    let mut sum = 0;
    let num = 10;
    while counter < num {
        counter += 1;
        if counter % 2 == 0 {
            continue;
        }
        sum += counter;
    }
    sum // 1 + 3 + .. + 9 = 25
}
```

### Nested loops

You can also use nested `while` loops if needed:

```sway
while condition_1 == true {
    // do stuff...
    while condition_2 == true {
        // do more stuff...
    }
}
```


---

### File: docs/nightly/sway/docs/book/src/basics/converting_types.md

# Converting Types

Below are some common type conversions in Sway:

- [Identity Conversions](#identity-conversions)
- [String Conversions](#string-conversions)
- [Number Conversions](#number-conversions)
- [Byte Array Conversions](#byte-array-conversions)

## Identity Conversions

### Convert to `Identity`

```sway
    let identity_from_b256: Identity = Identity::Address(Address::from(b256_address));
    let identity_from_address: Identity = Identity::Address(address);
    let identity_from_contract_id: Identity = Identity::ContractId(contract_id);
```

### Convert `Identity` to `ContractId` or `Address`

```sway
    match my_identity {
        Identity::Address(address) => log(address),
        Identity::ContractId(contract_id) => log(contract_id),
    };
```

### Convert `ContractId` or `Address` to `b256`

```sway
    let b256_from_address: b256 = address.into();
    let b256_from_contract_id: b256 = contract_id.into();
```

### Convert `b256` to `ContractId` or `Address`

```sway
    let address_from_b256: Address = Address::from(b256_address);
    let contract_id_from_b256: ContractId = ContractId::from(b256_address);
```

## String Conversions

### Convert `str` to `str[]`

```sway
    let fuel_str: str = "fuel";
    let fuel_str_array: str[4] = fuel_str.try_as_str_array().unwrap();
```

### Convert `str[]` to `str`

```sway
    let fuel_str_array: str[4] = __to_str_array("fuel");
    let fuel_str: str = from_str_array(fuel_str_array);
```

## Number Conversions

### Convert to `u256`

```sway
    let u8_1: u8 = 2u8;
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2u64;
    let b256_1: b256 = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20;

    let u256_from_u8: u256 = u8_1.as_u256();
    let u256_from_u16: u256 = u16_1.as_u256();
    let u256_from_u32: u256 = u32_1.as_u256();
    let u256_from_u64: u256 = u64_1.as_u256();
    let u256_from_b256: u256 = b256_1.as_u256();
```

### Convert to `u64`

```sway
    let u8_1: u8 = 2u8;
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u64_from_u8: u64 = u8_1.as_u64();

    let u64_from_u16: u64 = u16_1.as_u64();

    let u64_from_u32: u64 = u32_1.as_u64();

    let u64_from_u256: Option<u64> = <u64 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `u32`

```sway
    let u8_1: u8 = 2u8;
    let u16_1: u16 = 2u16;
    let u64_1: u64 = 2;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u32_from_u8: u32 = u8_1.as_u32();

    let u32_from_u16: u32 = u16_1.as_u32();

    let u32_from_u64_1: Option<u32> = u64_1.try_as_u32();
    let u32_from_u64_2: Option<u32> = <u32 as TryFrom<u64>>::try_from(u64_1);

    let u32_from_u256: Option<u32> = <u32 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `u16`

```sway
    let u8_1: u8 = 2u8;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u16_from_u8: u16 = u8_1.as_u16();

    let u16_from_u32_1: Option<u16> = u32_1.try_as_u16();
    let u16_from_u32_2: Option<u16> = <u16 as TryFrom<u32>>::try_from(u32_1);

    let u16_from_u64_1: Option<u16> = u64_1.try_as_u16();
    let u16_from_u64_2: Option<u16> = <u16 as TryFrom<u64>>::try_from(u64_1);

    let u16_from_u256: Option<u16> = <u16 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `u8`

```sway
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u8_from_u16_1: Option<u8> = u16_1.try_as_u8();
    let u8_from_u16_2: Option<u8> = <u8 as TryFrom<u16>>::try_from(u16_1);

    let u8_from_u32_1: Option<u8> = u32_1.try_as_u8();
    let u8_from_u32_2: Option<u8> = <u8 as TryFrom<u32>>::try_from(u32_1);

    let u8_from_u64_1: Option<u8> = u64_1.try_as_u8();
    let u8_from_u64_2: Option<u8> = <u8 as TryFrom<u64>>::try_from(u64_1);

    let u8_from_u256: Option<u8> = <u8 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `Bytes`

```sway
use std::{bytes::Bytes, bytes_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*}};
```

```sway
use std::{bytes::Bytes, bytes_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*}};
    let num = 5;
    let little_endian_bytes: Bytes = num.to_le_bytes();
    let big_endian_bytes: Bytes = num.to_be_bytes();
```

### Convert from `Bytes`

```sway
use std::{bytes::Bytes, bytes_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*}};
```

```sway
    let u16_from_le_bytes: u16 = u16::from_le_bytes(little_endian_bytes);
    let u16_from_be_bytes: u16 = u16::from_be_bytes(big_endian_bytes);

    let u32_from_le_bytes: u32 = u32::from_le_bytes(little_endian_bytes);
    let u32_from_be_bytes: u32 = u32::from_be_bytes(big_endian_bytes);

    let u64_from_le_bytes: u64 = u64::from_le_bytes(little_endian_bytes);
    let u64_from_be_bytes: u64 = u64::from_be_bytes(big_endian_bytes);

    let u256_from_le_bytes = u256::from_le_bytes(little_endian_bytes);
    let u256_from_be_bytes = u256::from_be_bytes(big_endian_bytes);

    let b256_from_le_bytes = b256::from_le_bytes(little_endian_bytes);
    let b256_from_be_bytes = b256::from_be_bytes(big_endian_bytes);
```

## Byte Array Conversions

### Convert to a Byte Array

```sway
use std::array_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*};
```

```sway
use std::array_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*};
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2u64;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;
    let b256_1: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
    // little endian
    let le_byte_array_from_u16: [u8; 2] = u16_1.to_le_bytes();
    let le_byte_array_from_u32: [u8; 4] = u32_1.to_le_bytes();
    let le_byte_array_from_u64: [u8; 8] = u64_1.to_le_bytes();
    let le_byte_array_from_u256: [u8; 32] = u256_1.to_le_bytes();
    let le_byte_array_from_b256: [u8; 32] = b256_1.to_le_bytes();
    // big endian
    let be_byte_array_from_u16: [u8; 2] = u16_1.to_be_bytes();
    let be_byte_array_from_u32: [u8; 4] = u32_1.to_be_bytes();
    let be_byte_array_from_u64: [u8; 8] = u64_1.to_be_bytes();
    let be_byte_array_from_u256: [u8; 32] = u256_1.to_be_bytes();
    let be_byte_array_from_b256: [u8; 32] = b256_1.to_be_bytes();
```

### Convert from a Byte Array

```sway
use std::array_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*};
```

```sway
    let u16_byte_array: [u8; 2] = [2_u8, 1_u8];
    let u32_byte_array: [u8; 4] = [4_u8, 3_u8, 2_u8, 1_u8];
    let u64_byte_array: [u8; 8] = [8_u8, 7_u8, 6_u8, 5_u8, 4_u8, 3_u8, 2_u8, 1_u8];
    let u256_byte_array: [u8; 32] = [
        32_u8, 31_u8, 30_u8, 29_u8, 28_u8, 27_u8, 26_u8, 25_u8, 24_u8, 23_u8, 22_u8,
        21_u8, 20_u8, 19_u8, 18_u8, 17_u8, 16_u8, 15_u8, 14_u8, 13_u8, 12_u8, 11_u8,
        10_u8, 9_u8, 8_u8, 7_u8, 6_u8, 5_u8, 4_u8, 3_u8, 2_u8, 1_u8,
    ];
    // little endian
    let le_u16_from_byte_array: u16 = u16::from_le_bytes(u16_byte_array);
    let le_u32_from_byte_array: u32 = u32::from_le_bytes(u32_byte_array);
    let le_u64_from_byte_array: u64 = u64::from_le_bytes(u64_byte_array);
    let le_u256_from_byte_array: u256 = u256::from_le_bytes(u256_byte_array);
    let le_b256_from_byte_array: b256 = b256::from_le_bytes(u256_byte_array);
    // big endian
    let be_u16_from_byte_array: u16 = u16::from_be_bytes(u16_byte_array);
    let be_u32_from_byte_array: u32 = u32::from_be_bytes(u32_byte_array);
    let be_u64_from_byte_array: u64 = u64::from_be_bytes(u64_byte_array);
    let be_u256_from_byte_array: u256 = u256::from_be_bytes(u256_byte_array);
    let be_b256_from_byte_array: b256 = b256::from_be_bytes(u256_byte_array);
```


---

### File: docs/nightly/sway/docs/book/src/basics/error_handling.md

# Error Handling

## Recoverable Errors

Recoverable errors represent expected faults. Similar to Rust, Sway expresses recoverable errors by using the `std::result::Result` enum, letting you propagate or transform the error without immediately reverting the transaction.

To learn more about expressing and handling recoverable errors, see the chapter on [`Result<T, E>` enum](commonly_used_library_types.md#resultt-e).

## Irrecoverable Errors

Irrecoverable errors indicate bugs or violated invariants. They trigger a VM-wide revert that atomically rolls back every state change in the transaction, and it cannot be caught or handled in Sway code, signaling that the program cannot sensibly continue.

### `panic` Expression

The recommended way of expressing an irrecoverable errors is to use the `panic` expression:

```sway
if some_error_occurred {
    panic "Some error has occurred.";
}
```

At runtime, the `panic` expression aborts and reverts the execution of the entire program. At compile time, for each `panic` encountered in code, Sway compiler will generate a unique revert code and create an entry in the ABI JSON `errorCodes` section. The generated `errorCodes` entry will contain the information about source location at which the `panic` occurs, as well as the error message.

**This mechanism allows for getting a rich troubleshooting information, without an additional on-chain cost.** The generated bytecode will contain only the revert instruction, and the remaining information, the error message and the error location, are stored off-chain, in the ABI JSON file.

For example, let's assume that the above code is situated in the module `some_module`, contained within the version `v1.2.3` of the package `some_package`.

At runtime, the `panic` will result in a compiler generated revert code, e.g., 18446744069414584323. At compile time, an entry similar to this will be added to the ABI JSON `errorCodes` section:

```json
"errorCodes": {
    "18446744069414584323": {
        "pos": {
          "pkg": "some_package@1.2.3",
          "file": "some_module.sw",
          "line": 13,
          "column": 9
        },
        "logId": null,
        "msg": "Some error has occurred."
    },
}
```

Rust and TypeScript SDK, as well as `forc test`, recognize revert codes generated from `panic` expressions. E.g., if a Sway unit test fails because of a revert caused by the above `panic` line, the `forc test` will display the following:

```console
test some_test, "path/to/failing/test.sw":42
    revert code: ffffffff00000003
    ├─ panic message: Some error has occurred.
    └─ panicked in:   some_package@1.2.3, src/some_module.sw:13:9
```

### Error Types

Passing textual error messages directly as a `panic` argument is the most convenient way to provide a helpful error message. It is sufficient for many use-cases. However, often we want:

- to provide an additional runtime information about the error.
- group a certain family of errors together.

For these use-cases, you can use _error types_. Error types are enums annotated with the `#[error_type]` attribute, whose all variants are attributed with the `#[error(m = "<error message>")]` attributes. Each variant represent a particular error, and the enum itself the family of errors. The convention is to postfix the names of error type enums with `Error`.

For example, let's assume we are checking if a provided `Identity` has certain access rights to our contract. The error type enum representing access rights violations could look like:

```sway
#[error_type]
pub enum AccessRightError {
    #[error(m = "The provided identity is not an administrator.")]
    NotAnAdmin: Identity,
    #[error(m = "The provided identity is not an owner.")]
    NotAnOwner: Identity,
    #[error(m = "The provided identity does not have write access.")]
    NoWriteAccess: Identity,
}
```

where each `Identity` represents the actual, provided identity.

In code, we can now check for access rights and panic if they are violated:

```sway
fn do_something_that_requires_admin_access(admin: Identity) {
    if !is_admin(admin) {
        panic AccessRightError::NotAnAdmin(admin);
    }

    // ...
}
```

Assuming we have a failing test for the above function, the test output will show the error message, but also the provided `Identity`. E.g.:

```console
test some_test_for_admin_access, "path/to/failing/test.sw":42
    revert code: ffffffff00000007
    ├─ panic message: The provided identity is not an administrator.
    ├─ panic value:   NotAnAdmin(Address(Address()))
    └─ panicked in:   some_other_package@0.1.0, src/admin_module.sw:11:9
```


---

### File: docs/nightly/sway/docs/book/src/basics/functions.md

# Functions

Functions in Sway are declared with the `fn` keyword. Let's take a look:

```sway
fn equals(first_param: u64, second_param: u64) -> bool {
    first_param == second_param
}
```

We have just declared a function named `equals` which takes two parameters: `first_param` and `second_param`. The parameters must both be 64-bit unsigned integers.

This function also returns a `bool` value, i.e. either `true` or `false`. This function returns `true` if the two given parameters are equal, and `false` if they are not. If we want to use this function, we can do so like this:

```sway
fn main() {
    equals(5, 5); // evaluates to `true`
    equals(5, 6); // evaluates to `false`
}
```

## Mutable Parameters

<!-- This section should explain how/when to use `ref mut` -->
<!-- ref_mut:example:start -->
We can make a function parameter mutable by adding `ref mut` before the parameter name. This allows mutating the argument passed into the function when the function is called.
<!-- ref_mut:example:end -->

For example:

```sway
fn increment(ref mut num: u32) {
    let prev = num;
    num = prev + 1u32;
}
```

This function is allowed to mutate its parameter `num` because of the `mut` keyword. In addition, the `ref` keyword instructs the function to modify the argument passed to it when the function is called, instead of modifying a local copy of it.

```sway
    let mut num: u32 = 0;
    increment(num);
    assert(num == 1u32); // The function `increment()` modifies `num`
```

Note that the variable `num` itself has to be declared as mutable for the above to compile.

> **Note**
> It is not currently allowed to use `mut` without `ref` or vice versa for a function parameter.

Similarly, `ref mut` can be used with more complex data types such as:

```sway
fn swap_tuple(ref mut pair: (u64, u64)) {
    let temp = pair.0;
    pair.0 = pair.1;
    pair.1 = temp;
}

fn update_color(ref mut color: Color, new_color: Color) {
    color = new_color;
}
```

We can then call these functions as shown below:

```sway
    let mut tuple = (42, 24);
    swap_tuple(tuple);
    assert(tuple.0 == 24); // The function `swap_tuple()` modifies `tuple.0`
    assert(tuple.1 == 42); // The function `swap_tuple()` modifies `tuple.1`
    let mut color = Color::Red;
    update_color(color, Color::Blue);
    assert(match color {
        Color::Blue => true,
        _ => false,
    }); // The function `update_color()` modifies the color to Blue
```

> **Note**
> The only place, in a Sway program, where the `ref` keyword is valid is before a mutable function parameter.


---

### File: docs/nightly/sway/docs/book/src/basics/index.md

# Sway Language Basics

Sway is a programming language designed for the FuelVM. It is a statically typed, compiled language with type inference and traits. Sway aims to make smart contract development safer and more efficient through the use of strong static analysis and compiler feedback.

Get started with the basics of Sway:

- [Variables](./variables.md)
- [Built-in Types](./built_in_types.md)
- [Commonly Used Library Types](./commonly_used_library_types.md)
- [Blockchain Types](./blockchain_types.md)
- [Functions](./functions.md)
- [Structs, Tuples, and Enums](./structs_tuples_and_enums.md)
- [Methods and Associated Functions](./methods_and_associated_functions.md)
- [Constants](./constants.md)
- [Comments and Logging](./comments_and_logging.md)
- [Control Flow](./control_flow.md)
- [Error Handling](./error_handling.md)


---

### File: docs/nightly/sway/docs/book/src/basics/methods_and_associated_functions.md

# Methods and Associated Functions

<!-- This section should explain methods & associated functions in Sway -->
<!-- methods_af:example:start -->
## Methods

Methods are similar to [functions](functions.md) in that we declare them with the `fn` keyword and they have parameters and return a value. However, unlike functions, _Methods_ are defined within the context of a struct (or enum), and either refers to that type or mutates it. The first parameter of a method is always `self`, which represents the instance of the struct (or enum) the method is being called on.

## Associated Functions

_Associated functions_ are very similar to _methods_, in that they are also defined in the context of a struct or enum, but they do not actually use any of the data in the struct and as a result do not take _self_ as a parameter. Associated functions could be standalone functions, but they are included in a specific type for organizational or semantic reasons.

### Constructors

Constructors are associated functions that construct, or in other words instantiate, new instances of a type. Their return type is always the type itself. E.g., public structs that have private fields must provide a public constructor, or otherwise they cannot be instantiated outside of the module in which they are declared.

## Declaring Methods and Associated Functions

To declare methods and associated functions for a struct or enum, use an `impl` block. Here, `impl` is short for implementation.
<!-- methods_af:example:end -->

```sway
script;

struct Foo {
    bar: u64,
    baz: bool,
}

impl Foo {
    // this is a _method_, as it takes `self` as a parameter.
    fn is_baz_true(self) -> bool {
        self.baz
    }

    // this is an _associated function_, since it does not take `self` as a parameter.
    // it is at the same time a _constructor_ because it instantiates and returns
    // a new instance of `Foo`.
    fn new_foo(number: u64, boolean: bool) -> Foo {
        Foo {
            bar: number,
            baz: boolean,
        }
    }
}

fn main() {
    let foo = Foo::new_foo(42, true);
    assert(foo.is_baz_true());
}

```

<!-- This section should explain how to call a method -->
<!-- call_method:example:start -->
To call a method, simply use dot syntax: `foo.iz_baz_true()`.
<!-- call_method:example:end -->

<!-- This section should explain how methods + assoc. fns can accept `ref mut` params -->
<!-- ref_mut:example:start -->
Similarly to [free functions](functions.md), methods and associated functions may accept `ref mut` parameters.
<!-- ref_mut:example:end -->

For example:

```sway
struct Coordinates {
    x: u64,
    y: u64,
}

impl Coordinates {
    fn move_right(ref mut self, distance: u64) {
        self.x += distance;
    }
}
```

and when called:

```sway
    let mut point = Coordinates { x: 1, y: 1 };
    point.move_right(5);
    assert(point.x == 6);
    assert(point.y == 1);
```


---

### File: docs/nightly/sway/docs/book/src/basics/structs_tuples_and_enums.md

# Structs, Tuples, and Enums

## Structs

<!-- This section should explain structs in Sway -->
<!-- structs:example:start -->
Structs in Sway are a named grouping of types. You may also be familiar with structs via another name: _product types_. Sway does not make any significantly unique usages of structs; they are similar to most other languages which have structs. If you're coming from an object-oriented background, a struct is like the data attributes of an object.

Those data attributes are called _fields_ and can be either public or private.

Private struct fields can be accessed only within the module in which their struct is declared. Public fields are accessible everywhere where the struct is accessible. This access control on the field level allows more fine grained encapsulation of data.

<!-- structs:example:end -->

To explain these concepts, let's take a look at the following example, in which we have a module called _data_structures_.

In that module, we declare a struct named `Foo` with two fields. The first field is named `bar`, it is public and it accepts values of type `u64`. The second field is named `baz`, it is also public and it accepts `bool` values.

In a similar way, we define the structs `Point`, `Line`, and `TupleInStruct`. Since all those structs are public, and all their fields are public, they can be instantiated in other modules using the _struct instantiation syntax_ as shown below.

On the other hand, the struct `StructWithPrivateFields` can be instantiated only within the _data_structures_ module, because it contains private fields. To be able to create instances of such structs outside of the module in which they are declared, the struct must offer [constructor associated functions](methods_and_associated_functions.md#constructors).

```sway
// the _data_structures_ module
library;

// Declare a struct type
pub struct Foo {
    pub bar: u64,
    pub baz: bool,
}

// Struct types for destructuring
pub struct Point {
    pub x: u64,
    pub y: u64,
}

pub struct Line {
    pub p1: Point,
    pub p2: Point,
}

pub struct TupleInStruct {
    pub nested_tuple: (u64, (u32, (bool, str))),
}

// Struct type instantiable only in the module _data_structures_
pub struct StructWithPrivateFields {
    pub public_field: u64,
    private_field: u64,
    other_private_field: u64,
}

```

<!-- This section should explain how to instantiate a struct in Sway -->
<!-- new_struct:example:start -->
In order to instantiate the struct we use _struct instantiation syntax_, which is very similar to the declaration syntax except with expressions in place of types.

There are three ways to instantiate the struct.

- Hard coding values for the fields
- Passing in variables with names different than the struct fields
- Using a shorthand notation via variables that are the same as the field names
<!-- new_struct:example:end -->

```sway
library;

mod data_structures;
use data_structures::{Foo, Line, Point, TupleInStruct};

fn hardcoded_instantiation() -> Foo {
    // Instantiate `foo` as `Foo`
    let mut foo = Foo {
        bar: 42,
        baz: false,
    };

    // Access and write to "baz"
    foo.baz = true;

    // Return the struct
    foo
}

fn variable_instantiation() -> Foo {
    // Declare variables with the same names as the fields in `Foo`
    let number = 42;
    let truthness = false;

    // Instantiate `foo` as `Foo`
    let mut foo = Foo {
        bar: number,
        baz: truthness,
    };

    // Access and write to "baz"
    foo.baz = true;

    // Return the struct
    foo
}

fn shorthand_instantiation() -> Foo {
    // Declare variables with the same names as the fields in `Foo`
    let bar = 42;
    let baz = false;

    // Instantiate `foo` as `Foo`
    let mut foo = Foo { bar, baz };

    // Access and write to "baz"
    foo.baz = true;

    // Return the struct
    foo
}

fn struct_destructuring() {
    let point1 = Point { x: 0, y: 0 };
    // Destructure the values from the struct into variables
    let Point { x, y } = point1;

    let point2 = Point { x: 1, y: 1 };
    // If you do not care about specific struct fields then use ".." at the end of your variable list
    let Point { x, .. } = point2;

    let line = Line {
        p1: point1,
        p2: point2,
    };
    // Destructure the values from the nested structs into variables
    let Line {
        p1: Point { x: x0, y: y0 },
        p2: Point { x: x1, y: y1 },
    } = line;
    // You may also destructure tuples nested in structs and structs nested in tuples
    let tuple_in_struct = TupleInStruct {
        nested_tuple: (42u64, (42u32, (true, "ok"))),
    };
    let TupleInStruct {
        nested_tuple: (a, (b, (c, d))),
    } = tuple_in_struct;

    let struct_in_tuple = (Point { x: 2, y: 4 }, Point { x: 3, y: 6 });
    let (Point { x: x0, y: y0 }, Point { x: x1, y: y1 }) = struct_in_tuple;
}

```

> **Note**
> You can mix and match all 3 ways to instantiate the struct at the same time.
> Moreover, the order of the fields does not matter when instantiating however we encourage declaring the fields in alphabetical order and instantiating them in the same alphabetical order

Furthermore, multiple variables can be extracted from a struct using the destructuring syntax.

### Struct Memory Layout

> **Note**
> This information is not vital if you are new to the language, or programming in general

Structs have zero memory overhead. What that means is that in memory, each struct field is laid out sequentially. No metadata regarding the struct's name or other properties is preserved at runtime. In other words, structs are compile-time constructs. This is the same in Rust, but different in other languages with runtimes like Java.

## Tuples

<!-- This section should explain what tuples are and how to access tuple values -->
<!-- tuples:example:start -->
Tuples are a [basic static-length type](./built_in_types.md#tuple-types) which contain multiple different types within themselves. The type of a tuple is defined by the types of the values within it, and a tuple can contain basic types as well as structs and enums.

You can access values directly by using the `.` syntax. Moreover, multiple variables can be extracted from a tuple using the destructuring syntax.
<!-- tuples:example:end -->

```sway
library;

fn tuple() {
    // You can declare the types yourself
    let tuple1: (u8, bool, u64) = (100, false, 10000);

    // Or have the types be inferred
    let mut tuple2 = (5, true, ("Sway", 8));

    // Retrieve values from tuples
    let number = tuple1.0;
    let sway = tuple2.2.1;

    // Destructure the values from the tuple into variables
    let (n1, truthness, n2) = tuple1;

    // If you do not care about specific values then use "_"
    let (_, truthness, _) = tuple2;

    // Internally mutate the tuple
    tuple2.1 = false;

    // Or change the values all at once (must keep the same data types)
    tuple2 = (9, false, ("Fuel", 99));
}

```

## Enums

<!-- This section should explain what enums are -->
<!-- enums:example:start -->
_Enumerations_, or _enums_, are also known as _sum types_. An enum is a type that could be one of several variants. To declare an enum, you enumerate all potential variants.
<!-- enums:example:end -->

Here, we have defined five potential colors. Each enum variant is just the color name. As there is no extra data associated with each variant, we say that each variant is of type `()`, or unit.

```sway
library;

// Declare the enum
enum Color {
    Blue: (),
    Green: (),
    Red: (),
    Silver: (),
    Grey: (),
}

fn main() {
    // To instantiate a variable with the value of an enum the syntax is
    let blue = Color::Blue;
    let silver = Color::Silver;
}

```

### Enums of Structs

It is also possible to have an enum variant contain extra data. Take a look at this more substantial example, which combines struct declarations with enum variants:

```sway
library;

struct Item {
    price: u64,
    amount: u64,
    id: u64,
}

enum MyEnum {
    Item: Item,
}

fn main() {
    let my_enum = MyEnum::Item(Item {
        price: 5,
        amount: 2,
        id: 42,
    });
}

```

### Enums of Enums

It is possible to define enums of enums:

```sway
library;

pub enum Error {
    StateError: StateError,
    UserError: UserError,
}

pub enum StateError {
    Void: (),
    Pending: (),
    Completed: (),
}

pub enum UserError {
    InsufficientPermissions: (),
    Unauthorized: (),
}

```

#### Preferred usage

The preferred way to use enums is to use the individual (not nested) enums directly because they are easy to follow and the lines are short:

```sway
library;

use ::enum_of_enums::{StateError, UserError};

fn preferred() {
    let error1 = StateError::Void;
    let error2 = UserError::Unauthorized;
}

```

#### Inadvisable

If you wish to use the nested form of enums via the `Error` enum from the example above, then you can instantiate them into variables using the following syntax:

```sway
library;

use ::enum_of_enums::{Error, StateError, UserError};

fn avoid() {
    let error1 = Error::StateError(StateError::Void);
    let error2 = Error::UserError(UserError::Unauthorized);
}

```

Key points to note:

- You must import all of the enums you need instead of just the `Error` enum
- The lines may get unnecessarily long (depending on the names)
- The syntax is not the most ergonomic

### Enum Memory Layout

> **Note**
> This information is not vital if you are new to the language, or programming in general.

Enums do have some memory overhead. To know which variant is being represented, Sway stores a one-word (8-byte) tag for the enum variant. The space reserved after the tag is equivalent to the size of the _largest_ enum variant. So, to calculate the size of an enum in memory, add 8 bytes to the size of the largest variant. For example, in the case of `Color` above, where the variants are all `()`, the size would be 8 bytes since the size of the largest variant is 0 bytes.


---

### File: docs/nightly/sway/docs/book/src/basics/variables.md

# Variables

<!-- This section should explain how variables are immutable -->
<!-- immutable_vars:example:start -->
Variables in Sway are _immutable by default_. This means that, by default, once a variable is declared, its value cannot change. This is one of the ways how Sway encourages safe programming, and many modern languages have this same default.
<!-- immutable_vars:example:end -->

Let's take a look at variables in detail.

## Declaring a Variable

Let's look at a variable declaration:

```sway
let foo = 5;
```

Great! We have just declared a variable, `foo`. What do we know about `foo`?

1. It is immutable.
1. Its value is `5`.
1. Its type is `u64`, a 64-bit unsigned integer.

`u64` is the default numeric type, and represents a 64-bit unsigned integer. See the section [Built-in Types](./built_in_types.md) for more details.

We can also make a mutable variable. Let's take a look:

```sway
let mut foo = 5;
foo = 6;
```

Now, `foo` is mutable, and the reassignment to the number `6` is valid. That is, we are allowed to _mutate_ the variable `foo` to change its value.

When assigning to a mutable variable, the right-hand side of the assignment is evaluated before the left-hand side. In the below example, the mutable variable `i` will first be increased and the resulting value of `1` will be stored to `array[1]`, thus resulting in `array` being changed to `[0, 1, 0]`.

```sway
let mut array = [0, 0, 0];
let mut i = 0;

array[i] = {
    i += 1;
    i
};
```

## Type Annotations

<!-- This section should explain type annotations -->
<!-- type_annotations:example:start -->
A variable declaration can contain a _type annotation_. A type annotation serves the purpose of declaring the type, in addition to the value, of a variable.
<!-- type_annotations:example:end -->

Let's take a look:

```sway
let foo: u32 = 5;
```

We have just declared the _type_ of the variable `foo` as a `u32`, which is an unsigned 32-bit integer. Let's take a look at a few other type annotations:

```sway
let bar: str[4] = __to_str_array("sway");
let baz: bool = true;
```

<!-- This section should explain what happens if there is a type conflict -->
<!-- type_conflict:example:start -->
If the value declared cannot be assigned to the declared type, there will be an error generated by the compiler.
<!-- type_conflict:example:end -->


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/access_control.md

# Access Control

<!-- This section should explain access control in Sway -->
<!-- access_control:example:start -->
Smart contracts require the ability to restrict access to and identify certain users or contracts. Unlike account-based blockchains, transactions in UTXO-based blockchains (i.e. Fuel) do not necessarily have a unique transaction sender. Additional logic is needed to handle this difference, and is provided by the standard library.
<!-- access_control:example:end -->

## `msg_sender`

<!-- This section should explain what the `msg_sender` method is -->
<!-- msg_sender:example:start -->
To deliver an experience akin to the EVM's access control, the `std` library provides a `msg_sender` function, which identifies a unique caller based upon the call and/or transaction input data.
<!-- msg_sender:example:end -->

```sway
contract;

abi MyOwnedContract {
    fn receive(field_1: u64) -> bool;
}

const OWNER = Address::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);

impl MyOwnedContract for Contract {
    fn receive(field_1: u64) -> bool {
        let sender = msg_sender().unwrap();
        if let Identity::Address(addr) = sender {
            assert(addr == OWNER);
        } else {
            revert(0);
        }

        true
    }
}

```

<!-- This section should explain how the `msg_sender` method works -->
<!-- msg_sender_details:example:start -->
The `msg_sender` function works as follows:

- If the caller is a contract, then `Ok(Sender)` is returned with the `ContractId` sender variant.
- If the caller is external (i.e. from a script), then all coin input owners in the transaction are checked. If all owners are the same, then `Ok(Sender)` is returned with the `Address` sender variant.
- If the caller is external and coin input owners are different, then the caller cannot be determined and a `Err(AuthError)` is returned.
<!-- msg_sender_details:example:end -->

## Contract Ownership

Many contracts require some form of ownership for access control. The [SRC-5 Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) has been defined to provide an interoperable interface for ownership within contracts.

To accomplish this, use the [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html) to keep track of the owner. This allows setting and revoking ownership using the variants `Some(..)` and `None` respectively. This is better, safer, and more readable than using the `Identity` type directly where revoking ownership has to be done using some magic value such as `b256::zero()` or otherwise.

- The following is an example of how to properly lock a function such that only the owner may call a function:

```sway
    #[storage(read)]
    fn only_owner() {
        storage.owner.only_owner();
        // Do stuff here
    }
```

Setting ownership can be done in one of two ways; During compile time or run time.

- The following is an example of how to properly set ownership of a contract during compile time:

```sway
storage {
    owner: Ownership = Ownership::initialized(Identity::Address(Address::zero())),
}
```

- The following is an example of how to properly set ownership of a contract during run time:

```sway
    #[storage(write)]
    fn set_owner(identity: Identity) {
        storage.owner.set_ownership(identity);
    }
```

- The following is an example of how to properly revoke ownership of a contract:

```sway
    #[storage(write)]
    fn revoke_ownership() {
        storage.owner.renounce_ownership();
    }
```

- The following is an example of how to properly retrieve the state of ownership:

```sway
    #[storage(read)]
    fn owner() -> State {
        storage.owner.owner()
    }
```

## Access Control Libraries

[Sway-Libs](../reference/sway_libs.md) provides the following libraries to enable further access control.

- [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html); used to apply restrictions on functions such that only a **single** user may call them. This library provides helper functions for the [SRC-5; Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md).
- [Admin Library](https://fuellabs.github.io/sway-libs/book/admin/index.html); used to apply restrictions on functions such that only a select few users may call them like a whitelist.
- [Pausable Library](https://fuellabs.github.io/sway-libs/book/pausable/index.html); allows contracts to implement an emergency stop mechanism.
- [Reentrancy Guard Library](https://fuellabs.github.io/sway-libs/book/reentrancy/index.html); used to detect and prevent reentrancy attacks.


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/calling_contracts.md

# Calling Contracts

Smart contracts can be _called_ by other contracts or scripts. In the FuelVM, this is done primarily with the [`call`](https://fuellabs.github.io/fuel-specs/master/vm/instruction_set#call-call-contract) instruction.

Sway provides a nice way to manage callable interfaces with its ABI system. The Fuel ABI specification can be found [here](https://fuellabs.github.io/fuel-specs/master/protocol/abi).

## Example

Here is an example of a contract calling another contract in Sway. A script can call a contract in the same way.

```sway
// ./contract_a.sw
contract;

abi ContractA {
    fn receive(field_1: bool, field_2: u64) -> u64;
}

impl ContractA for Contract {
    fn receive(field_1: bool, field_2: u64) -> u64 {
        assert(field_1 == true);
        assert(field_2 > 0);
        return_45()
    }
}

fn return_45() -> u64 {
  45
}
```

```sway
// ./contract_b.sw
contract;

use contract_a::ContractA;

abi ContractB {
    fn make_call();
}

const contract_id = 0x79fa8779bed2f36c3581d01c79df8da45eee09fac1fd76a5a656e16326317ef0;

impl ContractB for Contract {
    fn make_call() {
      let x = abi(ContractA, contract_id);
      let return_value = x.receive(true, 3); // will be 45
    }
}
```

> **Note**: The ABI is for external calls only therefore you cannot define a method in the ABI and call it in the same contract. If you want to define a function for a contract, but keep it private so that only your contract can call it, you can define it outside of the `impl` and call it inside the contract, similar to the `return_45()` function above.

## Advanced Calls

All calls forward a gas stipend, and may additionally forward one native asset with the call.

Here is an example of how to specify the amount of gas (`gas`), the asset ID of the native asset (`asset_id`), and the amount of the native asset (`coins`) to forward:

```sway
script;

abi MyContract {
    fn foo(field_1: bool, field_2: u64);
}

fn main() {
    let x = abi(MyContract, 0x79fa8779bed2f36c3581d01c79df8da45eee09fac1fd76a5a656e16326317ef0);
    let asset_id = 0x7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777;
    x.foo {
        gas: 5000, asset_id: asset_id, coins: 5000
    }
    (true, 3);
}
```

## Handling Re-entrancy

A common attack vector for smart contracts is [re-entrancy](https://docs.soliditylang.org/en/v0.8.4/security-considerations.html#re-entrancy). Similar to the EVM, the FuelVM allows for re-entrancy.

A _stateless_ re-entrancy guard is included in the [`sway-libs`](https://fuellabs.github.io/sway-libs/book/reentrancy/index.html) library. The guard will panic (revert) at run time if re-entrancy is detected.

```sway
contract;

use reentrancy::reentrancy_guard;

abi MyContract {
    fn some_method();
}

impl ContractB for Contract {
    fn some_method() {
        reentrancy_guard();
        // do something
    }
}
```

### CEI pattern violation static analysis

Another way of avoiding re-entrancy-related attacks is to follow the so-called
_CEI_ pattern. CEI stands for "Checks, Effects, Interactions", meaning that the
contract code should first perform safety checks, also known as
"pre-conditions", then perform effects, i.e. modify or read the contract storage
and execute external contract calls (interaction) only at the very end of the
function/method.

Please see this [blog post](https://fravoll.github.io/solidity-patterns/checks_effects_interactions.html)
for more detail on some vulnerabilities in case of storage modification after
interaction and this [blog post](https://chainsecurity.com/curve-lp-oracle-manipulation-post-mortem) for
more information on storage reads after interaction.

The Sway compiler implements a check that the CEI pattern is not violated in the
user contract and issues warnings if that's the case.

For example, in the following contract the CEI pattern is violated, because an
external contract call is executed before a storage write.

```sway
contract;

mod other_contract;

use other_contract::*;
use std::hash::*;

abi MyContract {
    #[storage(read, write)]
    fn withdraw(external_contract_id: ContractId);
}

storage {
    balances: StorageMap<Identity, u64> = StorageMap::<Identity, u64> {},
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn withdraw(external_contract_id: ContractId) {
        let sender = msg_sender().unwrap();
        let bal = storage.balances.get(sender).try_read().unwrap_or(0);

        assert(bal > 0);

        // External call
        let caller = abi(OtherContract, external_contract_id.into());
        caller.external_call {
            coins: bal,
        }();

        // Storage update _after_ external call
        storage.balances.insert(sender, 0);
    }
}

```

Here, `other_contract` is defined as follows:

```sway
library;

abi OtherContract {
    #[payable]
    fn external_call();
}

```

The CEI pattern analyzer issues a warning as follows, pointing to the
interaction before a storage modification:

```sh
warning
  --> /path/to/contract/main.sw:28:9
   |
26 |
27 |           let caller = abi(OtherContract, external_contract_id.into());
28 |           caller.external_call { coins: bal }();
   |  _________-
29 | |
30 | |         // Storage update _after_ external call
31 | |         storage.balances.insert(sender, 0);
   | |__________________________________________- Storage write after external contract interaction in function or method "withdraw". Consider making all storage writes before calling another contract
32 |       }
33 |   }
   |
____
```

In case there is a storage read after an interaction, the CEI analyzer will issue a similar warning.

In addition to storage reads and writes after an interaction, the CEI analyzer reports analogous warnings about:

- balance tree updates, i.e. balance tree reads with subsequent writes, which may be produced by the `tr` and `tro` ASM instructions or library functions using them under the hood;
- balance trees reads with `bal` instruction;
- changes to the output messages that can be produced by the `__smo` intrinsic function or the `smo` ASM instruction.

## Differences from the EVM

While the Fuel contract calling paradigm is similar to the EVM's (using an ABI, forwarding gas and data), it differs in _two_ key ways:

1. [**Native assets**](./native_assets.md): FuelVM calls can forward any native asset not just base asset.

2. **No data serialization**: Contract calls in the FuelVM do not need to serialize data to pass it between contracts; instead they simply pass a pointer to the data. This is because the FuelVM has a shared global memory which all call frames can read from.

## Fallback

When a contract is compiled, a special section called "contract selection" is also generated. This section checks if the contract call method matches any of the available ABI methods. If this fails, one of two possible actions will happen:

1 - if no fallback function was specified, the contract will revert;
2 - otherwise, the fallback function will be called.

For all intents and purposes the fallback function is considered a contract method, which means that it has all the limitations that other contract methods have. As for the fallback function signature, the function cannot have arguments, but it can return anything.

If for some reason the fallback function needs to returns different types, the intrinsic `__contract_ret` can be used.

```sway
contract;

abi MyContract {
    fn some_method();
}

impl MyContract for Contract {
    fn some_method() {
    }
}

#[fallback]
fn fallback() {
}
```

You may still access the method selector and call arguments in the fallback function.
For instance, let's assume a function `fn foobar(bool, u64) {}` gets called on a contract that doesn't have it, with arguments `true` and `42`.
It can execute the following fallback:

```sway
#[fallback]
fn fallback() {
    // the method selector is the first four bytes of sha256("foobar(bool,u64)")
    // per https://fuellabs.github.io/fuel-specs/master/protocol/abi#function-selector-encoding
    let method_selector = std::call_frames::first_param::<u64>();

    // the arguments tuple is (true, 42)
    let arguments = std::call_frames::second_param::<(bool, u64)>();
}
```


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/external_code.md

# External Code Execution

The `std-lib` includes a function called `run_external` that allows Sway contracts to execute arbitrary external Sway code.

This functionality enables features like upgradeable contracts and
proxies.

## Upgradeable Contracts

Upgradeable contracts are designed to allow the logic of a smart contract to be updated after deployment.

Consider this example proxy contract:

```sway
#[namespace(my_storage_namespace)]
storage {
    target_contract: Option<ContractId> = None,
}

impl Proxy for Contract {
    #[storage(write)]
    fn set_target_contract(id: ContractId) {
        storage.target_contract.write(Some(id));
    }

    #[storage(read)]
    fn double_input(_value: u64) -> u64 {
        let target = storage.target_contract.read().unwrap();
        run_external(target)
    }
}
```

The contract has two functions:

- `set_target_contract` updates the `target_contract` variable in storage with the `ContractId` of an external contract.
- `double_input` reads the `target_contract` from storage and uses it to run external code. If the `target_contract` has a function with the same name (`double_input`), the code in the external `double_input` function will run.
In this case, the function will return a `u64`.

Notice in the `Proxy` example above, the storage block has a `namespace` attribute. Using this attribute is considered a best practice for all proxy contracts in Sway, because it will prevent storage collisions with the implementation contract, as the implementation contract has access to both storage contexts.

Below is what an implementation contract could look like for this:

```sway
storage {
    value: u64 = 0,
    // to stay compatible, this has to stay the same in the next version
}

impl Implementation for Contract {
    #[storage(write)]
    fn double_input(value: u64) -> u64 {
        let new_value = value * 2;
        storage.value.write(new_value);
        new_value
    }
}
```

This contract has one function called `double_input`, which calculates the input value times two, updates the `value` variable in storage, and returns the new value.

## How does this differ from calling a contract?

There are a couple of major differences between calling a contract directly and using the `run_external` method.

First, to use `run_external`, the ABI of the external contract is not required. The proxy contract has no knowledge of the external contract except for its `ContractId`.

### Upgradeable Contract Storage

Second, the storage context of the proxy contract is retained for the loaded code.
This means that in the examples above, the `value` variable gets updated in the storage for the *proxy* contract.

For example, if you were to read the `value` variable by directly calling the implementation contract, you would get a different result than if you read it through the proxy contract.
The proxy contract loads the code and executes it in its own context.

## Fallback functions

If the function name doesn't exist in the target contract but a `fallback` function does, the `fallback` function will be triggered.

> If there is no fallback function, the transaction will revert.

You can access function parameters for fallback functions using the `call_frames` module in the `std-lib`.
For example, to access the `_foo` input parameter in the proxy function below, you can use the `called_args` method in the `fallback` function:

```sway
    fn does_not_exist_in_the_target(_foo: u64) -> u64 {
        run_external(TARGET)
    }
```

```sway
#[fallback]
fn fallback() -> u64 {
    use std::call_frames::*;
    __log(3);
    __log(called_method());
    __log("double_value");
    __log(called_method() == "double_value");
    let foo = called_args::<u64>();
    foo * 3
}
```

In this case, the `does_not_exist_in_the_target` function will return `_foo * 3`.

## Limitations

Some limitations of `run_external` function are:

- It can only be used with other contracts. Scripts, predicates, and library code cannot be run externally.
- If you change the implementation contract, you must maintain the same order of previous storage variables and types, as this is what has been stored in the proxy storage.
- You can't use the call stack in another call frame before you use `run_external`. You can only use the call stack within the call frame that contains `run_external`.


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/hashing_and_cryptography.md

# Hashing and Cryptography

The Sway standard library provides easy access to a selection of cryptographic hash functions (`sha256` and EVM-compatible `keccak256`), and EVM-compatible `secp256k1`-based signature recovery operations.

## Hashing

```sway
script;

use std::hash::*;

impl Hash for Location {
    fn hash(self, ref mut state: Hasher) {
        match self {
            Location::Earth => {
                0_u8.hash(state);
            }
            Location::Mars => {
                1_u8.hash(state);
            }
        }
    }
}

impl Hash for Stats {
    fn hash(self, ref mut state: Hasher) {
        self.strength.hash(state);
        self.agility.hash(state);
    }
}

impl Hash for Person {
    fn hash(self, ref mut state: Hasher) {
        self.name.hash(state);
        self.age.hash(state);
        self.alive.hash(state);
        self.location.hash(state);
        self.stats.hash(state);
        self.some_tuple.hash(state);
        self.some_array.hash(state);
        self.some_b256.hash(state);
    }
}

const VALUE_A = 0x9280359a3b96819889d30614068715d634ad0cf9bba70c0f430a8c201138f79f;

enum Location {
    Earth: (),
    Mars: (),
}

struct Person {
    name: str,
    age: u64,
    alive: bool,
    location: Location,
    stats: Stats,
    some_tuple: (bool, u64),
    some_array: [u64; 2],
    some_b256: b256,
}

struct Stats {
    strength: u64,
    agility: u64,
}

fn main() {
    let zero = b256::min();
    // Use the generic sha256 to hash some integers
    let sha_hashed_u8 = sha256(u8::max());
    let sha_hashed_u16 = sha256(u16::max());
    let sha_hashed_u32 = sha256(u32::max());
    let sha_hashed_u64 = sha256(u64::max());

    // Or hash a b256
    let sha_hashed_b256 = sha256(VALUE_A);

    // You can hash booleans too
    let sha_hashed_bool = sha256(true);

    // Strings are not a problem either
    let sha_hashed_str = sha256("Fastest Modular Execution Layer!");

    // Tuples of any size work too
    let sha_hashed_tuple = sha256((true, 7));

    // As do arrays
    let sha_hashed_array = sha256([4, 5, 6]);

    // Enums work too
    let sha_hashed_enum = sha256(Location::Earth);

    // Complex structs are not a problem
    let sha_hashed_struct = sha256(Person {
        name: "John",
        age: 9000,
        alive: true,
        location: Location::Mars,
        stats: Stats {
            strength: 10,
            agility: 9,
        },
        some_tuple: (true, 8),
        some_array: [17, 76],
        some_b256: zero,
    });

    log(sha_hashed_u8);
    log(sha_hashed_u16);
    log(sha_hashed_u32);
    log(sha_hashed_u64);
    log(sha_hashed_b256);
    log(sha_hashed_bool);
    log(sha_hashed_str);
    log(sha_hashed_tuple);
    log(sha_hashed_array);
    log(sha_hashed_enum);
    log(sha_hashed_struct);

    // Use the generic keccak256 to hash some integers
    let keccak_hashed_u8 = keccak256(u8::max());
    let keccak_hashed_u16 = keccak256(u16::max());
    let keccak_hashed_u32 = keccak256(u32::max());
    let keccak_hashed_u64 = keccak256(u64::max());

    // Or hash a b256
    let keccak_hashed_b256 = keccak256(VALUE_A);

    // You can hash booleans too
    let keccak_hashed_bool = keccak256(true);

    // Strings are not a problem either
    let keccak_hashed_str = keccak256("Fastest Modular Execution Layer!");

    // Tuples of any size work too
    let keccak_hashed_tuple = keccak256((true, 7));

    // As do arrays
    let keccak_hashed_array = keccak256([4, 5, 6]);

    // Enums work too
    let keccak_hashed_enum = keccak256(Location::Earth);

    // Complex structs are not a problem
    let keccak_hashed_struct = keccak256(Person {
        name: "John",
        age: 9000,
        alive: true,
        location: Location::Mars,
        stats: Stats {
            strength: 10,
            agility: 9,
        },
        some_tuple: (true, 8),
        some_array: [17, 76],
        some_b256: zero,
    });

    log(keccak_hashed_u8);
    log(keccak_hashed_u16);
    log(keccak_hashed_u32);
    log(keccak_hashed_u64);
    log(keccak_hashed_b256);
    log(keccak_hashed_bool);
    log(keccak_hashed_str);
    log(keccak_hashed_tuple);
    log(keccak_hashed_array);
    log(keccak_hashed_enum);
    log(keccak_hashed_struct);
}

```

## Cryptographic Signature Recovery and Verification

Fuel supports 3 asymmetric cryptographic signature schemes; `Secp256k1`, `Secp256r1`, and `Ed25519`.

### Public Key Recovery

Given a `Signature` and a sign `Message`, you can recover a `PublicKey`.

```sway
    // Secp256rk1 Public Key Recovery
    let secp256k1_signature: Signature = Signature::Secp256k1(Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    )));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A recovered public key pair.
    let secp256k1_public_key = secp256k1_signature.recover(signed_message);
    assert(secp256k1_public_key.is_ok());
    assert(
        secp256k1_public_key
            .unwrap() == PublicKey::from((
            0x41a55558a3486b6ee3878f55f16879c0798afd772c1506de44aba90d29b6e65c,
            0x341ca2e0a3d5827e78d838e35b29bebe2a39ac30b58999e1138c9467bf859965,
        )),
    );

    // Secp256r1 Public Key Recovery
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876712afadbff382e1bf31c44437823ed761cc3600d0016de511ac,
        0x44ac566bd156b4fc71a4a4cb2655d3da360c695edb27dc3b64d621e122fea23d,
    )));
    let signed_message = Message::from(0x1e45523606c96c98ba970ff7cf9511fab8b25e1bcd52ced30b81df1e4a9c4323);
    // A recovered public key pair.
    let secp256r1_public_key = secp256r1_signature.recover(signed_message);
    assert(secp256r1_public_key.is_ok());
    assert(
        secp256r1_public_key
            .unwrap() == PublicKey::from((
            0xd6ea577a54ae42411fbc78d686d4abba2150ca83540528e4b868002e346004b2,
            0x62660ecce5979493fe5684526e8e00875b948e507a89a47096bc84064a175452,
        )),
    );
```

### Signed Message Address Recovery

Given a `Signature` and signed `Message`, you can recover a Fuel `Address`.

```sway
    // Secp256k1 Address Recovery
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    )));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A recovered Fuel address.
    let secp256k1_address = secp256k1_signature.address(signed_message);
    assert(secp256k1_address.is_ok());
    assert(
        secp256k1_address
            .unwrap() == Address::from(0x02844f00cce0f608fa3f0f7408bec96bfd757891a6fda6e1fa0f510398304881),
    );

    // Secp256r1 Address Recovery
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876713afa8bf3383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A recovered Fuel address.
    let secp256r1_address = secp256r1_signature.address(signed_message);
    assert(secp256r1_address.is_ok());
    assert(
        secp256r1_address
            .unwrap() == Address::from(0xb4a5fabee8cc852084b71f17107e9c18d682033a58967027af0ab01edf2f9a6a),
    );

```

#### Signed Message EVM Address Recovery

Recovery of EVM addresses is also supported.

```sway
    // Secp256k1 EVM Address Recovery
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A recovered EVM address.
    let secp256k1_evm_address = secp256k1_signature.evm_address(signed_message);
    assert(secp256k1_evm_address.is_ok());
    assert(
        secp256k1_evm_address
            .unwrap() == EvmAddress::from(0x0000000000000000000000000ec44cf95ce5051ef590e6d420f8e722dd160ecb),
    );

    // Secp256r1 EVM Address Recovery
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0x62CDC20C0AB6AA7B91E63DA9917792473F55A6F15006BC99DD4E29420084A3CC,
        0xF4D99AF28F9D6BD96BDAAB83BFED99212AC3C7D06810E33FBB14C4F29B635414,
    )));
    let signed_message = Message::from(0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563);
    // A recovered EVM address.
    let secp256r1_evm_address = secp256r1_signature.evm_address(signed_message);
    assert(secp256r1_evm_address.is_ok());
    assert(
        secp256r1_evm_address
            .unwrap() == EvmAddress::from(0x000000000000000000000000408eb2d97ef0beda0a33848d9e052066667cb00a),
    );
```

### Public Key Signature Verification

Given a `Signature`, `PublicKey`, and `Message`, you can verify that the message was signed using the public key.

```sway
    // Secp256k1 Signature Verification
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    )));
    let secp256k1_public_key = PublicKey::from((
        0x41a55558a3486b6ee3878f55f16879c0798afd772c1506de44aba90d29b6e65c,
        0x341ca2e0a3d5827e78d838e35b29bebe2a39ac30b58999e1138c9467bf859965,
    ));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A verified public key
    let secp256k1_verified = secp256k1_signature.verify(secp256k1_public_key, signed_message);
    assert(secp256k1_verified.is_ok());

    // Secp256r1 Signature Verification
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876712afadbff382e1bf31c44437823ed761cc3600d0016de511ac,
        0x44ac566bd156b4fc71a4a4cb2655d3da360c695edb27dc3b64d621e122fea23d,
    )));
    let secp256r1_public_key = PublicKey::from((
        0xd6ea577a54ae42411fbc78d686d4abba2150ca83540528e4b868002e346004b2,
        0x62660ecce5979493fe5684526e8e00875b948e507a89a47096bc84064a175452,
    ));
    let signed_message = Message::from(0x1e45523606c96c98ba970ff7cf9511fab8b25e1bcd52ced30b81df1e4a9c4323);
    // A verified public key 
    let secp256r1_verified = secp256r1_signature.verify(secp256r1_public_key, signed_message);
    assert(secp256r1_verified.is_ok());

    // Ed25519 Signature Verification
    let ed25519_public_key = PublicKey::from(0x314fa58689bbe1da2430517de2d772b384a1c1d2e9cb87e73c6afcf246045b10);
    let ed25519_signature = Signature::Ed25519(Ed25519::from((
        0xf38cef9361894be6c6e0eddec28a663d099d7ddff17c8077a1447d7ecb4e6545,
        0xf5084560039486d3462dd65a40c80a74709b2f06d450ffc5dc00345c6b2cdd00,
    )));
    let hashed_message = Message::from(sha256(b256::zero()));
    // A verified public key  
    let ed25519_verified = ed25519_signature.verify(ed25519_public_key, hashed_message);
    assert(ed25519_verified.is_ok());
```

### Address Signature Verification

Given a `Signature`, `Address`, and `Message`, you can verify that the message was signed by the address.

```sway
    // Secp256k1 Address Verification
    let secp256k1_address = Address::from(0x02844f00cce0f608fa3f0f7408bec96bfd757891a6fda6e1fa0f510398304881);
    let secp256k1_signature = Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    ));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A verified address
    let secp256k1_verified = secp256k1_signature.verify_address(secp256k1_address, signed_message);
    assert(secp256k1_verified.is_ok());

    // Secp256r1 Address Verification
    let secp256r1_address = Address::from(0xb4a5fabee8cc852084b71f17107e9c18d682033a58967027af0ab01edf2f9a6a);
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876713afa8bf3383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A verified address
    let secp256r1_verified = secp256r1_signature.verify_address(secp256r1_address, signed_message);
    assert(secp256r1_verified.is_ok());

```

#### EVM Address Signature Verification

Recovery of EVM addresses verification is also supported.

```sway
    // Secp256k1 Address Verification
    let secp256k1_evm_address = EvmAddress::from(0x0000000000000000000000000ec44cf95ce5051ef590e6d420f8e722dd160ecb);
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A recovered EVM address.
    let secp256k1_verified = secp256k1_signature.verify_evm_address(secp256k1_evm_address, signed_message);
    assert(secp256k1_verified.is_ok());

    // Secp256r1 Address Verification
    let secp256r1_evm_address = EvmAddress::from(0x000000000000000000000000408eb2d97ef0beda0a33848d9e052066667cb00a);
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0x62CDC20C0AB6AA7B91E63DA9917792473F55A6F15006BC99DD4E29420084A3CC,
        0xF4D99AF28F9D6BD96BDAAB83BFED99212AC3C7D06810E33FBB14C4F29B635414,
    )));
    let signed_message = Message::from(0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563);
    // A recovered EVM address.
    let secp256r1_verified = secp256r1_signature.verify_evm_address(secp256r1_evm_address, signed_message);
    assert(secp256r1_verified.is_ok());
```


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/identifiers.md

# Identifiers

Addresses in Sway are similar to EVM addresses. The two major differences are:

1. Sway addresses are 32 bytes long (instead of 20)
2. Sway addresses are computed with the SHA-256 hash of the public key instead of the keccak-256 hash.

Contracts, on the other hand, are uniquely identified with a contract ID rather than an address. A contract's ID is also 32 bytes long and is calculated [here](https://fuellabs.github.io/fuel-specs/master/protocol/id/contract).


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/index.md

# Blockchain Development with Sway

Sway is fundamentally a blockchain language. Because of this, it has some features and requirements that you may not have seen in general-purpose programming languages.

These are also some concepts related to the FuelVM and Fuel ecosystem that you may utilize when writing Sway.

- [Hashing and Cryptography](./hashing_and_cryptography.md)
- [Contract Storage](./storage.md)
- [Function Purity](./purity.md)
- [Identifiers](./identifiers.md)
- [Native Assets](./native_assets.md)
- [Access Control](./access_control.md)
- [Calling Contracts](./calling_contracts.md)
- [External Code Execution](./external_code.md)


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/native_assets.md

# Native Assets

<!-- This section should explain native assets in Sway -->
<!-- native_assets:example:start -->
The FuelVM has built-in support for working with multiple assets.

## Key Differences Between EVM and FuelVM Assets

### ERC-20 vs Native Asset

On the EVM, Ether is the native asset. As such, sending ETH to an address or contract is an operation built into the EVM, meaning it doesn't rely on the existence of a smart contract to update balances to track ownership as with ERC-20 tokens.

On the FuelVM, _all_ assets are native and the process for sending _any_ native asset is the same.

While you would still need a smart contract to handle the minting and burning of assets, the sending and receiving of these assets can be done independently of the asset contract.

Just like the EVM however, Fuel has a standard that describes a standard API for Native Assets using the Sway Language. The ERC-20 equivalent for the Sway Language is the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md).

> **NOTE** It is important to note that Fuel does not have tokens.

### ERC-721 vs Native Asset

On the EVM, an ERC-721 token or NFT is a contract that contains multiple tokens which are non-fungible with one another.

On the FuelVM, the ERC-721 equivalent is a Native Asset where each asset has a supply of one. This is defined in the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md#non-fungible-asset-restrictions) under the Non-Fungible Asset Restrictions.

In practice, this means all NFTs are treated the same as any other Native Asset on Fuel. When writing Sway code, no additional cases for handling non-fungible and fungible assets are required.

### No Token Approvals

An advantage Native Assets bring is that there is no need for token approvals; as with Ether on the EVM. With millions of dollars hacked every year due to misused token approvals, the FuelVM eliminates this attack vector.

### Asset vs Coin vs Token

An "Asset" is a Native Asset on Fuel and has the associated `AssetId` type. Assets are distinguishable from one another. A "Coin" represents a singular unit of an Asset. Coins of the same Asset are not distinguishable from one another.

Fuel does not use tokens like other ecosystems such as Ethereum and uses Native Assets with a UTXO design instead.

## The `AssetId` type

The `AssetId` type represents any Native Asset on Fuel. An `AssetId` is used for interacting with an asset on the network.

The `AssetId` of any Native Asset on Fuel is calculated by taking the SHA256 hash digest of the originating `ContractId` that minted the asset and a `SubId` i.e. `sha256((contract_id, sub_id))`.

### Creating a New `AssetId`

There are 3 ways to instantiate a new `AssetId`:

#### Default

When a contract will only ever mint a single asset, it is recommended to use the `DEFAULT_ASSET_ID` sub id. This is referred to as the default asset of a contract.

To get the default asset from an internal contract call, call the `default()` function:

```sway
    let asset_id: AssetId = AssetId::default();
```

#### New

If a contract mints multiple assets or if the asset has been minted by an external contract, the `new()` function will be needed. The `new()` function takes the `ContractId` of the contract which minted the token as well as a `SubId`.

To create a new `AssetId` using a `ContractId` and `SubId`, call the `new()` function:

```sway
    let my_contract_id: ContractId = ContractId::from(0x1000000000000000000000000000000000000000000000000000000000000000);
    let my_sub_id: SubId = 0x2000000000000000000000000000000000000000000000000000000000000000;

    let asset_id: AssetId = AssetId::new(my_contract_id, my_sub_id);
```

#### From

In the case where the `b256` value of an asset is already known, you may call the `from()` function with the `b256` value.

```sway
    let asset_id: AssetId = AssetId::from(0x0000000000000000000000000000000000000000000000000000000000000000);
```

## The `SubId` type

The SubId is used to differentiate between different assets that are created by the same contract. The `SubId` is a `b256` value.

When creating a single new asset on Fuel, we recommend using the `DEFAULT_SUB_ID` or `SubId::zero()`.

## The Base Asset

On the Fuel Network, the base asset is Ether. This is the only asset on the Fuel Network that does not have a `SubId`.

The Base Asset can be returned anytime by calling the `base()` function of the `AssetId` type.

```sway
    let base_asset: AssetId = AssetId::base();
```

## Basic Native Asset Functionality

### Minting A Native Asset

To mint a new asset, the `std::asset::mint()` function must be called internally within a contract. A `SubId` and amount of coins must be provided. These newly minted coins will be owned by the contract which minted them. To mint another asset from the same contract, replace the `DEFAULT_SUB_ID` with your desired `SubId`.

```sway
        mint(DEFAULT_SUB_ID, mint_amount);
```

You may also mint an asset to a specific entity with the `std::asset::mint_to()` function. Be sure to provide a target `Identity` that will own the newly minted coins.

```sway
        mint_to(target_identity, DEFAULT_SUB_ID, mint_amount);
```

If you intend to allow external users to mint assets using your contract, the [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md#fn-mintrecipient-identity-vault_sub_id-subid-amount-u64) defines a standard API for minting assets. The [Sway-Libs Asset Library](https://fuellabs.github.io/sway-libs/book/asset/supply.html) also provides an additional library to support implementations of the SRC-3 Standard into your contract.

### Burning a Native Asset

To burn an asset, the `std::asset::burn()` function must be called internally from the contract which minted them. The `SubId` used to mint the coins and amount must be provided. The burned coins must be owned by the contract. When an asset is burned it doesn't exist anymore.

```sway
        burn(DEFAULT_SUB_ID, burn_amount);
```

If you intend to allow external users to burn assets using your contract, the [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md#fn-mintrecipient-identity-vault_sub_id-subid-amount-u64) defines a standard API for burning assets. The [Sway-Libs Asset Library](https://fuellabs.github.io/sway-libs/book/asset/supply.html) also provides an additional library to support implementations of the SRC-3 Standard into your contract.

### Transfer a Native Asset

To internally transfer a Native Asset, the `std::asset::transfer()` function must be called. A target `Identity` or user must be provided as well as the `AssetId` of the asset and an amount.

```sway
        transfer(target, asset_id, coins);
```

### Native Asset And Transactions

#### Getting The Transaction Asset

To query for the Native Asset sent in a transaction, you may call the `std::call_frames::msg_asset_id()` function.

```sway
        let amount = msg_asset_id();
```

#### Getting The Transaction Amount

To query for the amount of coins sent in a transaction, you may call the `std::context::msg_amount()` function.

```sway
        let amount = msg_amount();
```

### Native Assets and Contracts

#### Checking A Contract's Balance

To internally check a contract's balance, call the `std::context::this_balance()` function with the corresponding `AssetId`.

```sway
        this_balance(asset_id)
```

To check the balance of an external contract, call the `std::context::balance_of()` function with the corresponding `AssetId`.

```sway
        balance_of(target_contract, asset_id)
```

> **NOTE** Due to the FuelVM's UTXO design, balances of `Address`'s cannot be returned in the Sway Language. This must be done off-chain using the SDK.

#### Receiving Native Assets In A Contract

By default, a contract may not receive a Native Asset in a contract call. To allow transferring of assets to the contract, add the `#[payable]` attribute to the function.

```sway
    #[payable]
    fn deposit() {
        assert(msg_amount() > 0);
    }
```

## Native Asset Standards

There are a number of standards developed to enable further functionality for Native Assets and help cross contract functionality. Information on standards can be found in the [Sway Standards Repo](https://github.com/FuelLabs/sway-standards).

We currently have the following standards for Native Assets:

- [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md) defines the implementation of a standard API for Native Assets using the Sway Language.
- [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md) is used to enable mint and burn functionality for Native Assets.
- [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) is used to store metadata for Native Assets.
- [SRC-6; Vault Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-6-vault.md) defines the implementation of a standard API for asset vaults developed in Sway.

## Native Asset Libraries

Additional Libraries have been developed to allow you to quickly create an deploy dApps that follow the [Sway Standards](https://github.com/FuelLabs/sway-standards).

- [Asset Library](https://fuellabs.github.io/sway-libs/book/asset/index.html) provides functionality to implement the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) standards.

<!-- native_assets:example:end -->

## Single Native Asset Example

In this fully fleshed out example, we show a native asset contract which mints a single asset. This is the equivalent to the ERC-20 Standard use in Ethereum. Note there are no token approval functions.

It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-5; Ownership](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) standards. It does not use any external libraries.

```sway
// ERC20 equivalent in Sway.
contract;

use standards::{
    src3::SRC3,
    src5::{
        SRC5, 
        State, 
        AccessError,
    },
    src20::{
        SetDecimalsEvent, 
        SetNameEvent, 
        SetSymbolEvent, 
        SRC20, 
        TotalSupplyEvent,
    },
};
use std::{
    asset::{
        burn,
        mint_to,
    },
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    string::String,
    contract_id::ContractId
};

configurable {
    DECIMALS: u8 = 9u8,
    NAME: str[7] = __to_str_array("MyAsset"),
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

storage {
    total_supply: u64 = 0,
    owner: State = State::Uninitialized,
}

// Native Asset Standard
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(storage.total_supply.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

// Ownership Standard
impl SRC5 for Contract {
    #[storage(read)]
    fn owner() -> State {
        storage.owner.read()
    }
}

// Mint and Burn Standard
impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        require(sub_id.is_some() && sub_id.unwrap() == DEFAULT_SUB_ID, "incorrect-sub-id");
        require_access_owner();

        let new_supply = storage.total_supply.read() + amount;
        storage
            .total_supply
            .write(new_supply);
        mint_to(recipient, DEFAULT_SUB_ID, amount);
        
        TotalSupplyEvent::new(
            AssetId::default(), 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }

    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        require(sub_id == DEFAULT_SUB_ID, "incorrect-sub-id");
        require(msg_amount() >= amount, "incorrect-amount-provided");
        require(
            msg_asset_id() == AssetId::default(),
            "incorrect-asset-provided",
        );
        require_access_owner();

        let new_supply = storage.total_supply.read() - amount;
        storage
            .total_supply
            .write(new_supply);
        burn(DEFAULT_SUB_ID, amount);
        
        TotalSupplyEvent::new(
            AssetId::default(), 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }
}

abi SingleAsset {
    #[storage(read, write)]
    fn constructor(owner_: Identity);
}

impl SingleAsset for Contract {
    #[storage(read, write)]
    fn constructor(owner_: Identity) {
        require(storage.owner.read() == State::Uninitialized, "owner-initialized");
        storage.owner.write(State::Initialized(owner_));
    }
}

#[storage(read)]
fn require_access_owner() {
    require(
        storage.owner.read() == State::Initialized(msg_sender().unwrap()),
        AccessError::NotOwner,
    );
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
    }
}
```

## Multi Native Asset Example

In this fully fleshed out example, we show a native asset contract which mints multiple assets. This is the equivalent to the ERC-1155 Standard use in Ethereum. Note there are no token approval functions.

It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-5; Ownership](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) standards. It does not use any external libraries.

```sway
// ERC1155 equivalent in Sway.
contract;

use standards::{
    src5::{
        SRC5, 
        State, 
        AccessError
    },
    src20::{
        SetDecimalsEvent, 
        SetNameEvent, 
        SetSymbolEvent, 
        SRC20, 
        TotalSupplyEvent,
    }
    src3::SRC3,
};
use std::{
    asset::{
        burn,
        mint_to,
    },
    call_frames::msg_asset_id,
    hash::{
        Hash,
    },
    context::this_balance,
    storage::storage_string::*,
    string::String,
    contract_id::ContractId
};

storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
    owner: State = State::Uninitialized,
}

// Native Asset Standard
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }
    
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

// Mint and Burn Standard
impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        require(sub_id.is_some(), "Error: SubId is None");
        require_access_owner();

        let asset_id = AssetId::new(ContractId::this(), sub_id.unwrap());
        let supply = storage.total_supply.get(asset_id).try_read();
        if supply.is_none() {
            storage.total_assets.write(storage.total_assets.try_read().unwrap_or(0) + 1);
        }
        let new_supply = supply.unwrap_or(0) + amount;
        storage.total_supply.insert(asset_id, new_supply);
        mint_to(recipient, sub_id, amount);
        
        TotalSupplyEvent::new(
            asset_id, 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }
    
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        require_access_owner();
        let asset_id = AssetId::new(ContractId::this(), sub_id);
        require(this_balance(asset_id) >= amount, "not-enough-coins");
        
        let supply = storage.total_supply.get(asset_id).try_read();
        let new_supply = supply.unwrap_or(0) - amount;
        storage.total_supply.insert(asset_id, new_supply);
        burn(sub_id, amount);

        TotalSupplyEvent::new(
            asset_id, 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }
}

abi MultiAsset {
    #[storage(read, write)]
    fn constructor(owner_: Identity);
    
    #[storage(read, write)]
    fn set_name(asset: AssetId, name: Option<String>);

    #[storage(read, write)]
    fn set_symbol(asset: AssetId, symbol: Option<String>);

    #[storage(read, write)]
    fn set_decimals(asset: AssetId, decimals: u8);
}

impl MultiAsset for Contract {
    #[storage(read, write)]
    fn constructor(owner_: Identity) {
        require(storage.owner.read() == State::Uninitialized, "owner-initialized");
        storage.owner.write(State::Initialized(owner_));
    }
    
    #[storage(read, write)]
    fn set_name(asset: AssetId, name: Option<String>) {
        require_access_owner();
        storage.name.insert(asset, StorageString {});
        storage.name.get(asset).write_slice(name);

        SetNameEvent::new(asset, name, msg_sender().unwrap()).log();
    }

    #[storage(read, write)]
    fn set_symbol(asset: AssetId, symbol: Option<String>) {
        require_access_owner();
        storage.symbol.insert(asset, StorageString {});
        storage.symbol.get(asset).write_slice(symbol);

        SetSymbolEvent::new(asset, symbol, msg_sender().unwrap()).log();
    }

    #[storage(read, write)]
    fn set_decimals(asset: AssetId, decimals: u8) {
        require_access_owner();
        storage.decimals.insert(asset, decimals);

        SetDecimalsEvent::new(asset, decimals, msg_sender().unwrap()).log();
    }
}

#[storage(read)]
fn require_access_owner() {
    require(
        storage.owner.read() == State::Initialized(msg_sender().unwrap()),
        AccessError::NotOwner,
    );
}
```


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/purity.md

# Purity

<!-- This section should explain pure functions in Sway -->
<!-- pure:example:start -->
A function is _pure_ if it does not access any [persistent storage](./storage.md). Conversely, the function is _impure_ if it does access any storage. Naturally, as storage is only available in smart contracts, impure functions cannot be used in predicates, scripts, or libraries. A pure function cannot call an impure function.

In Sway, functions are pure by default but can be opted into impurity via the `storage` function attribute. The `storage` attribute may take `read` and/or `write` arguments indicating which type of access the function requires.

The `storage` attribute without any arguments, `#[storage()]`, indicates a pure function, and has the same effect as not having the attribute at all.
<!-- pure:example:end -->

```sway
#[storage(read)]
fn get_amount() -> u64 {
    ...
}

#[storage(read, write)]
fn increment_amount(increment: u64) -> u64 {
    ...
}

fn a_pure_function() {
    ...
}

#[storage()]
fn also_a_pure_function() {
    ...
}
```

> **Note**: the `#[storage(write)]` attribute also permits a function to read from storage. This is due to the fact that partially writing a storage slot requires first reading the slot.

<!-- This section should explain impure functions in Sway -->
<!-- impure:example:start -->
Impure functions which call other impure functions must have at least the same storage privileges or a superset of those for the function called. For example, to call a function with write access a caller must also have write access, or both read and write access. To call a function with read and write access the caller must also have both privileges.
<!-- impure:example:end -->

The `storage` attribute may also be applied to [methods and associated functions](../basics/methods_and_associated_functions.md), [trait](../advanced/traits.md) and [ABI](../sway-program-types/smart_contracts.md#the-abi-declaration) declarations.

<!-- This section should explain the benefits of using pure functions in Sway -->
<!-- pure_benefits:example:start -->
A pure function gives you some guarantees: you will not incur excessive storage gas costs, the compiler can apply additional optimizations, and they are generally easy to reason about and audit.

> **Note**: Purity does not provide an absolute guarantee that a storage access will not happen as a result of calling a pure function. E.g., it is possible for a pure function to call another contract, which can then call a write function in the original contract. The guarantee that the purity gives in this example is, that the original pure function itself does not change the storage, as well as that any function later called, that accesses storage, is clearly marked as impure.
<!-- pure_benefits:example:end -->

[A similar concept exists in Solidity](https://docs.soliditylang.org/en/v0.8.10/contracts.html#pure-functions). Note that Solidity refers to contract storage as _contract state_, and in the Sway/Fuel ecosystem, these two terms are largely interchangeable.


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/storage.md

# Storage

<!-- This section should explain storage in Sway -->
<!-- storage:example:start -->
When developing a [smart contract](../sway-program-types/smart_contracts.md), you will typically need some sort of persistent storage. In this case, persistent storage, often just called _storage_ in this context, is a place where you can store values that are persisted inside the contract itself. This is in contrast to a regular value in _memory_, which disappears after the contract exits.

Put in conventional programming terms, contract storage is like saving data to a hard drive. That data is saved even after the program that saved it exits. That data is persistent. Using memory is like declaring a variable in a program: it exists for the duration of the program and is non-persistent.

Some basic use cases of storage include declaring an owner address for a contract and saving balances in a wallet.
<!-- storage:example:end -->

## Storage Accesses Via the `storage` Keyword

Declaring variables in storage requires a `storage` block that contains a list of all your variables, their types, and their initial values. The initial value can be any expression that can be evaluated to a constant during compilation, as follows:

```sway
storage {
    var1: u64 = 1,
    var2: b256 = b256::zero(),
    var3: Address = Address::zero(),
    var4: Option<u8> = None,
}
```

To write into a storage variable, you need to use the `storage` keyword as follows:

```sway
        storage.var1.write(42);
        storage
            .var2
            .write(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .var3
            .write(Address::from(0x1111111111111111111111111111111111111111111111111111111111111111));
        storage.var4.write(Some(2u8));
```

To read a storage variable, you also need to use the `storage` keyword. You may use `read()` or `try_read()`, however we recommend using `try_read()` for additional safety.

```sway
        let var1: u64 = storage.var1.read();
        let var2: b256 = storage.var2.try_read().unwrap_or(b256::zero());
        let var3: Address = storage.var3.try_read().unwrap_or(Address::zero());
        let var4: Option<u8> = storage.var4.try_read().unwrap_or(None);
```

## Storing Structs

To store a struct in storage, each variable must be assigned in the `storage` block. This can be either my assigning the fields individually or using a public [constructor](../basics/methods_and_associated_functions.md#constructors) that can be evaluated to a constant during compilation.

```sway
struct Type1 {
    x: u64,
    y: u64,
}

struct Type2 {
    w: b256,
    z: bool,
}

impl Type2 {
    // a constructor that evaluates to a constant during compilation
    fn default() -> Self {
        Self {
            w: 0x0000000000000000000000000000000000000000000000000000000000000000,
            z: true,
        }
    }
}

storage {
    var1: Type1 = Type1 { x: 0, y: 0 },
    var2: Type2 = Type2::default(),
}
```

You may write to both fields of a struct and the entire struct as follows:

```sway
        // Store individual fields
        storage.var1.x.write(42);
        storage.var1.y.write(77);

        // Store an entire struct
        let new_struct = Type2 {
            w: 0x1111111111111111111111111111111111111111111111111111111111111111,
            z: false,
        };
        storage.var2.write(new_struct);
```

The same applies to reading structs from storage, where both the individual and struct as a whole may be read as follows:

```sway
        let var1_x: u64 = storage.var1.x.try_read().unwrap_or(0);
        let var1_y: u64 = storage.var1.y.try_read().unwrap_or(0);
        let var2: Type2 = storage.var2.try_read().unwrap_or(Type2::default());
```

## Common Storage Collections

We support the following common storage collections:

- `StorageMap<K, V>`
- `StorageVec<T>`
- `StorageBytes`
- `StorageString`

Please note that these types are not initialized during compilation. This means that if you try to access a key from a storage map before the storage has been set, for example, the call will revert.

Declaring these variables in storage requires a `storage` block as follows:

```sway
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
```

### `StorageMaps<K, V>`

Generic storage maps are available in the standard library as `StorageMap<K, V>` which have to be defined inside a `storage` block and allow you to call `insert()` and `get()` to insert values at specific keys and get those values respectively. Refer to [Storage Maps](../common-collections/storage_map.md) for more information about `StorageMap<K, V>`.

**Warning** While the `StorageMap<K, V>` is currently included in the prelude, to use it the `Hash` trait must still be imported. This is a known issue and will be resolved.

```sway
use std::hash::Hash;

// ANCHOR: storage_vec_import
use std::storage::storage_vec::*;
// ANCHOR: storage_vec_import

// ANCHOR: storage_bytes_import
use std::storage::storage_bytes::*;
// ANCHOR: storage_bytes_import

// ANCHOR: storage_string_import
use std::storage::storage_string::*;
// ANCHOR: storage_string_import

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

To write to a storage map, call either the `insert()` or `try_insert()` functions as follows:

```sway
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
```

The following demonstrates how to read from a storage map:

```sway
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
```

### `StorageVec<T>`

Generic storage vectors are available in the standard library as `StorageVec<T>` which have to be defined inside a `storage` block and allow you to call `push()` and `pop()` to push and pop values from a vector respectively. Refer to [Storage Vector](../common-collections/storage_vec.md) for more information about `StorageVec<T>`.

The following demonstrates how to import `StorageVec<T>`:

```sway
use std::storage::storage_vec::*;

// ANCHOR: storage_bytes_import
use std::storage::storage_bytes::*;
// ANCHOR: storage_bytes_import

// ANCHOR: storage_string_import
use std::storage::storage_string::*;
// ANCHOR: storage_string_import

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

> **NOTE**: When importing the `StorageVec<T>`, please be sure to use the glob operator: `use std::storage::storage_vec::*`.

The following demonstrates how to write to a `StorageVec<T>`:

```sway
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
```

The following demonstrates how to read from a `StorageVec<T>`:

```sway
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
```

### `StorageBytes`

Storage of `Bytes` is available in the standard library as `StorageBytes` which have to be defined inside a `storage` block. `StorageBytes` cannot be manipulated in the same way a `StorageVec<T>` or `StorageMap<K, V>` can but stores bytes more efficiently thus reducing gas. Only the entirety of a `Bytes` may be read/written to storage. This means any changes would require loading the entire `Bytes` to the heap, making changes, and then storing it once again. If frequent changes are needed, a `StorageVec<u8>` is recommended.

The following demonstrates how to import `StorageBytes`:

```sway
use std::storage::storage_bytes::*;

// ANCHOR: storage_string_import
use std::storage::storage_string::*;
// ANCHOR: storage_string_import

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

> **NOTE**: When importing the `StorageBytes`, please be sure to use the glob operator: `use std::storage::storage_bytes::*`.

The following demonstrates how to write to a `StorageBytes`:

```sway
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
```

The following demonstrates how to read from a `StorageBytes`:

```sway
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
```

### `StorageString`

Storage of `String` is available in the standard library as `StorageString` which have to be defined inside a `storage` block. `StorageString` cannot be manipulated in the same way a `StorageVec<T>` or `StorageMap<K, V>`. Only the entirety of a `String` may be read/written to storage.

The following demonstrates how to import `StorageString`:

```sway
use std::storage::storage_string::*;

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

> **NOTE**: When importing the `StorageString`, please be sure to use the glob operator: `use std::storage::storage_string::*`.

The following demonstrates how to write to a `StorageString`:

```sway
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
```

The following demonstrates how to read from a `StorageString`:

```sway
        let stored_string: String = storage.storage_string.read_slice().unwrap();
```

## Advanced Storage

For more advanced storage techniques please refer to the [Advanced Storage](../advanced/advanced_storage.md) page.


---

### File: docs/nightly/sway/docs/book/src/blockchain-development/time.md

# Time Library

The `std::time` library provides utilities for handling time durations and timestamps in Sway smart contracts.

## Duration

Represents a span of time in seconds.

### Creating Durations

```sway
fn create_durations() {
    // Using constants
    let zero = Duration::ZERO;
    let second = Duration::SECOND;
    let minute = Duration::MINUTE;
    let hour = Duration::HOUR;
    let day = Duration::DAY;
    let week = Duration::WEEK;

    // Using constructor methods
    let thirty_seconds = Duration::seconds(30);
    let two_hours = Duration::hours(2);
    let three_days = Duration::days(3);
}
```

### Converting Durations

Time `std::time` library supports conversion between different time scales such as `seconds`, `minutes`, `hours`, `days`, and `weeks`.

```sway
fn convert_durations() {
    let two_days = Duration::days(2);

    assert(two_days.as_seconds() == 172800); // 2 * 86400
    assert(two_days.as_minutes() == 2880); // 2 * 1440
    assert(two_days.as_hours() == 48); // 2 * 24
    assert(two_days.as_days() == 2);
    assert(two_days.as_weeks() == 0); // Truncated value
}
```

### Operations

The `std::time` supports operations on the `Duration` type.

```sway
fn duration_operations() {
    let day1 = Duration::DAY;
    let day2 = Duration::days(1);

    // Equality
    assert(day1 == day2);

    // Addition
    let two_days = day1 + day2;
    assert(two_days.as_days() == 2);

    // Subtraction
    let half_day = two_days - Duration::days(1).add(Duration::hours(12));
    assert(half_day.as_hours() == 12);

    // Comparison
    assert(Duration::MINUTE < Duration::HOUR);
}
```

## Time

Represents a UNIX timestamp (seconds since Jan 1, 1970).

### Creating Timestamps

There are 3 major ways to create a new timestamp.

```sway
fn create_timestamps() {
    // Current block time
    let now = Time::now();

    // Specific block time
    let block_time = Time::block(12345);

    // From UNIX timestamp
    let custom_time = Time::new(1672531200); // Jan 1, 2023 00:00:00 UTC
}
```

### Time Operations

Operations on the `Time` type are supported with conjunction of the `Duration` type.

```sway
fn time_operations() {
    let now = Time::now();
    let yesterday = now.subtract(Duration::DAY);
    let tomorrow = now.add(Duration::DAY);

    // Duration calculations
    let elapsed = now.duration_since(yesterday).unwrap();
    assert(elapsed.as_days() == 1);

    // Comparison
    assert(yesterday < now);
    assert(tomorrow > now);
}
```

### TAI64 Conversion

The Fuel VM internally uses TAI64 time. Conversions between UNIX and TAI64 are maintained with the `Time` type.

```sway
fn tai64_conversion() {
    let now = Time::now();

    // Convert to TAI64
    let tai64 = now.as_tai64();

    // Convert back to UNIX time
    let converted = Time::from_tai64(tai64);
    assert(now == converted);
}
```

### TAI64 vs UNIX Time

#### Conversion Details

The library uses:

```sway
const TAI_64_CONVERTER: u64 = 10 + (1 << 62);
```

(1 << 62) (0x4000000000000000) marks value as TAI64. 10 accounts for initial TAI-UTC offset in 1970.

Conversion formulas:

`UNIX → TAI64: tai64 = unix + TAI_64_CONVERTER`

`TAI64 → UNIX: unix = tai64 - TAI_64_CONVERTER`

#### Key Differences

| Feature      | TAI64                    | UNIX                      |
|--------------|--------------------------|---------------------------|
| Epoch        | 1970-01-01 00:00:00 TAI  | 1970-01-01 00:00:00 UTC   |
| Leap Seconds | No leap seconds          | Includes leap seconds     |
| Stability    | Continuous time scale    | Discontinuous adjustments |
| Value Range  | (1 << 62) + offset (10s) | Seconds since epoch       |

#### Why TAI64?

* Deterministic execution: No leap second ambiguities
* Monotonic time: Always increases steadily
* Blockchain-friendly: Aligns with Fuel's timestamp mechanism

## Best Practices

1. Use `Duration` for time spans instead of raw seconds
2. Always handle `TimeError` results from `duration_since()` and `elapsed()`
3. Convert to TAI64 when interacting with blockchain primitives
4. Use `Time::block()` for historical time comparisons
5. Prefer duration constants (`SECOND`, `HOUR`, etc.) for readability

## Limitations

1. Durations only support second-level precision
2. Time comparisons are limited to u64 range (584 billion years)
3. No calendar/date functionality (only timestamps)
4. Duration conversions truncate fractional units


---

### File: docs/nightly/sway/docs/book/src/common-collections/index.md

# Common Collections

Sway’s standard library includes a number of very useful data structures called collections. Most other data types represent one specific value, but collections can contain multiple values. Unlike the built-in array and tuple types which are allocated on the "stack" and cannot grow in size, the data these collections point to is stored either on the "heap" or in contract "storage", which means the amount of data does not need to be known at compile time and can grow as the program runs. Each kind of collection has different capabilities and costs, and choosing an appropriate one for your current situation is a skill you’ll develop over time. In this chapter, we’ll discuss three collections that are used very often in Sway programs:

A vector on the heap allows you to store a variable number of values next to each other.

A `StorageVec` is similar to a vector on the heap but uses persistent storage.

A `StorageMap` allows you to associate a value with a particular key.

We’ll discuss how to create and update a vector, `StorageVec`, and `StorageMap`, as well as what makes each special.

- [Vectors on the Heap](./vec.md)
- [`StorageVec`](./storage_vec.md)
- [`StorageMap`](./storage_map.md)


---

### File: docs/nightly/sway/docs/book/src/common-collections/storage_map.md

# Storage Maps

Another important common collection is the storage map.

<!-- This section should explain storage maps in Sway -->
<!-- storage_map:example:start -->
The type `StorageMap<K, V>` from the standard library stores a mapping of keys of type `K` to values of type `V` using a hashing function, which determines how it places these keys and values into _storage slots_. This is similar to [Rust's `HashMap<K, V>`](https://doc.rust-lang.org/std/collections/struct.HashMap.html) but with a few differences.

Storage maps are useful when you want to look up data not by using an index, as you can with vectors, but by using a key that can be of any type. For example, when building a ledger-based sub-currency smart contract, you could keep track of the balance of each wallet in a storage map in which each key is a wallet’s `Address` and the values are each wallet’s balance. Given an `Address`, you can retrieve its balance.

Similarly to `StorageVec<T>`, `StorageMap<K, V>` can only be used in a contract because only contracts are allowed to access persistent storage.

`StorageMap<T>` is included in the [standard library prelude](../introduction/standard_library.md#standard-library-prelude) which means that there is no need to import it manually.
<!-- storage_map:example:end -->

## Creating a New Storage Map

To create a new empty storage map, we have to declare the map in a `storage` block as follows:

```sway
    map: StorageMap<Address, u64> = StorageMap::<Address, u64> {},
```

<!-- This section should explain how to implement storage maps in Sway -->
<!-- use_storage_maps:example:start -->
Just like any other storage variable, two things are required when declaring a `StorageMap`: a type annotation and an initializer. The initializer is just an empty struct of type `StorageMap` because `StorageMap<K, V>` itself is an empty struct! Everything that is interesting about `StorageMap<K, V>` is implemented in its methods.

Storage maps, just like `Vec<T>` and `StorageVec<T>`, are implemented using generics which means that the `StorageMap<K, V>` type provided by the standard library can map keys of any type `K` to values of any type `V`. In the example above, we’ve told the Sway compiler that the `StorageMap<K, V>` in `map` will map keys of type `Address` to values of type `u64`.
<!-- use_storage_maps:example:end -->

## Updating a Storage Map

<!-- This section should explain how to update storage maps in Sway -->
<!-- update_storage_maps:example:start -->
To insert key-value pairs into a storage map, we can use the `insert` method.
<!-- update_storage_maps:example:end -->

For example:

```sway
    #[storage(write)]
    fn insert_into_storage_map() {
        let addr1 = Address::from(0x0101010101010101010101010101010101010101010101010101010101010101);
        let addr2 = Address::from(0x0202020202020202020202020202020202020202020202020202020202020202);

        storage.map.insert(addr1, 42);
        storage.map.insert(addr2, 77);
    }
```

Note two details here. First, in order to use `insert`, we need to first access the storage map using the `storage` keyword. Second, because `insert` requires _writing_ into storage, a `#[storage(write)]` annotation is required on the ABI function that calls `insert`.

> **Note**
> The storage annotation is also required for any private function defined in the contract that tries to insert into the map.

<!-- markdownlint-disable-line MD028 -->
> **Note**
> There is no need to add the `mut` keyword when declaring a `StorageMap<K, V>`. All storage variables are mutable by default.

## Accessing Values in a Storage Map

<!-- This section should explain how to access storage map values in Sway -->
<!-- access_storage_maps:example:start -->
We can get a value out of the storage map by providing its `key` to the `get` method.
<!-- access_storage_maps:example:end -->

For example:

```sway
    #[storage(read, write)]
    fn get_from_storage_map() {
        let addr1 = Address::from(0x0101010101010101010101010101010101010101010101010101010101010101);
        let addr2 = Address::from(0x0202020202020202020202020202020202020202020202020202020202020202);

        storage.map.insert(addr1, 42);
        storage.map.insert(addr2, 77);

        let value1 = storage.map.get(addr1).try_read().unwrap_or(0);
    }
```

Here, `value1` will have the value that's associated with the first address, and the result will be `42`. The `get` method returns an `Option<V>`; if there’s no value for that key in the storage map, `get` will return `None`. This program handles the `Option` by calling `unwrap_or` to set `value1` to zero if `map` doesn't have an entry for the key.

## Storage Maps with Multiple Keys

Maps with multiple keys can be implemented using tuples as keys. For example:

```sway
    map_two_keys: StorageMap<(b256, bool), b256> = StorageMap::<(b256, bool), b256> {},
```

## Nested Storage Maps

It is possible to nest storage maps as follows:

```sway
    nested_map: StorageMap<u64, StorageMap<u64, u64>> = StorageMap::<u64, StorageMap<u64, u64>> {},
    #[storage(read, write)]
    fn access_nested_map() {
        storage.nested_map.get(0).insert(1, 42);
        storage.nested_map.get(2).insert(3, 24);

        assert(storage.nested_map.get(0).get(1).read() == 42);
        assert(storage.nested_map.get(0).get(0).try_read().is_none()); // Nothing inserted here
        assert(storage.nested_map.get(2).get(3).read() == 24);
        assert(storage.nested_map.get(2).get(2).try_read().is_none()); // Nothing inserted here
    }
```

The nested map can then be accessed as follows:

```sway
    #[storage(read, write)]
    fn access_nested_map() {
        storage.nested_map.get(0).insert(1, 42);
        storage.nested_map.get(2).insert(3, 24);

        assert(storage.nested_map.get(0).get(1).read() == 42);
        assert(storage.nested_map.get(0).get(0).try_read().is_none()); // Nothing inserted here
        assert(storage.nested_map.get(2).get(3).read() == 24);
        assert(storage.nested_map.get(2).get(2).try_read().is_none()); // Nothing inserted here
    }
```


---

### File: docs/nightly/sway/docs/book/src/common-collections/storage_vec.md

# Storage Vectors

The second collection type we’ll look at is `StorageVec<T>`. Just like vectors on the heap (i.e. `Vec<T>`), storage vectors allow you to store more than one value in a single data structure where each value is assigned an index and can only store values of the same type. However, unlike `Vec<T>`, the elements of a `StorageVec` are stored in _persistent storage_, and consecutive elements are not necessarily stored in storage slots that have consecutive keys.

In order to use `StorageVec<T>`, you must first import `StorageVec` as follows:

```sway
use std::storage::storage_vec::*;
```

Another major difference between `Vec<T>` and `StorageVec<T>` is that `StorageVec<T>` can only be used in a contract because only contracts are allowed to access persistent storage.

## Creating a New `StorageVec`

To create a new empty `StorageVec`, we have to declare the vector in a `storage` block as follows:

```sway
    v: StorageVec<u64> = StorageVec {},
```

Just like any other storage variable, two things are required when declaring a `StorageVec`: a type annotation and an initializer. The initializer is just an empty struct of type `StorageVec` because `StorageVec<T>` itself is an empty struct! Everything that is interesting about `StorageVec<T>` is implemented in its methods.

Storage vectors, just like `Vec<T>`, are implemented using generics which means that the `StorageVec<T>` type provided by the standard library can hold any type. When we create a `StorageVec` to hold a specific type, we can specify the type within angle brackets. In the example above, we’ve told the Sway compiler that the `StorageVec<T>` in `v` will hold elements of the `u64` type.

## Updating a `StorageVec`

To add elements to a `StorageVec`, we can use the `push` method, as shown below:

```sway
    #[storage(read, write)]
    fn push_to_storage_vec() {
        storage.v.push(5);
        storage.v.push(6);
        storage.v.push(7);
        storage.v.push(8);
    }
```

Note two details here. First, in order to use `push`, we need to first access the vector using the `storage` keyword. Second, because `push` requires accessing storage, a `storage` annotation is required on the ABI function that calls `push`. While it may seem that `#[storage(write)]` should be enough here, the `read` annotation is also required because each call to `push` requires _reading_ (and then updating) the length of the `StorageVec` which is also stored in persistent storage.

> **Note**
> The storage annotation is also required for any private function defined in the contract that tries to push into the vector.

<!-- markdownlint-disable-line MD028 -->
> **Note**
> There is no need to add the `mut` keyword when declaring a `StorageVec<T>`. All storage variables are mutable by default.

## Reading Elements of Storage Vectors

To read a value stored in a vector at a particular index, you can use the `get` method as shown below:

```sway
    #[storage(read)]
    fn read_from_storage_vec() {
        let third = storage.v.get(2);
        match third {
            Some(third) => log(third.read()),
            None => revert(42),
        }
    }
```

Note three details here. First, we use the index value of `2` to get the third element because vectors are indexed by number, starting at zero. Second, we get the third element by using the `get` method with the index passed as an argument, which gives us an `Option<StorageKey<T>>`. Third, the ABI function calling `get` only requires the annotation `#[storage(read)]` as one might expect because `get` does not write to storage.

When the `get` method is passed an index that is outside the vector, it returns `None` without panicking. This is particularly useful if accessing an element beyond the range of the vector may happen occasionally under normal circumstances. Your code will then have logic to handle having either `Some(element)` or `None`. For example, the index could be coming as a contract method argument. If the argument passed is too large, the method `get` will return a `None` value, and the contract method may then decide to revert when that happens or return a meaningful error that tells the user how many items are in the current vector and give them another chance to pass a valid value.

## Iterating over the Values in a Vector

Iterating over a storage vector is conceptually the same as [iterating over a `Vec<T>`](./vec.md). The only difference is an additional call to `read()` to actually read the stored value.

```sway
    #[storage(read)]
    fn iterate_over_a_storage_vec() {
        // Iterate over all the elements
        // in turn using the `while` loop.
        // **This approach is not recommended.**
        // For iterating over all the elements
        // in turn use the `for` loop instead.
        let mut i = 0;
        while i < storage.v.len() {
            log(storage.v.get(i).unwrap().read());
            i += 1;
        }

        // The preferred and most performant way
        // to iterate over all the elements in turn is
        // to use the `for` loop.
        for elem in storage.v.iter() {
            log(elem.read());
        }

        // Use the `while` loop only when more
        // control over traversal is needed.
        // E.g., in the below example we iterate
        // the vector backwards, accessing only
        // every second element.
        let mut i = storage.v.len() - 1;
        while 0 <= i {
            log(storage.v.get(i).unwrap().read());
            i -= 2;
        }
    }
```

Note that **modifying a vector during iteration, by e.g. adding or removing elements, is a logical error and results in an [undefined behavior](../reference/undefined_behavior.md)**:

## Using an Enum to store Multiple Types

Storage vectors, just like `Vec<T>`, can only store values that are the same type. Similarly to what we did for `Vec<T>` in the section [Using an Enum to store Multiple Types](./vec.md#using-an-enum-to-store-multiple-types), we can define an enum whose variants will hold the different value types, and all the enum variants will be considered the same type: that of the enum. This is shown below:

```sway
enum TableCell {
    Int: u64,
    B256: b256,
    Boolean: bool,
}
```

Then we can declare a `StorageVec` in a `storage` block to hold that enum and so, ultimately, holds different types:

```sway
    row: StorageVec<TableCell> = StorageVec {},
```

We can now push different enum variants to the `StorageVec` as follows:

```sway
    #[storage(read, write)]
    fn push_to_multiple_types_storage_vec() {
        storage.row.push(TableCell::Int(3));
        storage
            .row
            .push(TableCell::B256(0x0101010101010101010101010101010101010101010101010101010101010101));
        storage.row.push(TableCell::Boolean(true));
    }
```

Now that we’ve discussed some of the most common ways to use storage vectors, be sure to review the API documentation for all the many useful methods defined on `StorageVec<T>` by the standard library. For now, these can be found in the [source code for `StorageVec<T>`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/storage.sw). For example, in addition to `push`, a `pop` method removes and returns the last element, a `remove` method removes and returns the element at some chosen index within the vector, an `insert` method inserts an element at some chosen index within the vector, etc.

## Nested Storage Vectors

It is possible to nest storage vectors as follows:

```sway
    nested_vec: StorageVec<StorageVec<u64>> = StorageVec {},
```

The nested vector can then be accessed as follows:

```sway
    #[storage(read, write)]
    fn access_nested_vec() {
        storage.nested_vec.push(StorageVec {});
        storage.nested_vec.push(StorageVec {});

        let mut inner_vec0 = storage.nested_vec.get(0).unwrap();
        let mut inner_vec1 = storage.nested_vec.get(1).unwrap();

        inner_vec0.push(0);
        inner_vec0.push(1);

        inner_vec1.push(2);
        inner_vec1.push(3);
        inner_vec1.push(4);

        assert(inner_vec0.len() == 2);
        assert(inner_vec0.get(0).unwrap().read() == 0);
        assert(inner_vec0.get(1).unwrap().read() == 1);
        assert(inner_vec0.get(2).is_none());

        assert(inner_vec1.len() == 3);
        assert(inner_vec1.get(0).unwrap().read() == 2);
        assert(inner_vec1.get(1).unwrap().read() == 3);
        assert(inner_vec1.get(2).unwrap().read() == 4);
        assert(inner_vec1.get(3).is_none());
    }
```


---

### File: docs/nightly/sway/docs/book/src/common-collections/vec.md

# Vectors on the Heap

The first collection type we’ll look at is `Vec<T>`, also known as a vector. Vectors allow you to store more than one value in a single data structure that puts all the values next to each other in memory. Vectors can only store values of the same type. They are useful when you have a list of items, such as the lines of text in a file or the prices of items in a shopping cart.

`Vec<T>` is included in the [standard library prelude](../introduction/standard_library.md#standard-library-prelude) which means that there is no need to import it manually.

## Creating a New Vector

To create a new empty vector, we call the `Vec::new` function, as shown below:

```sway
    let v: Vec<u64> = Vec::new();
```

Note that we added a type annotation here. Because we aren’t inserting any values into this vector, the Sway compiler doesn’t know what kind of elements we intend to store. Vectors are implemented using generics which means that the `Vec<T>` type provided by the standard library can hold any type. When we create a vector to hold a specific type, we can specify the type within angle brackets. In the example above, we’ve told the Sway compiler that the `Vec<T>` in `v` will hold elements of the `u64` type.

## Updating a Vector

To create a vector and then add elements to it, we can use the `push` method, as shown below:

```sway
    let mut v = Vec::new();

    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);
```

As with any variable, if we want to be able to change its value, we need to make it mutable using the `mut` keyword, as discussed in the section [Declaring a Variable](../basics/variables.md#declaring-a-variable). The numbers we place inside are all of type `u64`, and the Sway compiler infers this from the data, so we don’t need the `Vec<u64>` annotation.

## Reading Elements of Vectors

To read a value stored in a vector at a particular index, you can use the `get` method as shown below:

```sway
    let third = v.get(2);
    match third {
        Some(third) => log(third),
        None => revert(42),
    }
    let does_not_exist = v.get(100);
    // ...decide here how to handle an out-of-bounds access
```

Note two details here. First, we use the index value of `2` to get the third element because vectors are indexed by number, starting at zero. Second, we get the third element by using the `get` method with the index passed as an argument, which gives us an `Option<T>`.

When the `get` method is passed an index that is outside the vector, it returns `None` without panicking. This is particularly useful if accessing an element beyond the range of the vector may happen occasionally under normal circumstances. Your code will then have logic to handle having either `Some(element)` or `None`. For example, the index could be coming as a contract method argument. If the argument passed is too large, the method `get` will return a `None` value, and the contract method may then decide to revert when that happens or return a meaningful error that tells the user how many items are in the current vector and give them another chance to pass a valid value.

## Iterating over the Values in a Vector

To access elements of a vector, we can iterate through the valid indices using a `while` loop and the `len` method as shown below:

```sway
    let mut i = 0;
    while i < v.len() {
        log(v.get(i).unwrap());
        i += 1;
    }
```

Note two details here. First, we use the method `len` which returns the length of the vector. Second, we call the method `unwrap` to extract the `Option` returned by `get`. We know that `unwrap` will not fail (i.e. will not cause a revert) because each index `i` passed to `get` is known to be smaller than the length of the vector.

The idiomatic and convenient way to access each element in a vector in turn, is to use the `for` loop in the combination with the `iter` method. The `iter` method returns an iterator that iterates over all the elements of the vector sequentially.

```sway
    for elem in v.iter() {
        log(elem);
    }
    for elem in v.iter() {
        log(elem);
        if elem == 3 {
            v.push(6); // Modification causes undefined behavior!
        }
    }
```

Note that **modifying a vector during iteration, by e.g. adding or removing elements, is a logical error and results in an [undefined behavior](../reference/undefined_behavior.md)**:

```sway
    for elem in v.iter() {
        log(elem);
        if elem == 3 {
            v.push(6); // Modification causes undefined behavior!
        }
    }
```

Accessing vector elements via `while` loop should be used only when more control over traversal is needed. E.g., in the below example we iterate the vector backwards, accessing only every second element.

```sway
    // Start from the end
    let mut i = v.len() - 1;
    while 0 <= i {
        log(v.get(i).unwrap());
        // Access every second element
        i -= 2;
    }
```

## Using an Enum to store Multiple Types

Vectors can only store values that are the same type. This can be inconvenient; there are definitely use cases for needing to store a list of items of different types. Fortunately, the variants of an enum are defined under the same enum type, so when we need one type to represent elements of different types, we can define and use an enum!

For example, say we want to get values from a row in a table in which some of the columns in the row contain integers, some `b256` values, and some Booleans. We can define an enum whose variants will hold the different value types, and all the enum variants will be considered the same type: that of the enum. Then we can create a vector to hold that enum and so, ultimately, holds different types. We’ve demonstrated this below:

```sway
    enum TableCell {
        Int: u64,
        B256: b256,
        Boolean: bool,
    }

    let mut row = Vec::new();
    row.push(TableCell::Int(3));
    row.push(TableCell::B256(0x0101010101010101010101010101010101010101010101010101010101010101));
    row.push(TableCell::Boolean(true));
```

Now that we’ve discussed some of the most common ways to use vectors, be sure to review the API documentation for all the many useful methods defined on `Vec<T>` by the standard library. For now, these can be found in the [source code for `Vec<T>`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/vec.sw). For example, in addition to `push`, a `pop` method removes and returns the last element, a `remove` method removes and returns the element at some chosen index within the vector, an `insert` method inserts an element at some chosen index within the vector, etc.


---

### File: docs/nightly/sway/docs/book/src/debugging/debugging_with_cli.md

# Debugging with CLI

The `forc debug` CLI enables debugging a live transaction on a running Fuel Client node.

## An example project

First, we need a project to debug, so create a new project using

```bash
forc new --script dbg_example && cd dbg_example
```

And then add some content to `src/main.sw`, for example:

```sway
script;

use std::logging::log;

fn factorial(n: u64) -> u64 {
    let mut result = 1;
    let mut counter = 0;
    while counter < n {
        counter = counter + 1;
        result = result * counter;
    }
    return result;
}

fn main() {
    log::<u64>(factorial(5)); // 120
}
```

## Building and bytecode output

Now we are ready to build the project.

```bash
forc build
```

After this the resulting binary should be located at `out/debug/dbg_example.bin`. Because we are interested in the resulting bytecode, we can read that with:

```bash
forc parse-bytecode out/debug/dbg_example.bin
```

We can recognize the main loop by observing the control flow. Looking around halfword 58-60, we can see:

```text
  half-word   byte    op                                                 raw
          58   232    MOVI { dst: 0x11, val: 5 }                         72 44 00 05                                 
          59   236    LT { dst: 0x10, lhs: 0x10, rhs: 0x11 }             16 41 04 40                                 
          60   240    JNZF { cond_nz: 0x10, dynamic: 0x0, fixed: 81 }    76 40 00 51
```

Here we can see our `factorial(5)` being set up with `MOVI` setting the value 5, followed by the `LT` comparison and conditional jump `JNZF`. The multiplication for our factorial happens at halfword 147 with `MUL { dst: 0x10, lhs: 0x10, rhs: 0x11 }`. Finally, we can spot our log statement at halfword 139 with the `LOGD` instruction.

## Setting up the debugging

We can start up the debug infrastructure. On a new terminal session run `fuel-core run --db-type in-memory --debug`; we need to have that running because it actually executes the program. Now we can fire up the debugger itself: `forc-debug`. Now if everything is set up correctly, you should see the debugger prompt (`>>`). You can use `help` command to list available commands.

The debugger supports tab completion to help you discover files in your current working directory (and its subdirectories):

- Type `tx` and press tab to recursively search for valid transaction JSON files
- After selecting a transaction file, press tab again to search for ABI files
- You can keep pressing tab to cycle through the found files
- Of course, you can also manually type the full path to any transaction or ABI file, they don't have to be in your current directory

Now we would like to inspect the program while it's running. To do this, we first need to send the script to the executor, i.e. `fuel-core`. To do so, we need a *transaction specification*, `tx.json`. It looks something like this:

```json
{
  "Script": {
    "body": {
      "script_gas_limit": 1000000,
      "script": [
        26, 240, 48, 0, 116, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 96, 93, 255, 192, 1, 16, 255, 255, 0, 26, 236, 80, 0, 145, 0, 0, 184, 80, 67, 176, 80, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 37, 80, 71, 176, 40, 26, 233, 16, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 136, 26, 71, 208, 0, 114, 72, 0, 24, 40, 237, 20, 128, 80, 79, 176, 120, 114, 68, 0, 24, 40, 79, 180, 64, 80, 71, 176, 160, 114, 72, 0, 24, 40, 69, 52, 128, 80, 71, 176, 96, 114, 72, 0, 24, 40, 69, 52, 128, 80, 75, 176, 64, 26, 233, 16, 0, 26, 229, 32, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 144, 26, 71, 208, 0, 80, 75, 176, 24, 114, 76, 0, 16, 40, 73, 20, 192, 80, 71, 176, 144, 114, 76, 0, 16, 40, 69, 36, 192, 114, 72, 0, 16, 40, 65, 20, 128, 93, 69, 0, 1, 93, 65, 0, 0, 37, 65, 16, 0, 149, 0, 0, 63, 150, 8, 0, 0, 26, 236, 80, 0, 145, 0, 1, 88, 26, 87, 224, 0, 95, 236, 16, 42, 95, 236, 0, 41, 93, 67, 176, 41, 114, 68, 0, 5, 22, 65, 4, 64, 118, 64, 0, 81, 93, 67, 176, 42, 80, 71, 176, 200, 26, 233, 16, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 87, 26, 71, 208, 0, 114, 72, 0, 24, 40, 237, 20, 128, 80, 71, 176, 160, 114, 72, 0, 24, 40, 71, 180, 128, 80, 75, 176, 24, 114, 76, 0, 24, 40, 73, 20, 192, 80, 71, 176, 88, 114, 76, 0, 24, 40, 69, 36, 192, 93, 83, 176, 11, 93, 79, 176, 12, 93, 71, 176, 13, 114, 72, 0, 8, 16, 73, 20, 128, 21, 73, 36, 192, 118, 72, 0, 1, 116, 0, 0, 7, 114, 72, 0, 2, 27, 73, 52, 128, 114, 76, 0, 8, 16, 77, 36, 192, 38, 76, 0, 0, 40, 29, 68, 64, 26, 80, 112, 0, 16, 73, 68, 64, 95, 73, 0, 0, 114, 64, 0, 8, 16, 65, 20, 0, 80, 71, 176, 112, 95, 237, 64, 14, 95, 237, 48, 15, 95, 237, 0, 16, 80, 67, 176, 48, 114, 72, 0, 24, 40, 65, 20, 128, 80, 71, 176, 136, 114, 72, 0, 24, 40, 69, 4, 128, 80, 67, 177, 8, 114, 72, 0, 24, 40, 65, 20, 128, 80, 71, 177, 48, 114, 72, 0, 24, 40, 69, 4, 128, 80, 67, 177, 48, 80, 71, 176, 240, 114, 72, 0, 24, 40, 69, 4, 128, 80, 67, 176, 224, 26, 233, 16, 0, 26, 229, 0, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 56, 26, 67, 208, 0, 80, 71, 176, 72, 114, 72, 0, 16, 40, 69, 4, 128, 80, 67, 177, 32, 114, 72, 0, 16, 40, 65, 20, 128, 80, 71, 176, 184, 114, 72, 0, 16, 40, 69, 4, 128, 93, 67, 240, 0, 93, 71, 176, 23, 93, 75, 176, 24, 52, 1, 4, 82, 26, 244, 0, 0, 116, 0, 0, 8, 93, 67, 176, 41, 16, 65, 0, 64, 95, 237, 0, 41, 93, 67, 176, 42, 93, 71, 176, 41, 27, 65, 4, 64, 95, 237, 0, 42, 117, 0, 0, 91, 146, 0, 1, 88, 26, 249, 80, 0, 152, 8, 0, 0, 151, 0, 0, 63, 74, 248, 0, 0, 149, 0, 0, 15, 150, 8, 0, 0, 26, 236, 80, 0, 145, 0, 0, 72, 26, 67, 160, 0, 26, 71, 224, 0, 114, 72, 4, 0, 38, 72, 0, 0, 26, 72, 112, 0, 80, 79, 176, 24, 95, 237, 32, 3, 114, 72, 4, 0, 95, 237, 32, 4, 95, 236, 0, 5, 114, 72, 0, 24, 40, 237, 52, 128, 80, 75, 176, 48, 114, 76, 0, 24, 40, 75, 180, 192, 114, 76, 0, 24, 40, 65, 36, 192, 26, 245, 0, 0, 146, 0, 0, 72, 26, 249, 16, 0, 152, 8, 0, 0, 151, 0, 0, 15, 74, 248, 0, 0, 149, 0, 0, 63, 150, 8, 0, 0, 26, 236, 80, 0, 145, 0, 0, 104, 26, 67, 160, 0, 26, 71, 144, 0, 26, 75, 224, 0, 80, 79, 176, 80, 114, 80, 0, 24, 40, 77, 5, 0, 114, 64, 0, 24, 40, 237, 52, 0, 80, 67, 176, 40, 114, 76, 0, 24, 40, 67, 180, 192, 93, 79, 176, 5, 80, 65, 0, 16, 80, 83, 176, 64, 95, 237, 48, 8, 80, 77, 64, 8, 114, 84, 0, 8, 40, 77, 5, 64, 80, 67, 176, 24, 114, 76, 0, 16, 40, 65, 68, 192, 114, 76, 0, 16, 40, 69, 4, 192, 26, 245, 16, 0, 146, 0, 0, 104, 26, 249, 32, 0, 152, 8, 0, 0, 151, 0, 0, 63, 74, 248, 0, 0, 71, 0, 0, 0, 21, 6, 230, 244, 76, 29, 98, 145
      ],
      "script_data": [],
      "receipts_root": "0000000000000000000000000000000000000000000000000000000000000000"
    },
    "policies": {
      "bits": "MaxFee",
      "values": [0, 0, 0, 0]
    },
    "inputs": [
      {
        "CoinSigned": {
          "utxo_id": {
            "tx_id": "c49d65de61cf04588a764b557d25cc6c6b4bc0d7429227e2a21e61c213b3a3e2",
            "output_index": 18
          },
          "owner": "f1e92c42b90934aa6372e30bc568a326f6e66a1a0288595e6e3fbd392a4f3e6e",
          "amount": 10599410012256088000,
          "asset_id": "2cafad611543e0265d89f1c2b60d9ebf5d56ad7e23d9827d6b522fd4d6e44bc3",
          "tx_pointer": {
            "block_height": 0,
            "tx_index": 0
          },
          "witness_index": 0,
          "maturity": 0,
          "predicate_gas_used": null,
          "predicate": null,
          "predicate_data": null
        }
      }
    ],
    "outputs": [],
    "witnesses": [
      {
        "data": [156, 254, 34, 102, 65, 96, 133, 170, 254, 105, 147, 35, 196, 199, 179, 133, 132, 240, 208, 149, 11, 46, 30, 96, 44, 91, 121, 195, 145, 184, 159, 235, 117, 82, 135, 41, 84, 154, 102, 61, 61, 16, 99, 123, 58, 173, 75, 226, 219, 139, 62, 33, 41, 176, 16, 18, 132, 178, 8, 125, 130, 169, 32, 108]
      }
    ]
  }
}
```

However, the key `script` should contain the actual bytecode to execute, i.e. the contents of `out/debug/dbg_example.bin` as a JSON array. The following command can be used to generate it:

```bash
python3 -c 'print(list(open("out/debug/dbg_example.bin", "rb").read()))'
```

So now we replace the script array with the result, and save it as `tx.json`.

## Using the debugger

Now we can actually execute the script with an ABI to decode the log values:

```text
>> start_tx tx.json out/debug/dbg_example-abi.json

Receipt: LogData { id: 0000000000000000000000000000000000000000000000000000000000000000, ra: 0, rb: 1515152261580153489, ptr: 67107840, len: 8, digest: d2b80ebb9ce633ad49a9ccfcc58ac7ad33a9ab4741529ae4247a3b07e8fa1c74, pc: 10924, is: 10368, data: Some(0000000000000078) }
Decoded log value: 120, from contract: 0000000000000000000000000000000000000000000000000000000000000000
Receipt: ReturnData { id: 0000000000000000000000000000000000000000000000000000000000000000, ptr: 67106816, len: 0, digest: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855, pc: 10564, is: 10368, data: Some() }
Receipt: ScriptResult { result: Success, gas_used: 1273 }
Terminated
```

Looking at the output, we can see our `factorial(5)` result as the decoded log value of 120. The ABI has helped us decode the raw bytes `(0000000000000078)` into a meaningful value. It also tells us that the execution terminated without hitting any breakpoints. That's unsurprising, because we haven't set up any. We can do so with `breakpoint` command:

```text
>> breakpoint 0

>> start_tx tx.json out/debug/dbg_example-abi.json

Receipt: ScriptResult { result: Success, gas_used: 0 }
Stopped on breakpoint at address 0 of contract 0x0000000000000000000000000000000000000000000000000000000000000000
```

Now we have stopped execution at the breakpoint on entry (address `0`). We can now inspect the initial state of the VM.

```text
>> register ggas

reg[0x9] = 1000000  # ggas

>> memory 0x10 0x8

 000010: db f3 63 c9 1c 7f ec 95
```

However, that's not too interesting either, so let's just execute until the end, and then reset the VM to remove the breakpoints.

```text
>> continue

Receipt: LogData { id: 0000000000000000000000000000000000000000000000000000000000000000, ra: 0, rb: 1515152261580153489, ptr: 67107840, len: 8, digest: d2b80ebb9ce633ad49a9ccfcc58ac7ad33a9ab4741529ae4247a3b07e8fa1c74, pc: 10924, is: 10368, data: Some(0000000000000078) }
Decoded log value: 120, from contract: 0000000000000000000000000000000000000000000000000000000000000000
Receipt: ReturnData { id: 0000000000000000000000000000000000000000000000000000000000000000, ptr: 67106816, len: 0, digest: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855, pc: 10564, is: 10368, data: Some() }
Terminated

>> reset
```

Next, we will setup a breakpoint to check the state on each iteration of the `while` loop. For instance, if we'd like to see what numbers get multiplied together, we could set up a breakpoint before the operation. Looking at our bytecode we can see the main multiplication for our factorial happens at:

```text
  half-word   byte   op                                        raw
        147   588    MUL { dst: 0x10, lhs: 0x10, rhs: 0x11 }   1b 41 04 40
```

We can set a breakpoint on its address, at halfword-offset `147`.

```text
>>> breakpoint 147

>> start_tx tx.json out/debug/dbg_example-abi.json

Receipt: ScriptResult { result: Success, gas_used: 82 }
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000
```

Now we can inspect the inputs to multiply. Looking at [the specification](https://github.com/FuelLabs/fuel-specs/blob/master/src/fuel-vm/instruction-set.md#mul-multiply) tells us that the instruction `MUL { dst: 0x10, lhs: 0x10, rhs: 0x11 }` means `reg[0x10] = reg[0x10] * reg[0x11]`. So inspecting the inputs:

```text
>> r 0x10 0x11
reg[0x10] = 1        # reg16
reg[0x11] = 1        # reg17
```

So on the first round the numbers are 1 and 1, so we can continue to the next iteration with the `c` command:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 1        # reg16
reg[0x11] = 2        # reg17
```

And the next one:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 2        # reg16
reg[0x11] = 3        # reg17
```

And fourth one:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 6        # reg16
reg[0x11] = 4        # reg17
```

And round 5:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 24       # reg16
reg[0x11] = 5        # reg17
```

At this point we can look at the values

0x10 | 0x11
-----|------
1    | 1
1    | 2
2    | 3
6    | 4
24   | 5

From this we can clearly see that the left side, register `0x10` is the `result` variable which accumulates the factorial calculation (1, 1, 2, 6, 24), and register `0x11` is the `counter` which increments from 1 to 5. Now the counter equals the given factorial function argument `5`, and the loop terminates. So when we continue, the program finishes without encountering any more breakpoints:

```text
>> c

Receipt: LogData { id: 0000000000000000000000000000000000000000000000000000000000000000, ra: 0, rb: 1515152261580153489, ptr: 67107840, len: 8, digest: d2b80ebb9ce633ad49a9ccfcc58ac7ad33a9ab4741529ae4247a3b07e8fa1c74, pc: 10924, is: 10368, data: Some(0000000000000078) }
Decoded log value: 120, from contract: 0000000000000000000000000000000000000000000000000000000000000000
Receipt: ReturnData { id: 0000000000000000000000000000000000000000000000000000000000000000, ptr: 67106816, len: 0, digest: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855, pc: 10564, is: 10368, data: Some() }
Terminated
```


---

### File: docs/nightly/sway/docs/book/src/debugging/debugging_with_forc_call.md

# Debugging with Forc Call

The `forc call` command includes interactive debugging capabilities through the `--debug` flag, enabling developers to debug contract function calls step-by-step after transaction execution.

## Overview

When you add the `--debug` flag to any `forc call` command, it will:

1. Execute the contract function call as normal
2. Automatically launch an interactive debugging session
3. Allow you to step through the execution, inspect values, and set breakpoints
4. Provide full access to the `forc-debug` interface

This integration seamlessly combines contract interaction with debugging, making it easy to understand what happens during contract execution.

## Basic Usage

Simply add the `--debug` flag to any existing `forc call` command:

```bash
forc call <CONTRACT_ID> \
    --abi <ABI_PATH> \
    <FUNCTION_NAME> [ARGS...] \
    --debug
```

## Example: Debugging a Contract Call

Let's say you have a contract with a function that performs some calculations:

```sway
contract;

abi Calculator {
    fn factorial(n: u64) -> u64;
}

impl Calculator for Contract {
    fn factorial(n: u64) -> u64 {
        let mut result = 1;
        let mut counter = 0;
        while counter < n {
            counter = counter + 1;
            result = result * counter;
        }
        result
    }
}
```

### Debugging the Factorial Function

```bash
forc call 0x1234567890abcdef1234567890abcdef12345678 \
    --abi ./out/debug/calculator-abi.json \
    factorial 5 \
    --debug
```

This command will:

1. Execute `factorial(5)` on the deployed contract
2. Show the transaction result (return value: 120)
3. Launch the interactive debugger with the transaction data pre-loaded

### Interactive Debugging Session

Once the debugger launches, you'll see the pre-buffered debugger prompt to start the transaction:

```text
Welcome to the Sway Debugger! Type "help" for a list of commands.
>> start_tx /var/folders/xz/5djvk4596k5c1fj2prcd0d880000gn/T/.tmpexrnFE.json /var/folders/xz/5djvk4596k5c1fj2prcd0d880000gn/T/.tmpuaPRtF.json
```

You can now use all the [standard debugging commands](./debugging_with_cli.md#using-the-debugger).


---

### File: docs/nightly/sway/docs/book/src/debugging/debugging_with_ide.md

# Debugging with IDE

The `forc debug` plugin also enables line-by-line debugging of Sway unit tests in VSCode.

## Installation

1. Install the Sway VSCode extension from the [marketplace](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin).
2. Ensure you have the forc-debug binary installed. `which forc-debug`.
It can be installed with `fuelup component add forc-debug`.
3. Create a `.vscode/launch.json` file with the following contents:

```json
{
    "version": "0.2.0",
    "configurations": [
        {
        "type": "sway",
        "request": "launch",
        "name": "Debug Sway",
        "program": "${file}"
    }]
}
```

## An example project

Given this example contract:

```sway
contract;

abi CallerContract {
    fn test_false() -> bool;
}

impl CallerContract for Contract {
    fn test_false() -> bool {
        false
    }
}

abi CalleeContract {
    fn test_true() -> bool;
}

#[test]
fn test_multi_contract_calls() {
    let caller = abi(CallerContract, CONTRACT_ID);
    let callee = abi(CalleeContract, callee::CONTRACT_ID);

    let should_be_false = caller.test_false();
    let should_be_true = callee.test_true();
    assert(!should_be_false);
    assert(should_be_true);
}
```

Within the sway file open in VSCode, you can set breakpoints on lines within the test or functions that it calls, and click Run -> Start Debugging to begin debugging the unit test.

This will build the sway project and run it in debug mode. The debugger will stop the VM execution when a breakpoint is hit.

The debug panel will show VM registers under the Variables tab, as well as the current VM opcode where execution is suspended. You can continue execution, or use the Step Over function to step forward, instruction by instruction.


---

### File: docs/nightly/sway/docs/book/src/debugging/index.md

# Debugging

Forc provides tools for debugging both live transactions as well as Sway unit tests.
Debugging can be done via CLI or using the VSCode IDE.

**Unit testing** refers to "in-language" test functions annotated with `#[test]`. Line-by-line
debugging is available within the VSCode IDE.

**Live transaction** refers to the testing sending a transaction to a running Fuel Client
node to exercise your Sway code. Instruction-by-instruction debugging is available in the `forc debug` CLI.

- [Debugging with CLI](./debugging_with_cli.md)
- [Debugging with IDE](./debugging_with_ide.md)

## `__dbg` intrinsic function

Sway also offers the `__dbg` intrinsic function to help debug all applications types: scripts, contracts and predicates.
When called, this intrinsic function will print the current file, line and column, together with a customizable print of the specified value.

```sway
script;
fn main() -> u64 {
    __dbg(1u64)
}
```

The application above will print:

```terminal
[src/main.sw:3:5] = 1
```

Structs can be customized by implementing the `Debug` trait.

```sway
script;
struct S { }
impl Debug for S {
    fn fmt(self, ref mut f: Formatter) {
        f.debug_struct("S2")
            .field("field1", 1)
            .field("field2", "Hello")
            .finish();
    }
}
fn main() -> u64 {
    let _ = __dbg(S {});
    __dbg(1u64)
}
```

This code is very similar to what the Sway compiler generates by default for all declared types.
And this is what is printed:

```terminal
[src/main.sw:12:13] = S2 { field1: 1, field2: "Hello" }
[src/main.sw:13:5] = 1
```


---

### File: docs/nightly/sway/docs/book/src/examples/counter.md

# Counter

The following is a simple example of a contract which implements a counter. Both the `initialize_counter()` and `increment_counter()` ABI methods return the currently set value.

```bash
forc template --template-name counter my_counter_project
```

```sway
contract;

abi TestContract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64;

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
}

impl TestContract for Contract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64 {
        storage.counter.write(value);
        value
    }

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64 {
        let incremented = storage.counter.read() + amount;
        storage.counter.write(incremented);
        incremented
    }
}

```

## Build and deploy

The following commands can be used to build and deploy the contract. For a detailed tutorial, refer to [Building and Deploying](https://docs.fuel.network/guides/contract-quickstart/#building-the-contract).

```bash
# Build the contract
forc build

# Deploy the contract
forc deploy --testnet
```


---

### File: docs/nightly/sway/docs/book/src/examples/fizzbuzz.md

# `FizzBuzz`

This example is not the traditional [`FizzBuzz`](https://en.wikipedia.org/wiki/Fizz_buzz#Programming); instead it is the smart contract version! A script can call the `fizzbuzz` ABI method of this contract with some `u64` value and receive back the result as an `enum`.

The format for custom structs and enums such as `FizzBuzzResult` will be automatically included in the ABI JSON so that off-chain code can handle the encoded form of the returned data.

```sway
contract;

enum FizzBuzzResult {
    Fizz: (),
    Buzz: (),
    FizzBuzz: (),
    Other: u64,
}

abi FizzBuzz {
    fn fizzbuzz(input: u64) -> FizzBuzzResult;
}

impl FizzBuzz for Contract {
    fn fizzbuzz(input: u64) -> FizzBuzzResult {
        if input % 15 == 0 {
            FizzBuzzResult::FizzBuzz
        } else if input % 3 == 0 {
            FizzBuzzResult::Fizz
        } else if input % 5 == 0 {
            FizzBuzzResult::Buzz
        } else {
            FizzBuzzResult::Other(input)
        }
    }
}

```


---

### File: docs/nightly/sway/docs/book/src/examples/index.md

# Example

Some basic example contracts to see how Sway and Forc work.

- [Counter](./counter.md)
- [`FizzBuzz`](./fizzbuzz.md)
- [Wallet Smart Contract](./wallet_smart_contract.md)
- [Liquidity Pool](./wallet_smart_contract.md)

Additional examples can be found in the [Sway Applications](https://github.com/FuelLabs/sway-applications/tree/master) repository.


---

### File: docs/nightly/sway/docs/book/src/examples/liquidity_pool.md

# Liquidity Pool Example

All contracts in Fuel can mint and burn their own native asset. Contracts can also receive and transfer any native asset including their own. Internal balances of all native assets pushed through calls or minted by the contract are tracked by the FuelVM and can be queried at any point using the `balance_of` function from the `std` library. Therefore, there is no need for any manual accounting of the contract's balances using persistent storage.

The `std` library provides handy methods for accessing Fuel's native asset operations.

In this example, we show a basic liquidity pool contract minting its own native asset LP asset.

```sway
contract;

use std::{
    asset::{
        mint_to,
        transfer,
    },
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    hash::*,
};

abi LiquidityPool {
    fn deposit(recipient: Address);
    fn withdraw(recipient: Address);
}

const BASE_ASSET: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);

impl LiquidityPool for Contract {
    fn deposit(recipient: Address) {
        assert(msg_asset_id() == BASE_ASSET);
        assert(msg_amount() > 0);

        // Mint two times the amount.
        let amount_to_mint = msg_amount() * 2;

        // Mint some LP assets based upon the amount of the base asset.
        mint_to(Identity::Address(recipient), DEFAULT_SUB_ID, amount_to_mint);
    }

    fn withdraw(recipient: Address) {
        let asset_id = AssetId::default();
        assert(msg_asset_id() == asset_id);
        assert(msg_amount() > 0);

        // Amount to withdraw.
        let amount_to_transfer = msg_amount() / 2;

        // Transfer base asset to recipient.
        transfer(Identity::Address(recipient), BASE_ASSET, amount_to_transfer);
    }
}

```


---

### File: docs/nightly/sway/docs/book/src/examples/sway_applications.md

# Sway Applications

The [Sway-Applications](https://github.com/FuelLabs/sway-applications) Repository contains end-to-end example applications that are written in Sway in order to demonstrate what can be built.

## Asset Management

- [Airdrop](https://github.com/FuelLabs/sway-applications/tree/master/airdrop) is an asset distribution program where users are able to claim assets given a valid merkle proof.
- [Escrow](https://github.com/FuelLabs/sway-applications/tree/master/escrow) is a third party that keeps an asset on behalf of multiple parties.
- [Non-Fungible Native Asset (NFT)](https://github.com/FuelLabs/sway-applications/tree/master/NFT) is an asset contract which provides unique collectibles, identified and differentiated by IDs, where assets contain metadata giving them distinctive characteristics.
- [Fractional Non-Fungible Token (F-NFT)](https://github.com/FuelLabs/sway-applications/tree/master/fractional-NFT) is a token contract which issues shares or partial ownership upon locking an NFT into a vault.
- [Timelock](https://github.com/FuelLabs/sway-applications/tree/master/timelock) is a contract which restricts the execution of a transaction to a specified time range.
- [Native Asset](https://github.com/FuelLabs/sway-applications/tree/master/native-asset) is a basic asset contract that enables the use of Native Assets on Fuel using existing standards and libraries.

## Decentralized Finance

- [English Auction](https://github.com/FuelLabs/sway-applications/tree/master/english-auction) is an auction where users bid up the price of an asset until the bidding period has ended or a reserve has been met.
- [Fundraiser](https://github.com/FuelLabs/sway-applications/tree/master/fundraiser) is a program allowing users to pledge towards a goal.
- [OTC Swap Predicate](https://github.com/FuelLabs/sway-applications/tree/master/OTC-swap-predicate) is a predicate that can be used to propose and execute an atomic swap between two parties without requiring any on-chain state.

## Governance

- [Decentralized Autonomous Organization (DAO)](https://github.com/FuelLabs/sway-applications/tree/master/DAO) is an organization where users get to vote on governance proposals using governance assets.
- [Multi-Signature Wallet](https://github.com/FuelLabs/sway-applications/tree/master/multisig-wallet) is a wallet that requires multiple signatures to execute a transaction.

## Games

- [TicTacToe](https://github.com/FuelLabs/sway-applications/tree/master/TicTacToe) is a game where two players compete to align three markers in a row.

## Other

- [Counter-Script](https://github.com/FuelLabs/sway-applications/tree/master/counter-script) is a script that calls a contract to increment a counter.
- [Name-Registry](https://github.com/FuelLabs/sway-applications/tree/master/name-registry) allows users to perform transactions with human readable names instead of addresses.
- [Oracle](https://github.com/FuelLabs/sway-applications/tree/master/oracle) is a smart contract that provides off-chain data to on-chain applications.


---

### File: docs/nightly/sway/docs/book/src/examples/wallet_smart_contract.md

# Wallet Smart Contract

The ABI declaration is a separate project from your ABI implementation. The project structure for the code should be organized as follows with the `wallet_abi` treated as an external library:

```sh
.
├── wallet_abi
│   ├── Forc.toml
│   └── src
│       └── main.sw
└── wallet_smart_contract
    ├── Forc.toml
    └── src
        └── main.sw
```

It's also important to specify the source of the dependency within the project's `Forc.toml` file when using external libraries. Inside the `wallet_smart_contract` project, it requires a declaration like this:

```sh
[dependencies]
wallet_abi = { path = "../wallet_abi/" }
```

## ABI Declaration

```sway
library;

// ANCHOR: abi
abi Wallet {
    // ANCHOR: receive_funds
    #[storage(read, write), payable]
    fn receive_funds();
    // ANCHOR_END: receive_funds

    // ANCHOR: send_funds
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
    // ANCHOR_END: send_funds
}
// ANCHOR: abi
```

## ABI Implementation

```sway
contract;

use std::{asset::transfer, call_frames::msg_asset_id, context::msg_amount};

// ANCHOR: abi_import
use wallet_abi::Wallet;
// ANCHOR_END: abi_import
const OWNER_ADDRESS = Address::from(0x8900c5bec4ca97d4febf9ceb4754a60d782abbf3cd815836c1872116f203f861);

storage {
    balance: u64 = 0,
}

// ANCHOR: abi_impl
impl Wallet for Contract {
    #[storage(read, write), payable]
    fn receive_funds() {
        if msg_asset_id() == AssetId::base() {
            // If we received the base asset then keep track of the balance.
            // Otherwise, we're receiving other native assets and don't care
            // about our balance of coins.
            storage.balance.write(storage.balance.read() + msg_amount());
        }
    }

    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address) {
        let sender = msg_sender().unwrap();
        match sender {
            Identity::Address(addr) => assert(addr == OWNER_ADDRESS),
            _ => revert(0),
        };

        let current_balance = storage.balance.read();
        assert(current_balance >= amount_to_send);

        storage.balance.write(current_balance - amount_to_send);

        // Note: `transfer()` is not a call and thus not an
        // interaction. Regardless, this code conforms to
        // checks-effects-interactions to avoid re-entrancy.
        transfer(
            Identity::Address(recipient_address),
            AssetId::base(),
            amount_to_send,
        );
    }
}
// ANCHOR_END: abi_impl
```


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_add.md

# forc add

Adds one or more dependencies to a `Forc.toml` manifest.

## **Usage**

```bash
forc add [OPTIONS] <DEP_SPEC>...
```

## **Arguments**

* `<DEP_SPEC>`: List of dependencies in the format `name[@version]` (e.g., `custom_lib@0.1.0`, `custom_contract`)

## **Options**

* `--path <PATH>`: Add a local path dependency.
* `--git <URI>`: Add a Git-based dependency.

  * Can be combined with one of:

    * `--branch <branch>`
    * `--tag <tag>`
    * `--rev <rev>`
* `--ipfs <CID>`: Add a dependency sourced from IPFS.
* `--contract-dep`: Add to `[contract-dependencies]` instead of `[dependencies]`.
* `--salt <SALT>`: Salt to use for contract deployment (only applies to contract dependencies).
* `--package <SPEC>`: Apply change to a specific package in a workspace.
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
* `--dry-run`: Show what would be changed without writing to the file.
* `--offline`: Do not fetch any remote dependencies.
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for IPFS-sourced dependencies.


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_addr2line.md

# forc addr2line


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_build.md

# forc build


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_check.md

# forc check


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_clean.md

# forc clean


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_completions.md

# forc completions


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_contract-id.md

# forc contract-id


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_init.md

# forc init


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_new.md

# forc new


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_parse-bytecode.md

# forc parse-bytecode


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_plugins.md

# forc plugins


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_predicate-root.md

# forc predicate-root


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_remove.md

# forc remove

Removes one or more dependencies from a `Forc.toml` manifest.

## **Usage**

```bash
forc remove [OPTIONS] <DEP_SPEC>...
```

## **Arguments**

* `<DEP_SPEC>`: List of dependencies to remove by name (e.g., `custom_lib`, `custom_contract`)

## **Options**

* `--contract-dep`: Remove from `[contract-dependencies]` instead of `[dependencies]`.
* `--package <SPEC>`: Target a specific package in a workspace.
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
* `--dry-run`: Preview what would be removed without making any changes.
* `--offline`: Prevent forc from fetching metadata or resolving versions remotely.
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for reference.


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_template.md

# forc template


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_test.md

# forc test


---

### File: docs/nightly/sway/docs/book/src/forc/commands/forc_update.md

# forc update


---

### File: docs/nightly/sway/docs/book/src/forc/commands/index.md

<!-- markdownlint-disable MD041 -->
Here are a list of commands available to forc:


---

### File: docs/nightly/sway/docs/book/src/forc/dependencies.md

# Dependencies

Forc has a dependency management system which can pull packages using `git`, `ipfs`, `path`, or the community `registry`. This allows users to build and share Forc libraries.

## Adding Dependencies

You can add dependencies manually in your `Forc.toml`, or by using the `forc add` command.

### Using `forc add`

The `forc add` CLI supports various sources and optional flags:

```bash
forc add <dep> [--path <PATH>] [--git <URL> --tag <TAG>] [--ipfs <CID>] [--contract-dep]
```

#### Add Examples

* From a Git branch:

  ```bash
  forc add custom_lib --git https://github.com/FuelLabs/custom_lib --branch master
  ```

* From a local path:

  ```bash
  forc add custom_lib --path ../custom_lib
  ```

* From IPFS:

  ```bash
  forc add custom_lib --ipfs QmYwAPJzv5CZsnA...
  ```

* From registry (forc.pub):

  ```bash
  forc add custom_lib@0.0.1
  ```

* Add as a contract dependency:

  ```bash
  forc add my_contract --git https://github.com/example/contract --contract-dep
  ```

Optional:

* `--salt <HEX>` for custom contract salt.
* `--package <NAME>` to target a specific package in a workspace.
* `--manifest-path <PATH>` to specify a manifest file.

> ⚠️ **Note:**
> We do not currently support offline mode for projects that use **registry** sources.
> Also wildcard declarations `(ex: custom_lib = *)` to get the latest version available for that package or caret declarations `(ex: custom_lib = ^0.1)` to get `SemVer` compatible latest available option for a given dependency is not supported yet.

Once the package is added, running `forc build` will automatically fetch and resolve the dependencies.

### Manually Editing `Forc.toml`

If your `Forc.toml` doesn't already have a `[dependencies]` or `[contract-dependencies]` table, add one. Below, list the package name and its source.

#### Local Path

```toml
[dependencies]
custom_lib = { path = "../custom_lib" }
```

#### IPFS Source

```toml
[dependencies]
custom_lib = { ipfs = "QmYwAPJzv5CZsnA..." }
```

#### Registry Source (forc.pub)

```toml
[dependencies]
custom_lib = "0.0.1"
```

## Removing Dependencies

You can remove one or more dependencies using the `forc remove` command:

```bash
forc remove <dep> [--contract-dep] [--package <NAME>] [--manifest-path <PATH>]
```

### Remove Examples

* Remove from `[dependencies]`:

  ```bash
  forc remove custom_lib
  ```

* Remove from `[contract-dependencies]`:

  ```bash
  forc remove my_contract --contract-dep
  ```

* Target a specific package in a workspace:

  ```bash
  forc remove custom_lib --package my_project
  ```

## Updating Dependencies

To update dependencies in your Forc directory you can run:

```bash
forc update
```

For path and ipfs dependencies this will have no effect. For git dependencies with a branch reference, this will update the project to use the latest commit for the given branch.


---

### File: docs/nightly/sway/docs/book/src/forc/index.md

# Forc Reference

Forc stands for Fuel Orchestrator. Forc provides a variety of tools and commands for developers working with the Fuel ecosystem, such as scaffolding a new project, formatting, running scripts, deploying contracts, testing contracts, and more. If you're coming from a Rust background, forc is similar to cargo.

If you are new to Forc, see the [Forc Project](https://docs.fuel.network/docs/sway/introduction/forc_project/) introduction section.

For a comprehensive overview of the Forc CLI commands, see the [Commands](./commands/index.md) section.


---

### File: docs/nightly/sway/docs/book/src/forc/manifest_reference.md

# Manifest Reference

The `Forc.toml` (the _manifest_ file) is a compulsory file for each package and it is written in [TOML] format. `Forc.toml` consists of the following fields:

* [`[project]`](#the-project-section) — Defines a sway project.
  * `name` — The name of the project.
  * `version` — The version of the project.
  * `description` — A description of the project.
  * `authors` — The authors of the project.
  * `organization` — The organization of the project.
  * `license` — The project license.
  * `homepage` — URL of the project homepage.
  * `repository` — URL of the project source repository.
  * `documentation` — URL of the project documentation.
  * `categories` —  Categories of the project.
  * `keywords` —  Keywords the project.
  * `entry` — The entry point for the compiler to start parsing from.
    * For the recommended way of selecting an entry point of large libraries please take a look at: [Libraries](./../sway-program-types/libraries.md)
  * `implicit-std` -  Controls whether provided `std` version (with the current `forc` version) will get added as a dependency _implicitly_. _Unless you know what you are doing, leave this as default._
  * `forc-version` - The minimum forc version required for this project to work properly.
  * `metadata` - Metadata for the project; can be used by tools which would like to store package configuration in `Forc.toml`.

* [`[dependencies]`](#the-dependencies-section) — Defines the dependencies.
* `[network]` — Defines a network for forc to interact with.
  * `url` — URL of the network.

* [`[build-profile]`](#the-build-profile-section) - Defines the build profiles.

* [`[patch]`](#the-patch-section) - Defines the patches.

* [`[contract-dependencies]`](#the-contract-dependencies-section) - Defines the contract dependencies.

## The `[project]` section

An example `Forc.toml` is shown below. Under `[project]` the following fields are optional:

* `authors`
* `organization`
* `version`
* `description`
* `homepage`
* `repository`
* `documentation`
* `categories`
* `keywords`

Also for the following fields, a default value is provided so omitting them is allowed:

* `entry` - (default : `main.sw` )
* `implicit-std` - (default : `true` )

```toml
[project]
authors = ["user"]
entry = "main.sw"
description = "Wallet contract"
version = "1.0.0"
homepage = "https://example.com/"
repository = "https://example.com/"
documentation = "https://example.com/"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"
categories = ["example"]
keywords = ["example"]

[project.metadata]
indexing = { namespace = "counter-contract", schema_path = "out/release/counter-contract-abi.json" }
```

### Metadata Section in `Forc.toml`

The `[project.metadata]` section provides a dedicated space for external tools and plugins to store their configuration in `Forc.toml`. The metadata key names are arbitrary and do not need to match the tool's name.

#### Workspace vs Project Metadata

Metadata can be defined at two levels:

Workspace level - defined in the workspace\'s root `Forc.toml`:

```toml
[workspace.metadata]
my_tool = { shared_setting = "value" }
```

Project level - defined in individual project\'s `Forc.toml`:

```toml
[project.metadata.any_name_here]
option1 = "value"
option2 = "value"

[project.metadata.my_custom_config]
setting1 = "value"
setting2 = "value"
```

Example for an indexing tool:

```toml
[project.metadata.indexing]
namespace = "counter-contract"
schema_path = "out/release/counter-contract-abi.json"
```

When both workspace and project metadata exist:

* Project-level metadata should take precedence over workspace metadata
* Tools can choose to merge workspace and project settings
* Consider documenting your tool's metadata inheritance behavior

#### Guidelines for Plugin Developers

Best Practices

* Choose clear, descriptive metadata key names
* Document the exact metadata key name your tool expects
* Don't require `Forc.toml` if tool can function without it
* Consider using TOML format for dedicated config files
* Specify how your tool handles workspace vs project metadata

Implementation Notes

* The metadata section is optional
* Forc does not parse metadata contents
* Plugin developers handle their own configuration parsing
* Choose unique metadata keys to avoid conflicts with other tools

#### Example Use Cases

* Documentation generation settings
* Formatter configurations
* Debugger options
* Wallet integration
* Contract indexing
* Testing frameworks

This allows for a streamlined developer experience while maintaining clear separation between core Forc functionality and third-party tools.

#### External Tooling Examples

* [forc-index-ts](https://github.com/FuelLabs/example-forc-plugins/tree/master/forc-index-ts): A TypeScript CLI tool for parsing `Forc.toml` metadata to read contract ABI JSON file.
* [forc-index-rs](https://github.com/FuelLabs/example-forc-plugins/tree/master/forc-index-rs): A Rust CLI tool for parsing `Forc.toml` metadata to read contract ABI JSON file.

## The `[dependencies]` section

The following fields can be provided with a dependency:

* `version` - Desired version of the dependency
* `namespace` - If the specified registry source (by its version) also has a namespace associated with it (optional)
* `path` - The path of the dependency (if it is local)
* `git` - The URL of the git repo hosting the dependency
* `branch` - The desired branch to fetch from the git repo
* `tag` - The desired tag to fetch from the git repo
* `rev` - The desired rev (i.e. commit hash) reference

Please see [dependencies](./dependencies.md) for details

## The `[network]` section

For the following fields, a default value is provided so omitting them is allowed:

* `URL` - (default: _<http://127.0.0.1:4000>_)

## The `[build-profile.*]` section

The `[build-profile]` tables provide a way to customize compiler settings such as debug options.

The following fields can be provided for a build-profile:

* `print-ast` - Whether to print out the generated AST or not, defaults to false.
* `print-dca-graph` - Whether to print out the computed Dead Code Analysis (DCA) graph (in GraphViz DOT format), defaults to false.
* `print-dca-graph-url-format` - The URL format to be used in the generated DOT file, an example for VS Code would be: `vscode://file/{path}:{line}:{col}`.
* `print-ir` - Whether to print out the generated Sway IR (Intermediate Representation) or not, defaults to false.
* `print-asm` - Whether to print out the generated ASM (assembler), defaults to false.
* `terse` - Terse mode. Limited warning and error output, defaults to false.
* `time_phases` - Whether to output the time elapsed over each part of the compilation process, defaults to false.
* `include_tests` -  Whether or not to include test functions in parsing, type-checking, and code generation. This is set to true by invocations like `forc test`, but defaults to false.
* `error_on_warnings` - Whether to treat errors as warnings, defaults to false.

There are two default `[build-profile]` available with every manifest file. These are `debug` and `release` profiles. If you want to override these profiles, you can provide them explicitly in the manifest file like the following example:

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[build-profile.debug]
print-asm = { virtual = false, allocated = false, final = true }
print-ir = { initial = false, final = true, modified = false, passes = []}
terse = false

[build-profile.release]
print-asm = { virtual = true, allocated = false, final = true }
print-ir = { initial = true, final = false, modified = true, passes = ["dce", "sroa"]}
terse = true
```

Since `release` and `debug` are implicitly included in every manifest file, you can use them by just passing `--release` or by not passing anything (`debug` is default). For using a user defined build profile there is `--build-profile <profile name>` option available to the relevant commands. (For an example see [forc-build](../forc/commands/forc_build.md))

Note that providing the corresponding CLI options (like `--asm`) will override the selected build profile. For example if you pass both `--release` and `--asm all`, `release` build profile is overridden and resulting build profile would have a structure like the following:

```toml
print-ast = false
print-ir = { initial = false, final = false, modified = false, passes = []}
print-asm = { virtual = true, allocated = true, final = true }
terse = false
time-phases = false
include-tests = false
error-on-warnings = false
experimental-private-modules = false
```

## The `[patch]` section

The [patch] section of `Forc.toml` can be used to override dependencies with other copies. The example provided below patches `https://github.com/fuellabs/sway` with the `test` branch of the same repo.

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[dependencies]

[patch.'https://github.com/fuellabs/sway']
std = { git = "https://github.com/fuellabs/sway", branch = "test" }
```

In the example above, `std` is patched with the `test` branch from `std` repo. You can also patch git dependencies with dependencies defined with a path.

```toml
[patch.'https://github.com/fuellabs/sway']
std = { path = "/path/to/local_std_version" }
```

Just like `std` you can also patch dependencies you declared with a git repo.

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[dependencies]
foo = { git = "https://github.com/foo/foo", branch = "master" }

[patch.'https://github.com/foo']
foo = { git = "https://github.com/foo/foo", branch = "test" }
```

Note that each key after the `[patch]` is a URL of the source that is being patched.

## The `[contract-dependencies]` section

The `[contract-dependencies]` table can be used to declare contract dependencies for a Sway contract or script. Contract dependencies are the set of contracts that our contract or script may interact with. Declaring `[contract-dependencies]` makes it easier to refer to contracts in your Sway source code without having to manually update IDs each time a new version is deployed. Instead, we can use forc to pin and update contract dependencies just like we do for regular library dependencies.

Contracts declared under `[contract-dependencies]` are built and pinned just like regular `[dependencies]` however rather than importing each contract dependency's entire public namespace we instead import their respective contract IDs as `CONTRACT_ID` constants available via each contract dependency's namespace root. This means you can use a contract dependency's ID as if it were declared as a `pub const` in the root of the contract dependency package as demonstrated in the example below.

Entries under `[contract-dependencies]` can be declared in the same way that `[dependencies]` can be declared. That is, they can refer to the `path` or `git` source of another contract. Note that entries under `[contract-dependencies]` must refer to contracts and will otherwise produce an error.

Example `Forc.toml`:

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[contract-dependencies]
foo = { path = "../foo" }
```

Example usage:

```sway
script;

fn main() {
  let foo_id = foo::CONTRACT_ID;
}
```

Because the ID of a contract is computed deterministically, rebuilding the same contract would always result in the same contract ID. Since two contracts with the same contract ID cannot be deployed on the blockchain, a "salt" factor is needed to modify the contract ID. For each contract dependency declared under `[contract-dependencies]`, `salt` can be specified. An example is shown below:

```toml
[contract-dependencies]
foo = { path = "../foo", salt = "0x1000000000000000000000000000000000000000000000000000000000000000" }
```

For contract dependencies that do not specify any value for `salt`, a default of all zeros for `salt` is implicitly applied.


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_client/forc_call.md

# forc call


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_client/forc_deploy.md

# forc deploy


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_client/forc_run.md

# forc run


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_client/forc_submit.md

# forc submit


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_client/index.md

# forc-client

The forc plugin for interacting with a Fuel node.

Since transactions are going to require some gas, you need to sign them with an account that has enough coins to pay for them.

We offer multiple ways to sign the transaction:

  1. Sign the transaction via your local wallet using `forc-client` which integrates with our CLI wallet, `forc-wallet`.
  2. Use the default signer to deploy to a local node
  3. Use `forc-wallet` to manually sign transactions, and copy the signed transaction back to `forc-client`.

The easiest and recommended way to interact with deployed networks such as our testnets is option 1, using `forc-client` to sign your transactions which reads your default `forc-wallet` vault. For interacting with local node, we recommend using the second option, which leads `forc-client` to sign transactions with the private key that comes pre-funded in local environments.

## Option 1: Sign transactions via forc-client using your local forc-wallet vault

If you've used `forc-wallet` before, you'll already have a secure, password-protected vault holding your private key written to your file-system. `forc-client` is compatible with `forc-wallet` such that it can read that vault by asking you your password and use your account to sign transactions.

Example:

```console
> forc deploy

    Building /Users/yourname/test-projects/test-contract
    Finished release [optimized + fuel] target(s) in 11.39s
  Confirming transactions [deploy impl-contract]
             Network: https://testnet.fuel.network
             Wallet: /Users/yourname/.fuel/wallets/.wallet
✔ Wallet password · ********
? Wallet account ›
❯ [0] fuel12pls73y9hnqdqthvduy2x44x48zt8s50pkerf32kq26f2afeqdwq6rj9ar - 0.002197245 ETH
  [1] fuel1vzrm6kw9s3tv85gl25lpptsxrdguyzfhq6c8rk07tr6ft5g45nwqqh0uty - 0.001963631 ETH
? Do you agree to sign 1 transaction? (y/n) › yes
     Finished deploying impl-contract https://app.fuel.network/contract/0x94b712901f04332682d14c998a5fc5a078ed15321438f46d58d0383200cde43d
     Deployed in block https://app.fuel.network/block/5958351
```

As it can be seen from the example, `forc-client` asks for your password to decrypt the `forc-wallet` vault, and list your accounts so that you can select the one you want to fund the transaction with.

## Option 2: Using default signer

If you are not interacting with a deployed network, such as testnets, your local `fuel-core` environment can be structured such that it funds an account by default. Using `--default-signer` flag with `forc-client` binaries (run, deploy) will instruct `forc-client` to sign transactions with this pre-funded account. This makes it a useful command while working against a local node.

Example:

```console
> forc deploy --default-signer

    Building /Users/test/test-projects/test-contract
    Finished release [optimized + fuel] target(s) in 11.40s
  Confirming transactions [deploy impl-contract]
             Network: http://127.0.0.1:4000
    Finished deploying impl-contract 0xf9fb08ef18ce226954270d6d4f67677d484b8782a5892b3d436572b405407544
    Deployed in block 00000001
```

## Option 3: Manually signing through forc-wallet (Deprecated)

This option is for creating the transaction first, signing it manually, and supplying the signed transaction back to forc-client. Since it requires multiple steps, it is more error-prone and not recommended for general use cases. Also this will be deprecated soon.

1. Construct the transaction by using either `forc deploy` or `forc run`. To do so simply run `forc deploy --manual-sign` or `forc run --manual-sign` with your desired parameters. For a list of parameters please refer to the [forc-deploy](./forc_deploy.md) or [forc-run](./forc_run.md) section of the book. Once you run either command you will be asked the address of the wallet you are going to be signing with. After the address is given the transaction will be generated and you will be given a transaction ID. At this point CLI will actively wait for you to insert the signature.
2. Take the transaction ID generated in the first step and sign it with `forc wallet sign --account <account_index> tx-id <transaction_id>`. This will generate a signature.
3. Take the signature generated in the second step and provide it to `forc-deploy` (or `forc-run`). Once the signature is provided, the signed transaction will be submitted.

## Other useful commands of `forc-wallet`

- You can see a list of existing accounts with `accounts` command.

```sh
forc wallet accounts
```

- If you want to retrieve the address for an account by its index you can use `account` command.

```sh
forc wallet account <account_index>
```

> If you want to sign the transaction generated by `forc-deploy` or `forc-run` with an account funded by default once you start your local node, you can pass `--default-signer` to them. Please note that this will only work against your local node.
>
> ```sh
> forc-deploy --default-signer
> ```
>
> ```sh
> forc-run --default-signer
> ```

By default `--default-signer` flag would sign your transactions with the following private-key:

```sh
0xde97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c
```

## Selecting a target network

By default, `local` is used for the target network. To interact with the latest testnet, use the `--testnet` flag. When this flag is passed, transactions created by `forc-deploy` will be sent to the latest `testnet`:

```sh
forc-deploy --testnet
```

The same can be done to target mainnet:

```sh
forc-deploy --mainnet
```

It is also possible to pass the exact node URL while using `forc-deploy` or `forc-run` which can be done using `--node-url` flag:

```sh
forc-deploy --node-url https://mainnet.fuel.network
```

Another alternative is the `--target` option, which provides useful aliases to all targets. For example if you want to deploy to `testnet` you can use:

```sh
forc-deploy --target testnet
```

Since deploying and running projects on the testnet cost gas, you will need coins to pay for them. You can get some using the [testnet faucet](https://faucet-testnet.fuel.network/).

## Delayed transactions

For delayed transactions, you can use the `--submit-only` flag. This flag allows you to submit the transaction without waiting for its finalization.

One use case for this is multisig transactions, where a deployment transaction may stay in a pending state while waiting for all signatures.

```sh
forc-deploy --submit-only
```

## Deployment Artifacts

forc-deploy saves the details of each deployment in the `out/deployments` folder within the project's root directory. Below is an example of a deployment artifact:

```json
{
  "transaction_id": "0xec27bb7a4c8a3b8af98070666cf4e6ea22ca4b9950a0862334a1830520012f5d",
  "salt": "0x9e35d1d5ef5724f29e649a3465033f5397d3ebb973c40a1d76bb35c253f0dec7",
  "network_endpoint": "http://127.0.0.1:4000",
  "chain_id": 0,
  "contract_id": "0x767eeaa7af2621e637f9785552620e175d4422b17d4cf0d76335c38808608a7b",
  "deployment_size": 68,
  "deployed_block_id": "0x915c6f372252be6bc54bd70df6362dae9bf750ba652bf5582d9b31c7023ca6cf"
}
```

## Proxy Contracts

`forc-deploy` supports deploying proxy contracts automatically if it is enabled in the `Forc.toml` of the contract. This feature enables upgradeable contracts by deploying a proxy that forwards calls to an implementation contract, allowing you to upgrade the implementation without changing the proxy address.

### Configuration

To enable proxy deployment, add a `[proxy]` table to your `Forc.toml`:

```TOML
[project]
name = "test_contract"
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
implicit-std = false

[proxy]
enabled = true
```

The proxy configuration supports two fields:

- `enabled` (boolean, required): Whether to deploy a proxy contract
- `address` (string, optional): Address of an existing proxy contract to update

### Fresh Proxy Deployment

If there is no `address` field present under the proxy table, like the example above, `forc` will automatically create a proxy contract based on the [SRC-14](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-14-simple-upgradeable-proxies.md) implementation from [sway-standards](https://github.com/FuelLabs/sway-standards). The deployment process:

1. **Deploy Implementation Contract**: Your contract is deployed as the implementation
2. **Generate Proxy Contract**: A standard SRC-14 proxy contract is generated
3. **Deploy Proxy Contract**: The proxy is deployed with your implementation as the target
4. **Initialize Proxy**: The proxy is initialized with the deploying account as the owner
5. **Update Manifest**: The proxy address is automatically added to your `Forc.toml`

After deployment, you'll see output similar to:

```console
Deploying contract test_contract chunks
Finished deploying test_contract 0x440b...925
Finished deploying proxy contract for test_contract 0x19d4...f7
Initialized proxy contract for test_contract
```

The `Forc.toml` will be automatically updated with the proxy address:

```TOML
[proxy]
enabled = true
address = "0x19d465200575ebd085300242002efcda38db99e22449a5c1346588efe9ced7f7"
```

### Updating Existing Proxy

If you want to update the target of an existing [SRC-14](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-14-simple-upgradeable-proxies.md) compliant proxy contract, specify its address in the `address` field:

```TOML
[project]
name = "test_contract"
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
implicit-std = false

[proxy]
enabled = true
address = "0xd8c4b07a0d1be57b228f4c18ba7bca0c8655eb6e9d695f14080f2cf4fc7cd946" # example proxy contract address
```

When an `address` is present, `forc` will:

1. Deploy the new implementation contract
2. Call the existing proxy's `set_proxy_target` method to update the target
3. The proxy address remains the same, providing seamless upgrades

### Transaction Details

When deploying with proxy enabled, you'll see multiple transactions in the confirmation:

- One transaction to deploy the implementation contract
- One additional transaction to deploy the proxy (for fresh deployments) or update the target (for existing proxies)

Example output:

```console
Confirming transactions [deploy test_contract + deploy proxy]
Network: https://testnet.fuel.network
```

### Storage Slots

The proxy contract includes both its own storage slots and preserves the storage slots from your implementation contract, ensuring that contract state is properly maintained across upgrades.

### Important Notes

- The proxy owner (initially set to the deploying account) has exclusive rights to update the proxy target
- Once a proxy is deployed, the address in your `Forc.toml` allows for automatic target updates on subsequent deployments
- Proxy contracts work with both regular and [chunked contracts](#large-contracts) (contracts over 100<!-- markdownlint-disable-line MD032 -->kB)
- The implementation uses the SRC-14 standard for maximum compatibility with the Fuel ecosystem

## Large Contracts

For contracts over the maximum contract size limit (currently `100<!-- markdownlint-disable-line -->kB`) defined by the network, `forc-deploy` will split the contract into chunks and deploy the contract with multiple transactions using the Rust SDK's [loader contract](https://github.com/FuelLabs/fuels-rs/blob/master/docs/src/deploying/large_contracts.md) functionality. Chunks that have already been deployed will be reused on subsequent deployments.

## Deploying Scripts and Predicates

`forc deploy` now supports deploying scripts and predicates in addition to contracts. These are deployed as blobs with generated loaders for efficiency.

Scripts and predicates are deployed automatically when you run `forc deploy` on a project that contains them. The deployment process differs slightly from contract deployment:

1. For scripts and predicates, the bytecode is uploaded as a blob.
2. A loader is generated that can load and execute the blob.
3. The loader bytecode is saved in the project's output directory.

After deployment, you'll find new files in your project's output directory:

- For scripts: `<script_name>-loader.bin`
- For predicates: `<predicate_name>-loader.bin` and `<predicate_name>-loader-root`

The loader files contain the bytecode necessary to load and execute your script or predicate from the deployed blob.

This new deployment method allows for more efficient storage and execution of scripts and predicates on the Fuel network.

Note: Contracts are still deployed directly, not as blobs given that the contract size is under the maximum contract size limit defined by network (currently `100<!-- markdownlint-disable-line -->kB`).


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_crypto.md

# forc crypto


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_debug.md

# forc debug


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_doc.md

# forc doc


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_fmt.md

# forc fmt


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_lsp.md

# forc lsp


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_mcp/forc_call_tool/common_commands.md

# Common MCP Tool Usage

## Basic Function Calls

### Call a simple function

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"get_balance\",\"outputs\":[{\"type\":\"u64\"}]}]}",
    "function": "get_balance"
  }
}
```

### Call with parameters

```json
{
  "tool": "call_contract", 
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://api.example.com/contracts/0x1234.../abi.json",
    "function": "transfer",
    "function_args": ["\"0x5678...\"", "1000"]
  }
}
```

### Call with complex types

```json
// Tuple parameter (inline ABI)
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"process_order\",\"inputs\":[{\"name\":\"order\",\"type\":\"(u64, bool, str)\"}]}]}", 
    "function": "process_order",
    "function_args": ["\"(42, true, \\\"urgent\\\")\""]
  }
}

// Struct parameter (URL ABI)
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://contracts.fuel.network/abi/user-contract.json",
    "function": "create_user", 
    "function_args": ["\"{\\\"Alice\\\", 25, true}\""]
  }
}

// Array parameter (inline ABI)
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"sum_values\",\"inputs\":[{\"name\":\"values\",\"type\":\"[u64; 5]\"}]}]}",
    "function": "sum_values",
    "function_args": ["\"[1, 2, 3, 4, 5]\""]
  }
}

// Enum parameter (URL ABI)
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://api.example.com/contract-abi.json", 
    "function": "set_status",
    "function_args": ["\"(Active: true)\""]
  }
}
```

## Execution Modes

### Dry-run (default)

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"test_function\"}]}",
    "function": "test_function",
    "mode": "dry-run"
  }
}
```

### Simulate (estimates gas)

```json
{
  "tool": "call_contract", 
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://api.fuel.network/contracts/0x1234.../abi",
    "function": "test_function",
    "mode": "simulate"
  }
}
```

### Live (state changes)

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"test_function\"}]}", 
    "function": "test_function",
    "mode": "live",
    "signing_key": "your-private-key"
  }
}
```

## Payable Functions

### Transfer native asset

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"deposit\",\"attributes\":[\"payable\"]}]}",
    "function": "deposit",
    "amount": 1000,
    "mode": "live"
  }
}
```

### Transfer custom asset

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://contracts.fuel.network/abi/token-vault.json", 
    "function": "deposit_token",
    "amount": 500,
    "asset_id": "0x5678...",
    "mode": "live"
  }
}
```

## Direct Transfers

### Transfer to address/contract

```json
{
  "tool": "transfer_assets",
  "parameters": {
    "recipient": "0x1234...",
    "amount": 1000,
    "signing_key": "your-private-key"
  }
}
```

## Network Selection

### Local node

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"test\"}]}",
    "function": "test",
    "node_url": "http://127.0.0.1:4000"
  }
}
```

### Custom node URL

```json
{
  "tool": "call_contract", 
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://raw.githubusercontent.com/FuelLabs/sway-applications/main/contracts/abi.json",
    "function": "test",
    "node_url": "https://mainnet.fuel.network"
  }
}
```

## List Functions

### Show all callable functions

```json
{
  "tool": "list_contract_functions",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://api.fuel.network/contracts/0x1234.../abi"
  }
}
```

## Using Different ABI Sources

### Remote URL

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://example.com/contract-abi.json",
    "function": "function_name"
  }
}
```

### Inline JSON (recommended for MCP)

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"get\",\"outputs\":[{\"type\":\"u64\"}]}]}",
    "function": "get"
  }
}
```

### GitHub raw URL

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://raw.githubusercontent.com/FuelLabs/sway-applications/main/AMM/project/contracts/exchange-contract/out/debug/exchange-contract-abi.json",
    "function": "function_name"
  }
}
```

## Execution Trace

### Get formatted execution trace

```json
{
  "tool": "get_execution_trace",
  "parameters": {
    "trace_events": [/* trace events from call result */],
    "total_gas": 12345,
    "labels": {
      "0x1234...": "MyContract",
      "0x5678...": "TokenContract"
    }
  }
}
```


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_mcp/forc_call_tool/contract_samples.md

# Contract Examples with MCP Tool Usage

## 1. Simple Counter Contract

### Contract Code

```sway
contract;

storage {
    count: u64 = 0,
}

abi Counter {
    #[storage(read, write)]
    fn increment();
    
    #[storage(read)]
    fn get_count() -> u64;
    
    #[storage(write)]
    fn set_count(value: u64);
}

impl Counter for Contract {
    #[storage(read, write)]
    fn increment() {
        storage.count.write(storage.count.read() + 1);
    }
    
    #[storage(read)]
    fn get_count() -> u64 {
        storage.count.read()
    }
    
    #[storage(write)]
    fn set_count(value: u64) {
        storage.count.write(value);
    }
}
```

### MCP Tool Commands

```json
// Increment the counter
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"increment\",\"attributes\":[\"storage(read, write)\"]}]}",
    "function": "increment",
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Get current count
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"get_count\",\"outputs\":[{\"type\":\"u64\"}],\"attributes\":[\"storage(read)\"]}]}", 
    "function": "get_count"
  }
}

// Set count to specific value
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://raw.githubusercontent.com/FuelLabs/sway-applications/main/counter/out/debug/counter-abi.json",
    "function": "set_count",
    "function_args": ["42"],
    "mode": "live",
    "signing_key": "your-private-key"
  }
}
```

## 2. Token Contract

### Token Contract Code

```sway
contract;

use std::auth::msg_sender;

storage {
    balances: StorageMap<Identity, u64> = StorageMap {},
    total_supply: u64 = 0,
}

abi Token {
    #[storage(read, write)]
    fn mint(recipient: Identity, amount: u64);
    
    #[storage(read, write)]
    fn transfer(to: Identity, amount: u64);
    
    #[storage(read)]
    fn balance_of(account: Identity) -> u64;
}

impl Token for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, amount: u64) {
        let current = storage.balances.get(recipient).try_read().unwrap_or(0);
        storage.balances.insert(recipient, current + amount);
        storage.total_supply.write(storage.total_supply.read() + amount);
    }
    
    #[storage(read, write)]
    fn transfer(to: Identity, amount: u64) {
        let sender = msg_sender().unwrap();
        let sender_balance = storage.balances.get(sender).read();
        require(sender_balance >= amount, "Insufficient balance");
        
        storage.balances.insert(sender, sender_balance - amount);
        let recipient_balance = storage.balances.get(to).try_read().unwrap_or(0);
        storage.balances.insert(to, recipient_balance + amount);
    }
    
    #[storage(read)]
    fn balance_of(account: Identity) -> u64 {
        storage.balances.get(account).try_read().unwrap_or(0)
    }
}
```

### Token MCP Tool Commands

```json
// Mint tokens (Identity can be Address or ContractId)
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://raw.githubusercontent.com/FuelLabs/sway-applications/main/native-asset/out/debug/native-asset-abi.json",
    "function": "mint",
    "function_args": ["\"0x5678...\"", "1000000"],
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Transfer tokens
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"transfer\",\"inputs\":[{\"name\":\"to\",\"type\":\"Identity\"},{\"name\":\"amount\",\"type\":\"u64\"}]}]}",
    "function": "transfer", 
    "function_args": ["\"0x9abc...\"", "5000"],
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Check balance
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"balance_of\",\"inputs\":[{\"name\":\"account\",\"type\":\"Identity\"}],\"outputs\":[{\"type\":\"u64\"}]}]}",
    "function": "balance_of",
    "function_args": ["\"0x5678...\""]
  }
}
```

## 3. Complex Types Contract

### Complex Types Contract Code

```sway
contract;

struct User {
    name: str[32],
    age: u64,
    active: bool,
}

enum OrderStatus {
    Pending: (),
    Processing: u64,  // timestamp
    Completed: (u64, b256),  // timestamp, tx_hash
}

abi ComplexTypes {
    fn create_user(user: User) -> User;
    fn process_order(order_id: u64, status: OrderStatus);
    fn batch_operation(users: Vec<User>, amounts: [u64; 3]);
}

impl ComplexTypes for Contract {
    fn create_user(user: User) -> User {
        user
    }
    
    fn process_order(order_id: u64, status: OrderStatus) {
        // Process based on status
    }
    
    fn batch_operation(users: Vec<User>, amounts: [u64; 3]) {
        // Batch processing logic
    }
}
```

### Complex Types MCP Tool Commands

```json
// Create user (struct as tuple)
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"types\":[{\"typeId\":0,\"type\":\"struct User\",\"components\":[{\"name\":\"name\",\"type\":\"str[32]\"},{\"name\":\"age\",\"type\":\"u64\"},{\"name\":\"active\",\"type\":\"bool\"}]}],\"functions\":[{\"name\":\"create_user\",\"inputs\":[{\"name\":\"user\",\"type\":0}],\"outputs\":[{\"type\":0}]}]}",
    "function": "create_user",
    "function_args": ["\"{\\\"Alice\\\", 25, true}\""]
  }
}

// Update order status to Processing  
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://api.example.com/contracts/order-processor/abi.json",
    "function": "process_order",
    "function_args": ["12345", "\"(Processing: 1699564800)\""],
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Update order status to Completed
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "https://api.example.com/contracts/order-processor/abi.json",
    "function": "process_order",
    "function_args": ["12345", "\"(Completed: (1699651200, 0x1234567890abcdef...))\""],
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Batch operation with vector and array
{
  "tool": "call_contract", 
  "parameters": {
    "contract_id": "0x1234...",
    "abi": "{\"functions\":[{\"name\":\"batch_operation\",\"inputs\":[{\"name\":\"users\",\"type\":\"Vec<User>\"},{\"name\":\"amounts\",\"type\":\"[u64; 3]\"}]}]}",
    "function": "batch_operation",
    "function_args": [
      "\"[{\\\"Alice\\\", 25, true}, {\\\"Bob\\\", 30, true}]\"",
      "\"[100, 200, 300]\""
    ],
    "mode": "live",
    "signing_key": "your-private-key"
  }
}
```

## 4. Multi-Contract Interaction

### Exchange Contract Code

```sway
contract;

use std::call_frames::msg_asset_id;

abi Exchange {
    fn swap(
        token_in: ContractId,
        token_out: ContractId,
        amount_in: u64,
        min_amount_out: u64,
    );
}

impl Exchange for Contract {
    fn swap(
        token_in: ContractId,
        token_out: ContractId,
        amount_in: u64,
        min_amount_out: u64,
    ) {
        // Swap logic with external token contracts
    }
}
```

### MCP Tool Commands with Tracing

```json
// Swap tokens and get detailed trace
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0xexchange...",
    "abi": "https://raw.githubusercontent.com/FuelLabs/sway-applications/main/AMM/project/contracts/exchange-contract/out/debug/exchange-contract-abi.json",
    "function": "swap",
    "function_args": [
      "\"0xtoken1...\"",
      "\"0xtoken2...\"", 
      "1000",
      "950"
    ],
    "mode": "live",
    "signing_key": "your-private-key",
    "verbosity": 2
  }
}

// Then format the execution trace from the result
{
  "tool": "get_execution_trace",
  "parameters": {
    "trace_events": [/* trace events from call result */],
    "total_gas": 50000,
    "labels": {
      "0xexchange...": "DEX",
      "0xtoken1...": "TokenA", 
      "0xtoken2...": "TokenB"
    }
  }
}
```

## 5. Payable Functions

### Vault Contract Code

```sway
contract;

use std::{
    asset::transfer,
    call_frames::{msg_asset_id, msg_amount},
    context::msg_sender,
};

abi Vault {
    #[payable]
    fn deposit();
    
    #[payable]
    fn deposit_with_data(note: str[64]);
    
    fn withdraw(amount: u64, asset_id: AssetId);
}

impl Vault for Contract {
    #[payable]
    fn deposit() {
        // Automatically receives the asset
    }
    
    #[payable]
    fn deposit_with_data(note: str[64]) {
        let depositor = msg_sender().unwrap();
        let asset = msg_asset_id();
        let amount = msg_amount();
        // Process deposit with metadata
    }
    
    fn withdraw(amount: u64, asset_id: AssetId) {
        let sender = msg_sender().unwrap();
        transfer(sender, asset_id, amount);
    }
}
```

### Vault MCP Tool Commands

```json
// Deposit native asset
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0xvault...",
    "abi": "{\"functions\":[{\"name\":\"deposit\",\"attributes\":[\"payable\"]}]}",
    "function": "deposit",
    "amount": 10000,
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Deposit with note
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0xvault...",
    "abi": "https://api.example.com/contracts/vault/abi.json",
    "function": "deposit_with_data",
    "function_args": ["\"Savings for vacation\""],
    "amount": 5000,
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Deposit custom asset
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0xvault...",
    "abi": "{\"functions\":[{\"name\":\"deposit\",\"attributes\":[\"payable\"]}]}",
    "function": "deposit",
    "amount": 1000,
    "asset_id": "0xtoken...",
    "mode": "live",
    "signing_key": "your-private-key"
  }
}

// Withdraw
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0xvault...",
    "abi": "{\"functions\":[{\"name\":\"withdraw\",\"inputs\":[{\"name\":\"amount\",\"type\":\"u64\"},{\"name\":\"asset_id\",\"type\":\"AssetId\"}]}]}",
    "function": "withdraw",
    "function_args": ["2500", "\"0xasset...\""],
    "mode": "live",
    "signing_key": "your-private-key"
  }
}
```

## Tips for MCP Tool Usage

1. **ABI Sources**: Use inline JSON ABI or remote URLs - relative file paths won't work in MCP
2. **Inline ABI (recommended)**: Provide ABI as escaped JSON string for better reliability
3. **Remote ABI URLs**: Use GitHub raw URLs or hosted API endpoints for ABI files
4. **Use quotes for strings**: Always quote string arguments in `function_args`
5. **Hex format for bytes32**: Use full 64-character hex for b256, Address, ContractId
6. **Tuple notation**: Use parentheses for tuples: `(value1, value2)`
7. **Struct as tuple**: Structs are encoded as tuples in order of fields
8. **Enum variants**: Use variant name with value: `(VariantName: value)`
9. **Arrays vs Vectors**: Both use square brackets but arrays have fixed size
10. **Gas settings**: Use `gas_price` parameter for gas control
11. **Separate arguments**: Each function argument goes as a separate string in `function_args` array
12. **Mode selection**: Use `dry-run` (default), `simulate`, or `live` modes
13. **Asset transfers**: Use `amount` and `asset_id` parameters for payable functions


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_mcp/forc_call_tool/index.md

# forc-call mcp

The forc-call module provides MCP tools for interacting with deployed Fuel contracts, enabling AI assistants to call functions, inspect ABIs, transfer assets, and analyze execution traces.

## forc-call mcp tools

### call_contract

Call functions on deployed Fuel contracts with full support for complex types and execution modes.

**Parameters:**

- `contract_id` (string) - Contract address to call
- `abi` (string) - Contract ABI (JSON string or URL)
- `function` (string) - Function name to call
- `function_args` (array) - Function arguments as encoded strings
- `mode` (string) - Execution mode: `dry-run` (default), `simulate`, or `live`
- `node_url` (string, optional) - Custom node URL
- `signing_key` (string, optional) - Private key for live transactions
- `amount` (number, optional) - Asset amount for payable functions
- `asset_id` (string, optional) - Asset ID for transfers (default: native asset)
- `gas_price` (number, optional) - Gas price setting
- `verbosity` (number, optional) - Output verbosity level (0-3)

**Example:**

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234567890abcdef...",
    "abi": "{\"functions\":[{\"name\":\"get_balance\",\"outputs\":[{\"type\":\"u64\"}]}]}",
    "function": "get_balance",
    "mode": "dry-run"
  }
}
```

### list_contract_functions

List all callable functions in a contract's ABI with example usage commands.

**Parameters:**

- `contract_id` (string) - Contract address
- `abi` (string) - Contract ABI (JSON string or URL)

**Example:**

```json
{
  "tool": "list_contract_functions", 
  "parameters": {
    "contract_id": "0x1234567890abcdef...",
    "abi": "https://api.fuel.network/contract-abi.json"
  }
}
```

### transfer_assets

Transfer assets directly to addresses or contracts (live mode only).

**Parameters:**

- `signing_key` (string) - Private key for transaction signing
- `recipient` (string) - Recipient address or contract ID
- `amount` (number) - Transfer amount
- `asset_id` (string, optional) - Asset ID (default: native asset)
- `node_url` (string, optional) - Custom node URL
- `verbosity` (number, optional) - Output verbosity level

**Example:**

```json
{
  "tool": "transfer_assets",
  "parameters": {
    "recipient": "0x5678901234abcdef...",
    "amount": 1000,
    "signing_key": "your-private-key"
  }
}
```

### get_execution_trace

Generate human-readable execution traces from contract call results.

**Parameters:**

- `trace_events` (array) - Trace events from CallResponse
- `total_gas` (number) - Total gas used
- `labels` (object, optional) - Contract address to name mappings

**Example:**

```json
{
  "tool": "get_execution_trace",
  "parameters": {
    "trace_events": [/* events from call result */],
    "total_gas": 50000,
    "labels": {
      "0x1234...": "MainContract",
      "0x5678...": "TokenContract"
    }
  }
}
```

## forc-call mcp resources

The forc-call module provides comprehensive documentation resources accessible through the MCP protocol:

- **Type Encoding Reference** (`forc-call://type-encoding-reference`)
  - Complete guide for encoding Sway types for function arguments
  - See: [type_encoding_reference.md](./type_encoding_reference.md)
  
- **Common Commands** (`forc-call://examples/common-commands`)
  - Examples of typical usage patterns and tool invocations
  - See: [common_commands.md](./common_commands.md)
  
- **Contract Samples** (`forc-call://examples/contract-samples`)
  - Real contract examples with MCP tool commands
  - See: [contract_samples.md](./contract_samples.md)

### Accessing resources

Resources can be accessed through the MCP resources API:

1. Use `list_resources` to see all available resources
2. Use `read_resource` with the URIs above to access specific documentation
3. Resources are served by the MCP server at runtime for AI assistants

## Execution Modes

The forc-call module supports three execution modes:

### dry-run (default)

- Validates the transaction without executing
- Returns expected outputs without modifying state
- No signing key required
- Useful for testing and validation

### simulate

- Executes the transaction in a simulated environment
- Shows state changes and gas usage
- No signing key required
- Provides detailed execution trace

### live

- Executes the transaction on the blockchain
- Requires a signing key
- Modifies blockchain state permanently
- Returns transaction ID and receipts

## Type Encoding

When calling contract functions, arguments must be encoded according to their Sway types. Refer to the Type Encoding Reference resource for detailed information on encoding various types including:

- Basic types (bool, integers)
- Addresses and ContractId
- Arrays and vectors
- Strings
- Structs and enums
- Complex nested types

## Error Handling

The module provides detailed error messages for common issues:

- Invalid contract addresses
- ABI parsing errors
- Type encoding mismatches
- Network connectivity issues
- Insufficient funds or gas
- Function not found in ABI

## Best Practices

1. Always use `dry-run` mode first to validate calls
2. Check function signatures with `list_contract_functions` before calling
3. Use the type encoding reference for complex arguments
4. Provide descriptive labels in execution traces for better readability
5. Handle errors gracefully and provide meaningful feedback


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_mcp/forc_call_tool/type_encoding_reference.md

# MCP Tool Type Encoding Reference

When calling contract functions through the MCP `call_contract` tool, function arguments must be encoded according to their Sway types in the `function_args` parameter.

## Type Encoding Table

| Types                                         | Example input                                                        | Notes                                                                                          |
|-----------------------------------------------|----------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| bool                                          | `true` or `false`                                                    |                                                                                                |
| u8, u16, u32, u64, u128, u256                 | `42`                                                                 |                                                                                                |
| b256                                          | `0x0000000000000000000000000000000000000000000000000000000000000042` or `0000000000000000000000000000000000000000000000000000000000000042` | `0x` prefix is optional |
| bytes, RawSlice                               | `0x42` or `42`                                                       | `0x` prefix is optional                                                                                               |
| String, StringSlice, StringArray (Fixed-size) | `"abc"`                                                              |                                                                                                |
| Tuple                                         | `(42, true)`                                                         | The types in tuple can be different                                                                                               |
| Array (Fixed-size), Vector (Dynamic)          | `[42, 128]`                                                          | The types in array or vector must be the same; i.e. you cannot have `[42, true]`              |
| Struct                                        | `{42, 128}`                                                          | Since structs are packed encoded, the attribute names are not encoded; i.e. `{42, 128}`; this could represent the following `struct Polygon { x: u64, y: u64 }` |
| Enum                                          | `(Active: true)` or `(1: true)`       | Enums are key-val pairs with keys as being variant name (case-sensitive) or variant index (starting from 0) and values as being the variant value; this could represent the following `enum MyEnum { Inactive, Active(bool) }` |

## Detailed Type Examples

### Basic Types

```json
// Boolean
"function_args": ["true"]

// Integers
"function_args": ["42", "100", "1000000"]

// Large integers (u128, u256)
"function_args": ["340282366920938463463374607431768211455"]

// b256 (both formats work)
"function_args": ["0x0000000000000000000000000000000000000000000000000000000000000042"]
"function_args": ["0000000000000000000000000000000000000000000000000000000000000042"]
```

### String Types

```json
// Variable-length strings
"function_args": ["\"hello world\""]

// Fixed-size string arrays
"function_args": ["\"abc\""]
```

### Collection Types

```json
// Fixed-size arrays
"function_args": ["[1, 2, 3, 4, 5]"]

// Dynamic vectors
"function_args": ["[42, 128, 256]"]

// Tuples (mixed types)
"function_args": ["(42, true, \"hello\")"]
```

### Complex Types

#### Structs

Structs are encoded as tuples of their fields in declaration order:

```sway
struct Point { x: u64, y: u64 }
struct User { name: str[32], age: u64, active: bool }
```

```json
// Point struct
"function_args": ["{42, 128}"]

// User struct  
"function_args": ["{\"Alice\", 25, true}"]
```

#### Enums

Enums use variant name (case-sensitive) or index with value:

```sway
enum Status { 
    Inactive,
    Active(bool),
    Pending(u64)
}
```

```json
// Using variant names
"function_args": ["(Inactive: ())"]
"function_args": ["(Active: true)"] 
"function_args": ["(Pending: 42)"]

// Using variant indices (starting from 0)
"function_args": ["(0: ())"]
"function_args": ["(1: true)"]
"function_args": ["(2: 42)"]
```

#### Option Type

```json
// None variant
"function_args": ["(None: ())"]

// Some variant  
"function_args": ["(Some: 42)"]
```

### Advanced Types

```json
// Bytes (hex-encoded)
"function_args": ["0x48656c6c6f"]

// RawSlice (0x prefix optional)
"function_args": ["0x42"]
"function_args": ["42"]

// Identity (Address or ContractId)
"function_args": ["\"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\""]

// Address (64 hex characters)
"function_args": ["\"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\""]

// ContractId (64 hex characters)
"function_args": ["\"0x5678901234abcdef5678901234abcdef5678901234abcdef5678901234abcdef\""]

// AssetId (64 hex characters)
"function_args": ["\"0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890\""]
```

## MCP Tool Usage

When using the `call_contract` MCP tool, provide these encoded values in the `function_args` array:

```json
{
  "tool": "call_contract",
  "parameters": {
    "contract_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "abi": "{\"functions\":[{\"name\":\"transfer\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"u64\"}]}]}", 
    "function": "transfer",
    "function_args": ["\"0x5678901234abcdef5678901234abcdef5678901234abcdef5678901234abcdef\"", "1000"]
  }
}
```

### Complex Example

```json
{
  "tool": "call_contract", 
  "parameters": {
    "contract_id": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
    "abi": "{\"functions\":[{\"name\":\"process_data\",\"inputs\":[{\"name\":\"user\",\"type\":\"struct User\"},{\"name\":\"status\",\"type\":\"enum Status\"},{\"name\":\"amounts\",\"type\":\"[u64; 3]\"}]}]}",
    "function": "process_data",
    "function_args": [
      "{\"Alice\", 25, true}",
      "(Active: true)", 
      "[100, 200, 300]"
    ]
  }
}
```

## Important Notes

- **Strings must be quoted**: Always use double quotes around string values: `"text"`
- **Hex values flexible**: The `0x` prefix is optional for most hex values
- **Nested structures**: Follow the same encoding rules recursively for nested types
- **Struct encoding**: Use braces `{}` or parentheses `()` for structs - fields are encoded in declaration order without names
- **Enum encoding**: Use variant name (case-sensitive) or index with value: `(VariantName: value)`
- **Separate arguments**: Each function argument goes as a separate string in the `function_args` array
- **Array vs Vector**: Both use square brackets but arrays have fixed size, vectors are dynamic
- **Tuple notation**: Use parentheses `()` for tuples, mixed types allowed

## Tips for Success

1. **Test with dry-run first**: Use `"mode": "dry-run"` (default) to test encoding before live calls
2. **Check ABI compatibility**: Ensure your encoded arguments match the function signature in the ABI  
3. **Use inline ABI**: Provide ABI as escaped JSON string for better reliability in MCP context
4. **Validate addresses**: Ensure all addresses/IDs are exactly 64 hex characters (32 bytes)
5. **Quote all strings**: Even if they look like numbers, string types need quotes
6. **Mind the nesting**: Complex nested structures require careful attention to bracket/brace matching


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_mcp/index.md

# forc mcp

`forc-mcp` is a modular Model Context Protocol (MCP) server that provides AI assistants and tools with programmatic access to the Sway/Fuel ecosystem.  
It exposes functionality from various Forc tools through a standardized MCP interface, enabling seamless integration with AI agents like Claude.

## Overview

The Model Context Protocol (MCP) is a standard for connecting AI assistants to external tools and data sources. `forc-mcp` implements this protocol using a modular architecture that can expose multiple Forc tools and utilities.

### Modular Architecture

`forc-mcp` is designed with extensibility in mind. The server uses a plugin-based architecture where each Forc tool can be wrapped as an MCP module. This allows for:

- **Easy integration** of new Forc tools as MCP modules
- **Isolated functionality** - each module handles its specific domain
- **Consistent interface** - all modules follow the same MCP protocol
- **Selective loading** - choose which modules to enable

## Installation

Build and install `forc-mcp` from the Sway repository:

```bash
# Install from source
cargo install --path ./forc-plugins/forc-mcp

# Or install all forc tools
cargo install --path ./forc
```

## Server Modes

`forc-mcp` supports three transport modes for different integration scenarios:

### STDIO Mode

Standard input/output communication for direct process integration:

```bash
forc-mcp stdio
```

Most efficient for single-session interactions and direct integration with applications.

### Server-Sent Events (SSE) Mode

HTTP server with real-time event streaming:

```bash
forc-mcp sse --port 3001
```

Endpoints:

- `/sse` - Event stream endpoint
- `/message` - Message sending endpoint

Suitable for web-based integrations requiring real-time updates.

### HTTP Streamable Mode

Full HTTP-based MCP protocol implementation:

```bash
forc-mcp http --port 3001
```

Endpoints:

- `/mcp` - Main MCP protocol endpoint

Most suitable for distributed systems and web applications.

## IDE and CLI Integration

### Claude Code CLI

To integrate `forc-mcp` with Claude Code CLI, add the MCP server using one of these transport methods:

```bash
# STDIO transport (requires building forc-mcp first)
claude mcp add --transport stdio forc-mcp-stdio ./target/debug/forc-mcp stdio

# HTTP transport
claude mcp add --transport http forc-mcp-http http://localhost:3001/mcp

# HTTP transport with API key authentication
claude mcp add --transport http forc-mcp-http http://localhost:3001/mcp -H "X-Api-Key: mcp_XXXXXX..."

# Server-Sent Events transport
claude mcp add --transport sse forc-mcp-sse http://localhost:3001/sse
```

### Cursor IDE

For Cursor IDE integration, add the following configuration to your MCP settings file:

#### STDIO Transport

```json
{
  "mcpServers": {
    "forc-mcp": {
      "command": "./target/debug/forc-mcp",
      "args": ["stdio"],
      "transport": "stdio"
    }
  }
}
```

#### HTTP Transport (streamable HTTP)

```json
{
  "mcpServers": {
    "forc-mcp-http": {
      "url": "http://localhost:3001/mcp",
      "transport": "http"
    }
  }
}
```

#### HTTP Transport with API key authentication

```json
{
  "mcpServers": {
    "forc-mcp-http": {
      "url": "http://localhost:3001/mcp",
      "transport": "http",
      "headers": {
        "X-Api-Key": "mcp_XXXXXX..."
      }
    }
  }
}
```

#### SSE Transport

```json
{
  "mcpServers": {
    "forc-mcp-sse": {
      "url": "http://localhost:3001/sse",
      "transport": "sse"
    }
  }
}
```

## Extensibility

`forc-mcp` is designed to accommodate additional Forc tools as MCP modules. Future modules could include:

### Potential Future Modules

- **forc-deploy Module** - Contract deployment tools
- **forc-test Module** - Test execution and reporting
- **forc-doc Module** - Documentation generation and access
- **forc-fmt Module** - Code formatting tools
- **forc-lsp Module** - Language server integration for development workflows
- **forc-node Module** - Local node management

### Adding New Modules

The modular architecture allows developers to add new modules by:

1. **Implementing the `McpToolModule` trait** for the new tool
2. **Registering the module** with the main server using `register_module()`
3. **Defining tool schemas** and resource endpoints
4. **Adding documentation resources** specific to the module

Each module operates independently and can expose its own set of tools, resources, and documentation.

For more detailed examples and advanced usage, see the built-in documentation resources accessible through the MCP tools.


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_migrate.md

# forc migrate


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_node.md

# forc node


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/forc_publish.md

# forc publish


---

### File: docs/nightly/sway/docs/book/src/forc/plugins/index.md

# Plugins

Plugins can be used to extend `forc` with new commands that go beyond the native commands mentioned in the previous chapter. While the Fuel ecosystem provides a few commonly useful plugins (`forc-fmt`, `forc-client`, `forc-lsp`, `forc-migrate`), anyone can write their own!

Let's install a plugin, `forc-install`, and see what's underneath the plugin:

```sh
git clone https://github.com/darthbenro008/forc-install
cd forc-install
cargo install --path .
```

Check that we have installed `forc-install`:

```console
$ forc plugins
Installed Plugins:
forc-install
```

`forc-install` is a tool to manage GitHub dependencies in your Forc.toml file: For example, to install a sway library hosted on github:

```console
forc install https://github.com/user/sway-library
```

Note that some plugin crates can also provide more than one command. For example, installing the `forc-client` plugin provides the `forc deploy` and `forc run` commands. This is achieved by specifying multiple `[[bin]]` targets within the `forc-client` manifest.

## Writing your own plugin

We encourage anyone to write and publish their own `forc` plugin to enhance their development experience.

Your plugin must be named in the format `forc-<MY_PLUGIN>` and you may use the above template as a starting point. You can use [clap](https://docs.rs/clap/latest/clap/) and add more subcommands, options and configurations to suit your plugin's needs.


---

### File: docs/nightly/sway/docs/book/src/forc/workspaces.md

# Workspaces

A *workspace* is a collection of one or more packages, namely *workspace members*, that are managed together.

The key points for workspaces are:

* Common `forc` commands available for a single package can also be used for a workspace, like `forc build` or `forc deploy`.
* All packages share a common `Forc.lock` file which resides in the root directory of the workspace.

Workspace manifests are declared within `Forc.toml` files and support the following fields:

* [`members`](#the-members-field) - Packages to include in the workspace.
* [`[patch]`](#the-patch-section) - Defines the patches.

An empty workspace can be created with `forc new --workspace` or `forc init --workspace`.

## The `members` field

The `members` field defines which packages are members of the workspace:

```toml
[workspace]
members = ["member1", "path/to/member2"]
```

The `members` field accepts entries to be given in relative path with respect to the workspace root.
Packages that are located within a workspace directory but are *not* contained within the `members` set are ignored.

## The `[patch]` section

The `[patch]` section can be used to override any dependency in the workspace dependency graph. The usage is the same with package level `[patch]` section and details can be seen [here](./manifest_reference.md#the-patch-section).

It is not allowed to declare patch table in member of a workspace if the workspace manifest file contains a patch table.

Example:

```toml
[workspace]
members = ["member1", "path/to/member2"]


[patch.'https://github.com/fuellabs/sway']
std = { git = "https://github.com/fuellabs/sway", branch = "test" }
```

In the above example each occurrence of `std` as a dependency in the workspace will be changed with `std` from `test` branch of sway repo.

## Some `forc` commands that support workspaces

* `forc build` - Builds an entire workspace.
* `forc deploy` - Builds and deploys all deployable members (i.e, contracts) of the workspace in the correct order.
* `forc run` - Builds and runs all scripts of the workspace.
* `forc check` - Checks all members of the workspace.
* `forc update` - Checks and updates workspace level `Forc.lock` file that is shared between workspace members.
* `forc clean` - Cleans all output artifacts for each member of the workspace.
* `forc fmt` - Formats all members of a workspace.


---

### File: docs/nightly/sway/docs/book/src/index.md

# The Sway Programming Language

Welcome to the Sway programming language book 🌴.

**Q: Hi! What is Sway?**

Sway is a domain-specific programming language for implementing smart contracts on blockchain platforms, most notably for the [Fuel Virtual Machine (Fuel VM)](https://docs.fuel.network/docs/specs/fuel-vm/).

Heavily inspired by [Rust](https://doc.rust-lang.org/book/)'s approach to systems programming, Sway aims to bring modern programming language features and tooling to smart contract development whilst retaining performance, fine grained control and making extensive use of static analysis to prevent common security issues.

**Q: What does "domain-specific" mean?**

Sway is specifically made to be used within a blockchain environment, which behaves very differently than traditional computers.
This domain specific design permits it to make the right decisions about trade-offs at every level of the stack, enabling you to write fast, secure and cost effective smart contracts with features suited to your specific needs.

**Q: Why not use Solidity?**

Solidity is a venerable pioneer but it suffers from being tied to a lot of the historical quirks of the EVM.
It lacks common features programmers have come to expect, has a relatively inexpressive type system, and it lacks a unified tooling ecosystem.

In Sway, we let you design smart contracts with a full modern box of tools.
You get a fully featured language with generics, algebraic types and trait based polymorphism.
You also get an integrated, unified and easy to use toolchain with code completion LSP server, formatter, documentation generation and everything you need to run and deploy your contracts so that nothing comes between you and implementing what you want.

Our expressive type system allows you to catch semantic mistakes, we provide good defaults and we do extensive static analysis checks (such as enforcing the [Checks, Effects, Interactions](./blockchain-development/calling_contracts.md#cei-pattern-violation-static-analysis) pattern) so that you can make sure you write secure and correct code at compile time.

**Q: Why not use Rust?**

Whilst Rust is a great systems programming language (and Sway itself is written in Rust), it isn't suited for smart contract development.

Rust shines because it can use zero-cost abstractions and its sophisticated borrow-checker memory model to achieve impressive runtime performance for complex programs without a garbage collector.

On a blockchain, cost of execution and deployment is the scarce resource.
Memory usage is low and execution time is short.
This makes complex memory management in general much too expensive to be worthwhile and Rust's borrow checker a burden with no upside.

General purpose programming languages in general are ill suited to this environment because their design has to assume execution on a general-purpose computing environment.

Sway attempts to bring all the other advantages of Rust, including its modern type system, approach to safety and good defaults to smart contract developers by providing familiar syntax and features adapted to the specific needs of the blockchain environment.

**Q: I don't know Rust or Solidity. Can I still learn Sway?**

Yes! If you are familiar with the basics of programming, blockchain, and using a terminal you can build with Sway.

**Q: What can I build with Sway?**

You can build smart contracts and their components and libraries for them.
You can learn more about the different program types and how they fit together in the [Program Types](./sway-program-types/index.md) section.

**Q: Do I need to install anything?**

If you want to develop with Sway in your local environment, you need to install [`fuelup`](https://docs.fuel.network/guides/installation/) and your editor of choice that supports LSP, such as [VSCode](https://code.visualstudio.com/).

If you don't want to install anything just yet, you can use the [Sway Playground](https://www.sway-playground.org/) to edit, compile, and deploy Sway code.

**Q: Where can I find example Sway code?**

You can find example applications built with Sway in the [Sway Applications repository](https://github.com/FuelLabs/sway-applications) on GitHub. You can also find projects building on Fuel in the [Fuel ecosystem home](https://app.fuel.network/ecosystem).

**Q: What is the standard library?**

The [standard library](./introduction/standard_library.md), also referred to as `std`, is a library that offers core functions and helpers for developing in Sway. The standard library has its own [reference documentation](https://fuellabs.github.io/sway/master/std/) that has detailed information about each module in `std`.

**Q: What are Sway standards?**

Similar to ERC standards for Ethereum and Solidity, Sway has its own SRC standards that help enable cross compatibility across different smart contracts. For more information on using a Sway Standard, you can check out the [Sway-Standards Repository](https://github.com/FuelLabs/sway-standards).

**Q: How can I make a token?**

Sway has multiple native assets. To mint a new native asset, check out the [native assets](./blockchain-development/native_assets.md) page.

**Q: How can I make an NFT?**

You can find an example of an NFT contract in Sway in the [Sway Applications repo](https://github.com/FuelLabs/sway-applications/tree/master/NFT).

**Q: How can I test Sway code?**

Sway provides [unit testing](./testing/unit-testing.md), so you can test your Sway code with Sway. You can also use the Fuel [Rust SDK](https://docs.fuel.network/docs/fuels-rs/testing/) or [TypeScript SDK](https://docs.fuel.network/docs/fuels-ts/testing/) to test your Sway programs.

**Q: How can I deploy a contract?**

You can use the `forc deploy` command to deploy a contract. For a detailed guide on how to deploy a contract, refer to the [quickstart guide](https://docs.fuel.network/docs/intro/quickstart-contract/).

**Q: Is there a way to convert Solidity code to Sway?**

Yes! You can use the Solidity to Sway transpiler built in to the [Sway Playground](https://www.sway-playground.org/) to convert Solidity code into Sway code. Note that the transpiler is still experimental, and may not work in every case.

**Q: How can I get help with Sway?**

If you run into an issue or have a question, post it on the [Fuel forum](https://forum.fuel.network/) so someone in the Fuel community can help.

**Q: Where should I get started?**

*Ready to build?* You can find step-by-step guides for how to build an application with Sway in the [Fuel Developer Guides](https://docs.fuel.network/guides/).

*Want to read?* Get started by reading the [Introduction](./introduction/index.md) and [Basics](./basics/index.md) sections of this book.


---

### File: docs/nightly/sway/docs/book/src/introduction/forc_project.md

# A Forc Project

To initialize a new project with Forc, use `forc new`:

```sh
forc new my-fuel-project
```

Here is the project that Forc has initialized:

<!-- This section should show the tree for a new forc project -->
<!-- tree:example:start -->
```console
$ cd my-fuel-project
$ tree .
├── Forc.toml
└── src
    └── main.sw
```
<!-- tree:example:end -->

<!-- This section should explain the `Forc.toml` file -->
<!-- forc_toml:example:start -->
`Forc.toml` is the _manifest file_ (similar to `Cargo.toml` for Cargo or `package.json` for Node), and defines project metadata such as the project name and dependencies.
<!-- forc_toml:example:end -->

For additional information on dependency management, see: [here](../forc/dependencies.md).

```toml
[project]
authors = ["User"]
entry = "main.sw"
license = "Apache-2.0"
name = "my-fuel-project"

[dependencies]
```

Here are the contents of the only Sway file in the project, and the main entry point, `src/main.sw`:

```sway
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

The project is a _contract_, one of four different project types. For additional information on different project types, see [here](../sway-program-types/index.md).

We now compile our project with `forc build`, passing the flag `--asm final` to view the generated assembly:

```console
$ forc build --asm final
...
.program:
ji   i4
noop
DATA_SECTION_OFFSET[0..32]
DATA_SECTION_OFFSET[32..64]
lw   $ds $is 1
add  $$ds $$ds $is
lw   $r0 $fp i73              ; load input function selector
lw   $r1 data_0               ; load fn selector for comparison
eq   $r2 $r0 $r1              ; function selector comparison
jnzi $r2 i12                  ; jump to selected function
movi $$tmp i123               ; special code for mismatched selector
rvrt $$tmp                    ; revert if no selectors matched
ret  $one
.data:
data_0 .word 559005003

  Compiled contract "my-fuel-project".
  Bytecode size is 60 bytes.
```


---

### File: docs/nightly/sway/docs/book/src/introduction/fuel_toolchain.md

# The Fuel Toolchain

The Fuel toolchain consists of several components.

## Forc (`forc`)

The "Fuel Orchestrator" [Forc](https://github.com/FuelLabs/sway/tree/master/forc) is our equivalent of Rust's [Cargo](https://doc.rust-lang.org/cargo/). It is the primary entry point for creating, building, testing, and deploying Sway projects.

## Sway Language Server (`forc-lsp`)

The Sway Language Server `forc-lsp` is provided to expose features to IDEs. [Installation instructions](../lsp/installation.md).

## Sway Formatter (`forc-fmt`)

A canonical formatter is provided with `forc-fmt`. [Installation instructions](./getting_started.md). It can be run manually with

```sh
forc fmt
```

The [Visual Studio Code plugin](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin) will
automatically format Sway files with `forc-fmt` on save, though you might have to explicitly set the Sway plugin as the
default formatter, like this:

```json
"[sway]": {
  "editor.defaultFormatter": "FuelLabs.sway-vscode-plugin"
}
```

## Fuel Core (`fuel-core`)

An implementation of the Fuel protocol, [Fuel Core](https://github.com/FuelLabs/fuel-core), is provided together with the _Sway toolchain_ to form the _Fuel toolchain_. [The Rust SDK](https://github.com/FuelLabs/fuels-rs) will automatically start and stop an instance of the node during tests, so there is no need to manually run a node unless using Forc directly without the SDK.


---

### File: docs/nightly/sway/docs/book/src/introduction/getting_started.md

# Getting Started

## Installing the `Fuel` toolchain

Please visit the Fuel [Installation Guide](https://docs.fuel.network/guides/installation) to install the Fuel toolchain binaries and prerequisites.

## Sway Quickstart

Check out the [Developer Quickstart Guide](https://docs.fuel.network/guides/quickstart/) for a step-by-step guide on building a fullstack dapp on Fuel. The guide will walk you through writing a smart contract, setting up a wallet, and building a frontend to interact with your contract.


---

### File: docs/nightly/sway/docs/book/src/introduction/index.md

# Introduction

To get started with Forc and Sway smart contract development, install the Fuel toolchain and Fuel full node and set up your first project.

- [Getting Started](./getting_started.md)
- [The Fuel Toolchain](./fuel_toolchain.md)
- [A Forc Project](./forc_project.md)
- [Standard Library](./standard_library.md)
- [Sway Language Standards](./sway_standards.md)


---

### File: docs/nightly/sway/docs/book/src/introduction/standard_library.md

# Standard Library

<!-- This section should explain what the std-lib is -->
<!-- std_lib:example:start -->
Similar to Rust, Sway comes with its own standard library.

The Sway Standard Library is the foundation of portable Sway software, a set of minimal shared abstractions for the broader Sway ecosystem. It offers core types, like `Result<T, E>` and `Option<T>`, library-defined operations on language primitives, native asset management, blockchain contextual operations, access control, storage management, and support for types from other VMs, among many other things.
<!-- std_lib:example:end -->

The entire Sway standard library is a Forc project called `std`, and is available directly [here](https://github.com/FuelLabs/sway/tree/master/sway-lib-std). Navigate to the appropriate tagged release if the latest `master` is not compatible. You can find the latest `std` documentation [here](https://fuellabs.github.io/sway/master/std/).

## Using the Standard Library

The standard library is made implicitly available to all Forc projects created using [`forc new`](../forc/commands/forc_new.md). In other words, it is not required to manually specify `std` as an explicit dependency. Forc will automatically use the version of `std` that matches its version.

Importing items from the standard library can be done using the `use` keyword, just as importing items from any Sway project. For example:

```sway
use std::storage::storage_vec::*;
```

This imports the `StorageVec` type into the current namespace.

## Standard Library Prelude

<!-- This section should explain what the std-lib prelude is -->
<!-- prelude:example:start -->
Sway comes with a variety of things in its standard library. However, if you had to manually import every single thing that you used, it would be very verbose. But importing a lot of things that a program never uses isn't good either. A balance needs to be struck.

The prelude is the list of things that Sway automatically imports into every Sway program. It's kept as small as possible, and is focused on things which are used in almost every single Sway program.

The current version of the prelude lives in [`std::prelude`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/prelude.sw), and re-exports the following:

- [`std::address::Address`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/address.sw), a wrapper around the `b256` type representing a wallet address.
- [`std::contract_id::ContractId`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/contract_id.sw), a wrapper around the `b256` type representing the ID of a contract.
- [`std::identity::Identity`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/identity.sw), an enum with two possible variants: `Address: Address` and `ContractId: ContractId`.
- [`std::vec::Vec`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/vec.sw), a growable, heap-allocated vector.
- [`std::storage::storage_key::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/storage/storage_key.sw), contains the API for accessing a `std::storage::StorageKey` which describes a location in storage.
- [`std::storage::storage_map::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/storage/storage_map.sw), a key-value mapping in contract storage.
- [`std::option::Option`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/option.sw), an enum which expresses the presence or absence of a value.
- [`std::result::Result`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/result.sw), an enum for functions that may succeed or fail.
- [`std::assert::assert`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/assert.sw), a function that reverts the VM if the condition provided to it is `false`.
- [`std::assert::assert_eq`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/assert.sw), a function that reverts the VM and logs its two inputs `v1` and `v2` if the condition `v1` == `v2` is `false`.
- [`std::assert::assert_ne`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/assert.sw), a function that reverts the VM and logs its two inputs `v1` and `v2` if the condition `v1` != `v2` is `false`.
- [`std::revert::require`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/revert.sw), a function that reverts the VM and logs a given value if the condition provided to it is `false`.
- [`std::revert::revert`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/revert.sw), a function that reverts the VM.
- [`std::logging::log`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/logging.sw), a function that logs arbitrary stack types.
- [`std::auth::msg_sender`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/auth.sw), a function that gets the `Identity` from which a call was made.
- [`std::primitives::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/primitives.sw), methods on primitive types.
- [`std::primitive_conversions::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/primitive_conversions.sw), methods for converting between primitive types.
- [`std::raw_ptr::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/raw_ptr.sw), functions for working with raw pointers.
- [`std::raw_slice::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/raw_slice.sw), functions for working with raw slices.
- [`std::ops::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/ops.sw), mathematical operations such as addition, subtraction, multiplication, and division.
- [`std::str::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/str.sw), methods for working with strings.
- [`std::codec::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/codec.sw), automatic serialization and deserialization of types.
<!-- prelude:example:end -->


---

### File: docs/nightly/sway/docs/book/src/introduction/sway_standards.md

# Sway Standards

Just like many other smart contract languages, usage standards have been developed to enable cross compatibility between smart contracts.

For more information on using a Sway Standard, please refer to the [Sway-Standards Repository](https://github.com/FuelLabs/sway-standards).

## Standards

### Native Asset Standards

- [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md) defines the implementation of a standard API for [Native Assets](../blockchain-development/native_assets.md) using the Sway Language.
- [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md) is used to enable mint and burn functionality for Native Assets.
- [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) is used to store metadata for [Native Assets](../blockchain-development/native_assets.md), usually as NFTs.
- [SRC-9; Metadata Keys Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-9-metadata-keys.md) is used to store standardized metadata keys for [Native Assets](../blockchain-development/native_assets.md) in combination with the SRC-7 standard.
- [SRC-6; Vault Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-6-vault.md) defines the implementation of a standard API for asset vaults developed in Sway.

### Predicate Standards

- [SRC-13; Soulbound Address Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-13-soulbound-address.md) defines a specific `Address` as a Soulbound Address for Soulbound Assets to become non-transferable.

### Access Control Standards

- [SRC-5; Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) is used to restrict function calls to admin users in contracts.

### Contract Standards

- [SRC-12; Contract Factory](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-12-contract-factory.md) defines the implementation of a standard API for contract factories.

### Bridge Standards

- [SRC-8; Bridged Asset](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-8-bridged-asset.md) defines the metadata required for an asset bridged to the Fuel Network.
- [SRC-10; Native Bridge Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-10-native-bridge.md) defines the standard API for the Native Bridge between the Fuel Chain and the canonical base chain.

### Documentation Standards

- [SRC-2; Inline Documentation](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-2-inline-documentation.md) defines how to document your Sway files.

## Standards Support

Libraries have also been developed to support Sway Standards. These can be in [Sway-Libs](../reference/sway_libs.md).


---

### File: docs/nightly/sway/docs/book/src/lsp/features.md

# Features

## Code Actions

_Source:_ [code_actions](https://github.com/FuelLabs/sway/tree/master/sway-lsp/src/capabilities/code_actions)

Quickly generate boilerplate code and code comments for functions, structs, and ABIs.

## Completion

_Source:_ [completion.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/completion.rs)

Suggests code to follow partially written statements for functions and variables.

## Go to Definition

Jumps to the definition of a symbol from its usage.

## Find All References

Locates all occurrences of a symbol throughout the project.

## Hover

_Source:_ [hover](https://github.com/FuelLabs/sway/tree/master/sway-lsp/src/capabilities/hover)

Provides documentation, compiler diagnostics, and reference links when hovering over functions and variables.

## Inlay Hints

_Source:_ [inlay_hints.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/inlay_hints.rs)

Displays the implied type of a variable next to the variable name. Configurable in Settings.

## Rename

_Source:_ [rename.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/rename.rs)

Renames a symbol everywhere in the workspace.

## Diagnostics

_Source:_ [diagnostic.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/diagnostic.rs)

Displays compiler warnings and errors inline.

## Syntax Highlighting

_Source:_ [highlight.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/highlight.rs)

Highlights code based on type and context.

## Run

_Source:_ [runnable.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/runnable.rs)

Shows a button above a runnable function or test.


---

### File: docs/nightly/sway/docs/book/src/lsp/index.md

# Sway LSP

Welcome to the documentation for Sway LSP, the language server designed specifically for the Sway programming language. This documentation serves as a comprehensive guide to help you understand and utilize the powerful features provided by Sway LSP.

Sway LSP is built on the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP), a standardized protocol for enabling rich programming language support in editor and IDE environments. It acts as a bridge between your favorite code editor or integrated development environment and the Sway programming language, offering advanced semantic analysis and a wide range of features to enhance your development experience.

With Sway LSP, you can expect a seamless and efficient coding experience while working with the Sway programming language. It provides intelligent code completion, precise symbol navigation, type information, and other smart features that empower you to write clean and error-free code. By leveraging the power of Sway LSP, you can increase productivity, reduce debugging time, and write high-quality code with confidence.

In this documentation, you will find detailed information about how to set up Sway LSP in your preferred code editor or IDE, configure its settings to match your coding style, and take advantage of its various features. We will guide you through the installation process, provide examples of typical configuration setups, and walk you through the usage of each feature supported by Sway LSP.

Whether you are a beginner or an experienced Sway developer, this documentation aims to be your go-to resource for understanding and maximizing the capabilities of Sway LSP. So let's dive in and unlock the full potential of the Sway programming language with Sway LSP!

- [Installation](./installation.md)
- [Features](./features.md)
- [Troubleshooting](./troubleshooting.md)


---

### File: docs/nightly/sway/docs/book/src/lsp/installation.md

# Installation

The Sway language server is contained in the [`forc-lsp`](../forc/plugins/forc_lsp.md) binary, which is installed as part of the [Fuel toolchain](../introduction/fuel_toolchain.md). Once installed, it can be used with a variety of IDEs. It must be installed for any of the IDE plugins to work.

> **Note**: There is no need to manually run `forc-lsp` (the plugin will automatically start it), however both `forc` and `forc-lsp` must be in your `$PATH`. To check if `forc` is in your `$PATH`, type `forc --help` in your terminal.

## VSCode

This is the best supported editor at the moment.

You can install the latest release of the plugin from the [marketplace](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin).

Note that we only support the most recent version of VS Code.

## Code OSS (VSCode on Linux)

1. Install [code-marketplace](https://aur.archlinux.org/packages/code-marketplace) to get access to all of the extensions in the VSCode marketplace.
2. Install the [Sway](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin) extension.

## vim / neovim

Follow the documentation for [sway.vim](https://github.com/FuelLabs/sway.vim) to install.

## helix

[Install helix](https://docs.helix-editor.com/install.html) and Sway LSP will work out of the box.

Sway support is built into helix using [tree-sitter-sway](https://github.com/FuelLabs/tree-sitter-sway).

## Emacs

Coming soon! Feel free to [contribute](https://github.com/FuelLabs/sway/issues/3527).


---

### File: docs/nightly/sway/docs/book/src/lsp/troubleshooting.md

# Troubleshooting

First, confirm you are running the most recent version:

```sh
fuelup toolchain install latest
fuelup update
forc-lsp --version
```

Second, confirm that your `$PATH` resolves to the `forc-lsp` binary in `$HOME/.fuelup/bin`.

```sh
which forc-lsp
```

## Slow Performance

If you are experiencing slow performance, you can try the following:

Follow [the steps above](#troubleshooting) to ensure you are running the most recent version.

Then, make sure you only have the most recent version of the LSP server running.

```sh
pkill forc-lsp
```

### Large projects

Sway projects with ten or more Sway files are likely to have slower LSP performance. We are working on better support for large projects.

In the meantime, if it's too slow, you can disable the LSP server entirely with the `sway-lsp.diagnostic.disableLsp` setting. The extension will still provide basic syntax highlighting, command palettes, as well as the Sway debugger, but all other language features will be disabled.

## Server Logs

You can enable verbose logging of the LSP server.

In VSCode, this is under the setting:

```json
"sway-lsp.trace.server": "verbose"
```

Once enabled, you can find this in the output window under Sway Language Server.

For other editors, see [Installation](./installation.md) for links to documentation.


---

### File: docs/nightly/sway/docs/book/src/reference/attributes.md

# Attributes

Attributes are a form of metadata that can additionally instruct Sway compiler or other tools like `forc test`. Attributes can annotate different language elements, like, e.g., items, enum variants, struct fields, etc.

Below is the list of attributes supported by the Sway compiler, ordered alphabetically:

- [ABI Name](#abi-name)
- [Allow](#allow)
- [Cfg](#cfg)
- [Deprecated](#deprecated)
- [Error](#error)
- [Error Type](#error-type)
- [Fallback](#fallback)
- [Inline](#inline)
- [Payable](#payable)
- [Storage](#payable)
- [Test](#test)

## ABI Name

The `#[abi_name]` attribute allows to specify the ABI name for an item.
This means that when an ABI JSON file is generated, the name that is output is the one specified
by the attribute. This can be useful to allow renaming items, while allowing for keeping backwards
compatibility at the contract ABI level.

> **Note**: At the moment, only enum and struct types support the attribute.

In the example that follows, we originally had `MyStruct` and `MyEnum` types, which we, later on, renamed to `RenamedMyStruct` and `RenamedMyEnum` in code. To keep the backward compatibility of the ABI, we annotate the types with the `#[abi_name]` attribute and give them the original names:

```sway
contract;

#[abi_name(name = "MyStruct")]
struct RenamedMyStruct {}

#[abi_name(name = "MyEnum")]
enum RenamedMyEnum {
  A: ()
}

abi MyAbi {
    fn my_struct() -> RenamedMyStruct;
    fn my_enum() -> RenamedMyEnum;
}

impl MyAbi for Contract {
  fn my_struct() -> RenamedMyStruct { RenamedMyStruct{} }
  fn my_enum() -> RenamedMyEnum { RenamedMyEnum::A }
}
```

This generates the following JSON ABI:

```json
{
  "concreteTypes": [
    {
      "concreteTypeId": "215af2bca9e1aa8fec647dab22a0cd36c63ce5ed051a132d51323807e28c0d67",
      "metadataTypeId": 1,
      "type": "enum MyEnum"
    },
    {
      "concreteTypeId": "d31db280ac133d726851d8003bd2f06ec2d3fc76a46f1007d13914088fbd0791",
      "type": "struct MyStruct"
    }
  ],
  ...
}
```

We get the same JSON ABI output both before and after renaming the types, due to attributing them with
`#[abi_name(name = ...)]`, which forces them to be generated with their previous Sway names.
This means consumers of this contract will still get the original names, keeping compatibility at the ABI level.

## Allow

The `#[allow(...)]` attribute disables compiler checks so that certain warnings will go unreported. The following warnings can be disabled:

- `#[allow(dead_code)]` disables warnings for dead code;
- `#[allow(deprecated)]` disables warnings for usage of deprecated elements, like, e.g., structs, functions, enum variants, etc.

## Cfg

The `#[cfg(...)]` attribute allows conditional compilation. The annotated code element will be compiled only if the condition in to the `cfg` attribute evaluates to true. The following conditions can be expressed:

- `#[cfg(target = "<target>")]` where `<target>` can be either "evm" or "fuel";
- `#[cfg(program_type = "<program_type>")]` where `<program_type>` can be either "predicate", "script", "contract", or "library";
- `#[cfg(experimental_<feature_flag> = true/false)]` where `<feature_flag>` is one of the known experimental feature flags.

## Deprecated

The `#[deprecated]` attribute marks an item as deprecated and makes the compiler emit a warning for every usage of the deprecated item. This warning can be disabled using `#[allow(deprecated)]`.

It is possible to improve the warning message with `#[deprecated(note = "Your deprecation message.")]`

## Error

The `#[error]` defines an error message for an error type enum variant:

```sway
#[error_type]
enum SomeErrors {
    #[error(m = "An unexpected error occurred.")]
    UnexpectedError: (),
}
```

## Error Type

The `#[error_type]` marks an enum as error type enum:

```sway
#[error_type]
enum SomeErrors {
    ...
}
```

All variants of an error type enum must be annotated with the [`#[error]` attribute](#error). Error type enums are meant to be use in `panic` expressions for rich error reporting.

## Fallback

The `#[fallback]` attribute makes the compiler use the marked function as the contract call fallback function. This means that, when a contract method is called, and the contract method selection fails, the fallback function will be called instead.

More details in [Calling Contracts](../blockchain-development/calling_contracts.md#fallback).

## Inline

The inline attribute *suggests* to the compiler if a copy of the annotated function should be placed in the caller, rather than generating code to call the function where it is defined.

The `#[inline(never)]` attribute *suggests* that an inline expansion should never be performed.

The `#[inline(always)]` attribute *suggests* that an inline expansion should always be performed.

> **Note**: `#[inline(..)]` in every form is a hint, with no *requirements* on the compiler to place a copy of the annotated function in the caller. The Sway compiler automatically inlines functions based on internal heuristics. Incorrectly inlining functions can make the program slower, so this attribute should be used with care.

## Payable

The lack of `#[payable]` implies the method is non-payable. When calling an ABI method that is non-payable, the compiler emits an error if the amount of coins forwarded with the call is not guaranteed to be zero. Note that this is strictly a compile-time check and does not incur any runtime cost.

## Storage

In Sway, functions are pure by default but can be opted into impurity via the `storage` function attribute. The `storage` attribute may take `read` and/or `write` arguments indicating which type of access the function requires.

The `#[storage(read)]` attribute indicates that a function requires read access to the storage.

The `#[storage(write)]` attribute indicates that a function requires write access to the storage.

More details in [Purity](../blockchain-development/purity.md).

## Test

The `#[test]` attribute marks a function to be executed as a test.

The `#[test(should_revert)]` attribute marks a function to be executed as a test that should revert.

More details in [Unit Testing](../testing/unit-testing.md).


---

### File: docs/nightly/sway/docs/book/src/reference/compiler_intrinsics.md

# Compiler Intrinsics

The Sway compiler supports a list of intrinsics that perform various low level operations that are useful for building libraries. Compiler intrinsics should rarely be used but are preferred over `asm` blocks because they are type-checked and are safer overall. Below is a list of all available compiler intrinsics:

---

```sway
__size_of_val<T>(val: T) -> u64
```

**Description:** Return the size of type `T` in bytes.

**Constraints:** None.

---

```sway
__size_of<T>() -> u64
```

**Description:** Return the size of type `T` in bytes.

**Constraints:** None.

---

```sway
__size_of_str_array<T>() -> u64
```

**Description:** Return the size of type `T` in bytes. This intrinsic differs from `__size_of` in the case of "string arrays" where the actual length in bytes of the string is returned without padding the byte size to the next word alignment. When `T` is not a "string array" `0` is returned.

**Constraints:** None.

---

```sway
__assert_is_str_array<T>()
```

**Description:** Throws a compile error if type `T` is not a "string array".

**Constraints:** None.

---

```sway
__to_str_array(s: str) -> str[N]
```

**Description:** Converts a "string slice" to "string array" at compile time. Parameter "s" must be a string literal.

**Constraints:** None.

---

```sway
__is_reference_type<T>() -> bool
```

**Description:** Returns `true` if `T` is a _reference type_ and `false` otherwise.

**Constraints:** None.

---

```sway
__is_str_array<T>() -> bool
```

**Description:** Returns `true` if `T` is a string array and `false` otherwise.

**Constraints:** None.

---

```sway
__eq<T>(lhs: T, rhs: T) -> bool
```

**Description:** Returns whether `lhs` and `rhs` are equal.

**Constraints:** `T` is `bool`, `u8`, `u16`, `u32`, `u64`, `u256`, `b256` or `raw_ptr`.

---

```sway
__gt<T>(lhs: T, rhs: T) -> bool
```

**Description:** Returns whether `lhs` is greater than `rhs`.

**Constraints:** `T` is `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__lt<T>(lhs: T, rhs: T) -> bool
```

**Description:** Returns whether `lhs` is less than `rhs`.

**Constraints:** `T` is `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__gtf<T>(index: u64, tx_field_id: u64) -> T
```

**Description:** Returns transaction field with ID `tx_field_id` at index `index`, if applicable. This is a wrapper around FuelVM's [`gtf` instruction](https://fuellabs.github.io/fuel-specs/master/vm/instruction_set#gtf-get-transaction-fields). The resulting field is cast to `T`.

**Constraints:** None.

---

```sway
__addr_of<T>(val: T) -> raw_ptr
```

**Description:** Returns the address in memory where `val` is stored.

**Constraints:** None.

---

```sway
__state_load_word(key: b256) -> u64
```

**Description:** Reads and returns a single word from storage at key `key`.

**Constraints:** None.

---

```sway
__state_load_quad(key: b256, ptr: raw_ptr, slots: u64) -> bool
```

**Description:** Reads `slots` number of slots (`b256` each) from storage starting at key `key` and stores them in memory starting at address `ptr`. Returns a Boolean describing whether all the storage slots were previously set.

**Constraints:** None.

---

```sway
__state_store_word(key: b256, val: u64) -> bool
```

**Description:** Stores a single word `val` into storage at key `key`. Returns a Boolean describing whether the store slot was previously set.

**Constraints:** None.

---

```sway
__state_store_quad(key: b256, ptr: raw_ptr, slots: u64) -> bool
```

**Description:** Stores `slots` number of slots (`b256` each) starting at address `ptr` in memory into storage starting at key `key`. Returns a Boolean describing whether the first storage slot was previously set.

**Constraints:** None.

---

```sway
__log<T>(val: T) where T: AbiEncode
```

**Description:** Logs value `val`.

**Constraints:**

- `T` must implement AbiEncode

---

```sway
__add<T>(lhs: T, rhs: T) -> T
```

**Description:** Adds `lhs` and `rhs` and returns the result.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__sub<T>(lhs: T, rhs: T) -> T
```

**Description:** Subtracts `rhs` from `lhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__mul<T>(lhs: T, rhs: T) -> T
```

**Description:** Multiplies `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__div<T>(lhs: T, rhs: T) -> T
```

**Description:** Divides `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__and<T>(lhs: T, rhs: T) -> T
```

**Description:** Bitwise AND `lhs` and `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__or<T>(lhs: T, rhs: T) -> T
```

**Description:** Bitwise OR `lhs` and `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__xor<T>(lhs: T, rhs: T) -> T
```

**Description:** Bitwise XOR `lhs` and `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__mod<T>(lhs: T, rhs: T) -> T
```

**Description:** Modulo of `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__rsh<T>(lhs: T, rhs: u64) -> T
```

**Description:** Logical right shift of `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__lsh<T>(lhs: T, rhs: u64) -> T
```

**Description:** Logical left shift of `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__revert(code: u64)
```

**Description:** Reverts with error code `code`.

**Constraints:** None.

---

```sway
__ptr_add(ptr: raw_ptr, offset: u64)
```

**Description:** Adds `offset` to the raw value of pointer `ptr`.

**Constraints:** None.

---

```sway
__ptr_sub(ptr: raw_ptr, offset: u64)
```

**Description:** Subtracts `offset` to the raw value of pointer `ptr`.

**Constraints:** None.

---

```sway
__smo<T>(recipient: b256, data: T, coins: u64)
```

**Description:** Sends a message `data` of arbitrary type `T` and `coins` amount of the base asset to address `recipient`.

**Constraints:** None.

---

```sway
__not(op: T) -> T
```

**Description:** Bitwise NOT of `op`

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__jmp_mem()
```

**Description:** Jumps to `MEM[$hp]`.

**Constraints:** None.

---

```sway
__slice<T>(item: &[T; N], start: u64, end: u64) -> &[T]
__slice<T>(item: &[T], start: u64, end: u64) -> &[T]
__slice<T>(item: &mut [T; N], start: u64, end: u64) -> &mut [T]
__slice<T>(item: &mut [T], start: u64, end: u64) -> &mut [T]
```

**Description:** Slices an array or another slice.

This intrinsic returns a reference to a slice containing the range of elements inside `item`.
The mutability of reference is defined by the first parameter mutability.

Runtime bound checks are not generated, and must be done manually when and where appropriated. Compile time bound checks are done when possible.

**Constraints:**

- `item` is an array or a slice;
- when `start` is a literal, it must be smaller than `item` length;
- when `end` is a literal, it must be smaller than or equal to `item` length;
- `end` must be greater than or equal to `start`

---

```sway
__elem_at<T>(item: &[T; N], index: u64) -> &T
__elem_at<T>(item: &[T], index: u64) -> &T
__elem_at<T>(item: &mut [T; N], index: u64) -> &mut T
__elem_at<T>(item: &mut [T], index: u64) -> &mut T
```

**Description:** Returns a reference to the indexed element. The mutability of reference is defined by the first parameter mutability.

Runtime bound checks are not generated, and must be done manually when and where appropriated. Compile time bound checks are done when possible.

**Constraints:**

- `item` is a reference to an array or a reference to a slice;
- when `index` is a literal, it must be smaller than `item` length;

---

```sway
__dbg<T>(value: T) -> T where T: Debug
```

**Description:** Automatically calls the `Debug` trait on the passed `value`, with file, line and column information. The passed value is returned without any modification, allowing `__dbg(...)` to be used inside of any expression.

The code generated by this intrinsic function varies with the compilation mode. For example:

```terminal
forc build            <- will print everything as expected
forc build --release  <- nothing will be printed
```

To enable code generation even on `Release` builds, the flag `force-dbg-in-release` needs to be enabled inside `forc.toml`.
Example:

```toml
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
license = "Apache-2.0"
entry = "main.sw"
name = "some-project"
force-dbg-in-release = true
```

It is strongly suggested to always remove this flag before publishing binaries as it will not have any effect when running
on real nodes and it only increases gas usage.

**Constraints:**

- `T` must implement Debug


---

### File: docs/nightly/sway/docs/book/src/reference/contributing_to_sway.md

# Contributing To Sway

Thanks for your interest in contributing to Sway! This document outlines the process for installing and setting up the Sway toolchain for development, as well as some conventions on contributing to Sway.

If you run into any difficulties getting started, you can always ask questions on our [Discourse](https://forum.fuel.network/).

## Building and setting up a development workspace

See the [introduction](../introduction/index.md) section for instructions on installing and setting up the Sway toolchain.

## Getting the repository

1. Visit the [Sway](https://github.com/FuelLabs/sway) repo and fork the project.
2. Then clone your forked copy to your local machine and get to work.

```sh
git clone https://github.com/FuelLabs/sway
cd sway
```

## Building and testing

The following steps will run the sway test suite and ensure that everything is set up correctly.

First, open a new terminal and start `fuel-core` with:

```sh
fuel-core
```

Then open a second terminal, `cd` into the `sway` repo and run:

```sh
cargo run --bin test
```

After the test suite runs, you should see:

```console
Tests passed.
_n_ tests run (0 skipped)
```

Congratulations! You've now got everything setup and are ready to start making contributions.

## Finding something to work on

There are many ways in which you may contribute to the Sway project, some of which involve coding knowledge and some which do not. A few examples include:

- Reporting bugs
- Adding documentation to the Sway book
- Adding new features or bug fixes for which there is already an open issue
- Making feature requests

Check out our [Help Wanted](https://github.com/FuelLabs/sway/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22), [Sway Book](https://github.com/FuelLabs/sway/issues?q=is%3Aopen+is%3Aissue+label%3A%22The+Sway+Book%22) or [Good First Issue](https://github.com/FuelLabs/sway/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) issues to find a suitable task.

If you are planning something big, for example, related to multiple components or changes current behaviors, make sure to open an issue to discuss with us before starting on the implementation.

## Contribution flow

This is a rough outline of what a contributor's workflow looks like:

- Make sure what you want to contribute is already tracked as an issue.
  - We may discuss the problem and solution in the issue.
- Create a Git branch from where you want to base your work. This is usually master.
- Write code, add test cases, and commit your work.
- Run tests and make sure all tests pass.
- If the PR contains any breaking changes, add the breaking label to your PR.
- Push your changes to a branch in your fork of the repository and submit a pull request.
  - Make sure to mention the issue, which is created at step 1, in the commit message.
- Your PR will be reviewed and some changes may be requested.
  - Once you've made changes, your PR must be re-reviewed and approved.
  - If the PR becomes out of date, you can use GitHub's 'update branch' button.
  - If there are conflicts, you can merge and resolve them locally. Then push to your PR branch.
    Any changes to the branch will require a re-review.
- Our CI system (Github Actions) automatically tests all authorized pull requests.
- Use Github to merge the PR once approved.

Thanks for your contributions!

### Linking issues

Pull requests should be linked to at least one issue in the same repo.

If the pull request resolves the relevant issues, and you want GitHub to close these issues automatically after it merged into the default branch, you can use the syntax (`KEYWORD #ISSUE-NUMBER`) like this:

```markdown
close #123
```

If the pull request links an issue but does not close it, you can use the keyword `ref` like this:

```markdown
ref #456
```

Multiple issues should use full syntax for each issue and separate by a comma, like:

```markdown
close #123, ref #456
```


---

### File: docs/nightly/sway/docs/book/src/reference/index.md

# Sway Reference

- [Compiler Intrinsics](./compiler_intrinsics.md)
- [Attributes](./attributes.md)
- [Style Guide](./style_guide.md)
- [Known Issues and Workarounds](./known_issues_and_workarounds.md)
- [Differences from Rust](./rust_differences.md)
- [Differences from Solidity](./solidity_differences.md)
- [Contributing to Sway](./contributing_to_sway.md)
- [Keywords](./keywords.md)


---

### File: docs/nightly/sway/docs/book/src/reference/keywords.md

# Keywords

The following list contains keywords that are reserved for current or
future use by the Sway language. As such, **they cannot be used as
identifiers**. Identifiers are names of functions, variables,
parameters, modules, constants, attributes, types or
traits, etc.

## Keywords Currently in Use

The following is an alphabetically sorted list of keywords currently in use, with their
functionality shortly described.

- `as` - rename items in `use` statements, e.g., `use type::type_name as alias_name;`
- [`abi`](../sway-program-types/smart_contracts.md#the-abi-declaration) - define a smart contract ABI in a syntactically similar way to traits
- [`asm`](../advanced/assembly.md) - define an assembly block
- [`break`](../basics/control_flow.md#break-and-continue) - exit a loop immediately
- `configurable` - define configurable constants
- [`const`](../basics/constants.md) - define constant
- [`continue`](../basics/control_flow.md#break-and-continue) - continue to the next loop iteration
- [`contract`](../sway-program-types/smart_contracts.md) - define contract program type
- `else` - used in conjunction with `if` conditions for control flow constructs
- [`enum`](../basics/structs_tuples_and_enums.md#enums) - define an enum
- `false` - Boolean false literal
- [`for`](../basics/control_flow.md#for) - loop based on iterators
- [`fn`](../basics/functions.md)- define a function
- [`if`](../basics/control_flow.md#if-expressions) - branch based on the result of a conditional expression
- `impl` - implement inherent or trait functionality
- `let` - bind a variable
- [`library`](../sway-program-types/libraries.md) - define library program type
- [`match`](../basics/control_flow.md#match-expressions) - exhaustively match a value to patterns
- `mod` - define a module
- `mut` - denote mutability
- `pub` - denote public visibility
- [`predicate`](../sway-program-types/predicates.md) - define predicate program type
- `ref` - bind by reference
- `return` - return early from a function
- [`script`](../sway-program-types/scripts.md) - define script program type
- `Self` - a type alias for the type we are defining or implementing
- `self` - method call target
- [`storage`](../blockchain-development/storage.md) - define a storage declaration
- `str`- string slice
- [`struct`](../basics/structs_tuples_and_enums.md#structs) - define a structure
- [`trait`](../advanced/traits.md#declaring-a-trait) - define a trait
- `true` - Boolean true literal
- [`type`](../advanced/advanced_types.md#creating-type-synonyms-with-type-aliases) - define a type alias or associated type
- `use` - bring symbols into scope
- `where` - specifies trait constraints for generic type arguments
- [`while`](../basics/control_flow.md#while) - loop conditionally based on the result of an expression

## Keywords Reserved for Possible Future Use

- `abstract`
- `async`
- `await`
- `become`
- `box`
- `do`
- `dyn`
- `extern`
- `for`
- `in`
- `loop`
- `macro`
- `move`
- `override`
- `priv`
- `static`
- `super`
- `try`
- `typeof`
- `unsafe`
- `unsized`
- `virtual`
- `yield`


---

### File: docs/nightly/sway/docs/book/src/reference/known_issues_and_workarounds.md

# Known Issues and Workarounds

## Known Issues

* [#870](https://github.com/FuelLabs/sway/issues/870): All `impl` blocks need to be defined before any of the functions they define can be called.  This includes sibling functions in the same `impl` declaration, i.e., functions in an `impl` can't call each other yet.

## Missing Features

* [#1182](https://github.com/FuelLabs/sway/issues/1182) Arrays in a `storage` block are not yet supported. See the [Manual Storage Management](../advanced/advanced_storage.md#manual-storage-management) section for details on how to use `store` and `get` from the standard library to manage storage slots directly. Note, however, that `StorageMap<K, V>` _does_ support arbitrary types for `K` and `V` without any limitations.

## General

* No compiler optimization passes have been implemented yet, therefore bytecode will be more expensive and larger than it would be in production. Note that eventually the optimizer will support zero-cost abstractions, avoiding the need for developers to go down to inline assembly to produce optimal code.


---

### File: docs/nightly/sway/docs/book/src/reference/rust_differences.md

# Differences From Rust

Sway shares a lot with Rust, especially its syntax. Because they are so similar, you may be surprised or caught off guard when they differ. This page serves to outline, from a high level, some of the syntactic _gotchas_ that you may encounter.

## Enum Variant Syntax

In Rust, enums generally take one of three forms: _unit_ variants, which have no inner data, _struct_ variants, which contain named fields, and _tuple_ variants, which contain within them a tuple of data. If you are unfamiliar with these terms, this is what they look like:

```rust,ignore
// note to those skimming the docs: this is Rust syntax! Not Sway! Don't copy/paste this into a Sway program.

enum Foo {
    UnitVariant,
    TupleVariant(u32, u64, bool),
    StructVariant {
        field_one: bool,
        field_two: bool
    }
}
```

In Sway, enums are simplified. Enums variants must all specify exactly one type. This type represents their interior data. This is actually isomorphic to what Rust offers, but with a different syntax. You can see the above enum but with Sway syntax below:

```sway
// This is equivalent Sway syntax for the above Rust enum.
enum Foo {
    UnitVariant: (),
    TupleVariant: (u32, u64, bool),
    StructVariant: MyStruct,
}

struct MyStruct {
    field_one: bool,
    field_two: bool,
}
```

## Memory Allocation

In Rust, the borrow checker implements Rust's [ownership system](https://doc.rust-lang.org/1.8.0/book/ownership.html)

In Sway, there is no borrow checker.  This means there is no concept of ownership, borrowing, or lifetimes.  Instead, objects are copied and moved similar to C++.  Also Sway does not have any destructors nor `Drop` traits.  This means allocated memory lives for the entire transaction and is not deallocated until the end of the transaction.  A transaction may allocate up to [64 MB](https://github.com/FuelLabs/fuel-vm/blob/a80f82ed7c793763de6a73ca72d946b311b0fd0b/fuel-vm/src/consts.rs#L26) of memory.


---

### File: docs/nightly/sway/docs/book/src/reference/solidity_differences.md

# Differences From Solidity

This page outlines some of the critical differences between Sway and Solidity, and between the FuelVM and the EVM.

## Underlying Virtual Machine

The underlying virtual machine targeted by Sway is the FuelVM, specified [here](https://github.com/FuelLabs/fuel-specs). Solidity targets the Ethereum Virtual Machine (EVM), specified [here](https://ethereum.github.io/yellowpaper/paper.pdf).

## Word Size

Words in the FuelVM are 64 bits (8 bytes), rather than the 256 bits (32 bytes) of the EVM. Therefore, all primitive integers smaller and including `u64` are stored in registers; `u256`, being bigger than the registers, and hashes (the `b256` type) are not stored in registers but rather in memory. They are therefore pointers to a 32-byte memory region containing their data.

## Unsigned Integers Only

Only unsigned integers are provided as primitives: `u8`, `u16`, `u32`, `u64`, and `u256`. Signed integer arithmetic is not available in the FuelVM. Signed integers and signed integer arithmetic can be implemented in high-level libraries if needed.

## Global Revert

Panics in the FuelVM (called "reverts" in Solidity and the EVM) are global, i.e. they cannot be caught. A panic will completely and unconditionally revert the stateful effects of a transaction, minus gas used.

## Default Safe Math

<!-- This section should explain safe math in Fuel vs EVM -->
<!-- safe_math:example:start -->
Math in the FuelVM is by default safe (i.e. any overflow or exception is a panic). Safety checks are performed natively in the VM implementation, rather than at the bytecode level like [Solidity's default safe math](https://docs.soliditylang.org/en/latest/080-breaking-changes.html#silent-changes-of-the-semantics).
<!-- safe_math:example:end -->

## No* Code Size Limit

There is no practical code size limit to Sway contracts. The physical limit is governed by the [`VM_MAX_RAM` VM parameter](https://fuellabs.github.io/fuel-specs/master/vm#parameters), which at the time of writing is 64 MiB.

## Account Types

Account types in the FuelVM have type-safe wrappers around primitive `b256` hashes to clearly distinguish their respective types. The wrapper `Address` mirrors that of an EOA (Externally Owned Account) and has the ability to hold UTXOs in the context of the EVM. The other wrapper, `ContractId`, reflects that of a deployed contract in the EVM but cannot hold UTXOs.


---

### File: docs/nightly/sway/docs/book/src/reference/style_guide.md

# Style Guide

## Capitalization

<!-- This section should explain the capitalization style guide -->
<!-- cap:example:start -->
In Sway, structs, traits, and enums are `CapitalCase`. Modules, variables, and functions are `snake_case`, constants are `SCREAMING_SNAKE_CASE`. The compiler will warn you if your capitalization is ever unidiomatic.
<!-- cap:example:end -->


---

### File: docs/nightly/sway/docs/book/src/reference/sway_libs.md

# Sway Libraries

The purpose of Sway Libraries is to contain libraries which users can import and use that are not part of the standard library.

These libraries contain helper functions and other tools valuable to blockchain development.

For more information on how to use a Sway-Libs library, please refer to the [Sway-Libs Book](https://fuellabs.github.io/sway-libs/book/getting_started/index.html).

## Assets Libraries

Asset Libraries are any libraries that use [Native Assets](../blockchain-development/native_assets.md) on the Fuel Network.

- [Asset Library](https://fuellabs.github.io/sway-libs/book/asset/index.html); provides helper functions for the [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) standards.

## Access Control and Security Libraries

Access Control and Security Libraries are any libraries that are built and intended to provide additional safety when developing smart contracts.

- [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html); used to apply restrictions on functions such that only a **single** user may call them. This library provides helper functions for the [SRC-5; Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md).
- [Admin Library](https://fuellabs.github.io/sway-libs/book/admin/index.html); used to apply restrictions on functions such that only a select few users may call them like a whitelist.
- [Pausable Library](https://fuellabs.github.io/sway-libs/book/pausable/index.html); allows contracts to implement an emergency stop mechanism.
- [Reentrancy Guard Library](https://fuellabs.github.io/sway-libs/book/reentrancy/index.html); used to detect and prevent reentrancy attacks.

## Cryptography Libraries

Cryptography Libraries are any libraries that provided cryptographic functionality beyond what the std-lib provides.

- [Bytecode Library](https://fuellabs.github.io/sway-libs/book/bytecode/index.html); used for on-chain verification and computation of bytecode roots for contracts and predicates.
- [Merkle Proof Library](https://fuellabs.github.io/sway-libs/book/merkle/index.html); used to verify Binary Merkle Trees computed off-chain.

## Math Libraries

Math Libraries are libraries which provide mathematic functions or number types that are outside of the std-lib's scope.

- [Signed Integers Library](https://fuellabs.github.io/sway-libs/book/signed_integers/index.html); an interface to implement signed integers.

## Data Structures Libraries

Data Structure Libraries are libraries which provide complex data structures which unlock additional functionality for Smart Contracts.

- [Queue Library](https://fuellabs.github.io/sway-libs/book/queue/index.html); a linear data structure that provides First-In-First-Out (FIFO) operations.


---

### File: docs/nightly/sway/docs/book/src/reference/undefined_behavior.md

# Behavior Considered Undefined

Sway code that contains any of the following behavior is considered undefined.
The compiler is allowed to treat undefined Sway code however it desires,
including removing it or replacing it with any other Sway code.

This is not an exhaustive list, it may grow or shrink, there is no formal model
of Sway's semantics so there may be more behavior considered undefined. We
reserve the right to make some of the listed behavior defined in the future.

* Invalid arithmetic operations (overflows, underflows, division by zero, etc.).
* Misuse of compiler intrinsics.
* Incorrect use of inline assembly.
* Reading and writing `raw_ptr` and `raw_slice`.
* Slicing and indexing out of bounds by directly using compiler intrinsics.
* Modifying collections while iterating over them using `Iterator`s.


---

### File: docs/nightly/sway/docs/book/src/sway-program-types/index.md

# Sway Program Types

<!-- This section should explain program types -->
<!-- programs:example:start -->
A Sway program itself has a type: it is either a _contract_, a _predicate_, a _script_, or a _library_. The first three of these things are all deployable to the blockchain. A _library_ is simply a project designed for code reuse and is never directly deployed to the chain.

Every Sway file _must_ begin with a declaration of what type of program it is. A project can have many libraries within it, but only one contract, script, or predicate. Scripts and predicates require `main` functions to serve as entry points, while contracts instead publish an ABI. This chapter will go into detail about all of these various types of programs and what purposes they serve.
<!-- programs:example:end -->

Contracts are used primarily for protocols or systems that operate within a fixed set of rules. A good example would be a staking contract or a decentralized exchange (also called a DEX).

Scripts are used for complex on-chain interactions that won't persist. An example of this may be using a DEX and Lender to create a leveraged position (borrow, swap, re-collateralize) which is a complex transaction that would usually take multiple steps.

Libraries are for code that is reusable and useful for handling common situations. A good example of this would be a library to handle fixed-point math or big number math.

- [Contracts](./smart_contracts.md)
- [Libraries](./libraries.md)
- [Scripts](./scripts.md)
- [Predicates](./predicates.md)


---

### File: docs/nightly/sway/docs/book/src/sway-program-types/libraries.md

# Libraries

<!-- This section should explain what a library is -->
<!-- library:example:start -->
Libraries in Sway are files used to define new common behavior.
<!-- library:example:end -->

The most prominent example of this is the [Sway Standard Library](../introduction/standard_library.md) that is made implicitly available to all Forc projects created using `forc new`.

## Writing Libraries

<!-- This section should explain how libraries are defined -->
<!-- def_lib:example:start -->
Libraries are defined using the `library` keyword at the beginning of a file, followed by a name so that they can be imported.
<!-- def_lib:example:end -->

```sway
library;

// library code
```

A good reference library to use when learning library design is the [Sway Standard Library](../introduction/standard_library.md). For example, the standard library offers an [implementation](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/option.sw) of `enum Option<T>` which is a generic type that represents either the existence of a value using the variant `Some(..)` or a value's absence using the variant `None`. The [Sway file implementing `Option<T>`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/option.sw) has the following structure:

- The `library` keyword:

```sway
library;
```

- A `use` statement that imports `revert` from another library _inside_ the standard library:

```sway
use ::revert::revert;
```

- The `enum` definition which starts with the keyword `pub` to indicate that this `Option<T>` is publicly available _outside_ the `option` library:

```sway
pub enum Option<T> {
    // variants
}
```

- An `impl` block that implements some methods for `Option<T>`:

```sway
impl<T> Option<T> {

    fn is_some(self) -> bool {
        // body of is_some
    }

    // other methods
}
```

Now that the library `option` is fully written, and because `Option<T>` is defined with the `pub` keyword, we are now able to import `Option<T>` using `use std::option::Option;` from any Sway project and have access to all of its variants and methods. That being said, `Option` is automatically available in the [standard library prelude](../introduction/standard_library.md#standard-library-prelude) so you never actually have to import it manually.

Libraries are composed of just a `Forc.toml` file and a `src` directory, unlike contracts which usually contain a `tests` directory and a `Cargo.toml` file as well. An example of a library's `Forc.toml`:

```toml
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "lib.sw"
license = "Apache-2.0"
name = "my_library"

[dependencies]
```

which denotes the authors, an entry file, the name by which it can be imported, and any dependencies.

For large libraries, it is recommended to have a `lib.sw` entry point re-export all other sub-libraries.

<!-- This section should explain the `mod` keyword -->
<!-- mod:example:start -->
The `mod` keyword registers a submodule, making its items (such as functions and structs) accessible from the parent library.
If used at the top level it will refer to a file in the `src` folder and in other cases in a folder named after the library in which it is defined.
<!-- mod:example:end -->

For example, the `lib.sw` of the standard library looks like:

```sway
library;

mod block;
mod storage;
mod constants;
mod vm;
// .. Other deps
```

with other libraries contained in the `src` folder, like the `vm` library (inside of `src/vm.sw`):

```sway
library;

mod evm;
// ...
```

and it's own sub-library `evm` located in `src/vm/evm.sw`:

```sway
library;

// ...
```

## Using Libraries

There are two types of Sway libraries, based on their location and how they can be imported.

### Internal Libraries

Internal libraries are located within the project's `src` directory alongside
`main.sw` or in the appropriate folders as shown below:

```bash
$ tree
.
├── Cargo.toml
├── Forc.toml
└── src
    ├── internal_lib.sw
    ├── main.sw
    └── internal_lib
        └── nested_lib.sw
```

As `internal_lib` is an internal library, it can be imported into `main.sw` as follows:

- Use the `mod` keyword followed by the library name to make the internal library a dependency
- Use the `use` keyword with a `::` separating the name of the library and the imported item(s)

```sway
mod internal_lib; // Assuming the library name in `internal_lib.sw` is `internal_lib`

use internal_lib::mint;

// `mint` from `internal_library` is now available in this file
```

### External Libraries

External libraries are located outside the main `src` directory as shown below:

```bash
$ tree
.
├── my_project
│   ├── Cargo.toml
│   ├── Forc.toml
│   └─── src
│       └── main.sw
│
└── external_lib
    ├── Cargo.toml
    ├── Forc.toml
    └─── src
        └── lib.sw
```

As `external_lib` is outside the `src` directory of `my_project`, it needs to be added as a dependency in the `Forc.toml` file of `my_project`, by adding the library path in the `dependencies` section as shown below, before it can be imported:

```toml
[dependencies]
external_library = { path = "../external_library" }
```

Once the library dependency is added to the `toml` file, you can import items from it as follows:

- Make sure the item you want imported are declared with the `pub` keyword (if applicable, for instance: `pub fn mint() {}`)
- Use the `use` keyword to selectively import items from the library

```sway
use external_library::mint;

// `mint` from `external_library` is now available in this file
```

Wildcard imports using `*` are supported, but it is generally recommended to use explicit imports where possible.

> **Note**: the standard library is implicitly available to all Forc projects, that is, you are not required to manually specify `std` as an explicit dependency in `Forc.toml`.

## Reference Sway Libraries

The repository [`sway-libs`](https://github.com/FuelLabs/sway-libs/) is a collection of external libraries that you can import and make use of in your Fuel applications. These libraries are meant to be implementations of common use-cases valuable for dapp development.

Some Sway Libraries to try out:

- [Binary Merkle Proof](https://docs.fuel.network/docs/sway-libs/merkle/)
- [Signed Integers](https://docs.fuel.network/docs/sway-libs/signed_integers/)
- [Ownership](https://fuellabs.github.io/sway-libs/book/ownership/index.html)

### Example

You can import and use a Sway Library such as the [Ownership](https://fuellabs.github.io/sway-libs/book/ownership/index.html) library just like any other external library.

```sway
use ownership::Ownership;
```

Once imported, you can use the following basic functionality of the library in your smart contract:

- Declaring an owner
- Changing ownership
- Renouncing ownership
- Ensuring a function may only be called by the owner


---

### File: docs/nightly/sway/docs/book/src/sway-program-types/predicates.md

# Predicates

From the perspective of Sway, predicates are programs that return a Boolean value and which represent ownership of some resource upon execution to true. They have no access to contract storage. Here is a trivial predicate, which always evaluates to true:

```sway
predicate;

// All predicates require a main function which returns a Boolean value.
fn main() -> bool {
    true
}
```

The address of this predicate is `0xd19a5fe4cb9baf41ad9813f1a6fef551107c8e8e3f499a6e32bccbb954a74764`. Any assets sent to this address can be unlocked or claimed by executing the predicate above as it always evaluates to true.

It does not need to be deployed to a blockchain because it only exists during a transaction. That being said, the predicate address is on-chain as the owner of one or more UTXOs.

## Transfer Coins to a Predicate

In Fuel, coins can be sent to a predicate's address(the bytecode root, calculated [here](https://github.com/FuelLabs/fuel-specs/blob/master/src/identifiers/predicate-id.md)).

## Spending Predicate Coins

The coin UTXOs become spendable not on the provision of a valid signature, but rather if the supplied predicate both has a root that matches their owner, and [evaluates](https://github.com/FuelLabs/fuel-specs/blob/master/src/fuel-vm/index.md#predicate-verification) to `true`.

If a predicate reverts, or tries to access impure VM opcodes, the evaluation is automatically `false`.

An analogy for predicates is rather than a traditional 12 or 24 word seed phrase that generates a private key and creates a valid signature, a predicate's code can be viewed as the private key. Anyone with the code may execute a predicate, but only when the predicate evaluates to true may the assets owned by that address be released.

## Spending Conditions

Predicates may introspect the transaction spending their coins (inputs, outputs, script bytecode, etc.) and may take runtime arguments, either or both of which may affect the evaluation of the predicate.

It is important to note that predicates cannot read or write memory. They may however check the inputs and outputs of a transaction. For example in the [OTC Predicate Swap Example](https://github.com/FuelLabs/sway-applications/tree/master/OTC-swap-predicate), a user may specify they would like to swap `asset1` for `asset2` and with amount of `5`. The user would then send `asset1` to the predicate. Only when the predicate can verify that the outputs include `5` coins of `asset2` being sent to the original user, may `asset1` be transferred out of the predicate.


---

### File: docs/nightly/sway/docs/book/src/sway-program-types/scripts.md

# Scripts

A script is runnable bytecode on the chain which executes once to perform some task. It does not represent ownership of any resources and it cannot be called by a contract. A script can return a single value of any type.

Scripts are state-aware in that while they have no persistent storage (because they only exist during the transaction) they can call contracts and act based upon the returned values and results.

This example script calls a contract:

```sway
script;

use wallet_abi::Wallet;

fn main() {
    let contract_address = 0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b;
    let caller = abi(Wallet, contract_address);
    let amount_to_send = 200;
    let recipient_address = Address::from(0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b);
    caller
        .send_funds {
            gas: 10000,
            coins: 0,
            asset_id: b256::zero(),
        }(amount_to_send, recipient_address);
}

```

Scripts, similar to predicates, rely on a `main()` function as an entry point. You can call other functions defined in a script from the `main()` function or call another contract via an [ABI cast](./smart_contracts.md#calling-a-smart-contract-from-a-script).

An example use case for a script would be a router that trades funds through multiple decentralized exchanges to get the price for the input asset, or a script to re-adjust a Collateralized Debt Position via a flash loan.

## Scripts and the SDKs

Unlike EVM transactions which can call a contract directly (but can only call a single contract), Fuel transactions execute a script, which may call zero or more contracts. The Rust and TypeScript SDKs provide functions to call contract methods as if they were calling contracts directly. Under the hood, the SDKs wrap all contract calls with scripts that contain minimal code to simply make the call and forward script data as call parameters.


---

### File: docs/nightly/sway/docs/book/src/sway-program-types/smart_contracts.md

# What is a Smart Contract?

<!-- This section should explain what is a smart contract -->
<!-- contract:example:start -->
A smart contract is no different than a script or predicate in that it is a piece of bytecode that is deployed to the blockchain via a [transaction](https://fuellabs.github.io/fuel-specs/master/protocol/tx_format). The main features of a smart contract that differentiate it from scripts or predicates are that it is _callable_ and _stateful_. Put another way, a smart contract is analogous to a deployed API with some database state.
<!-- contract:example:end -->

The interface of a smart contract, also just called a contract, can be explicitly defined with an [ABI declaration](#the-abi-declaration) or implicitly with an [impl Self](#impl-self-contracts) item for the special type "Contract". See [this contract](../examples/wallet_smart_contract.md) for an example on using ABIs.

## Syntax of a Smart Contract

As with any Sway program, the program starts with a declaration of what [program type](./index.md) it is. When using ABIs, a contract must either define or import an [ABI declaration](#the-abi-declaration) and implement it.

<!-- This section should explain best practices for ABIs -->
<!-- ABI:example:start -->
It is considered good practice to define your ABI in a separate library and import it into your contract. This allows callers of your contract to simply import the ABI directly and use it in their scripts to call your contract.
<!-- ABI:example:end -->

Let's take a look at an ABI declaration in a library:

```sway
library;

// ANCHOR: abi
abi Wallet {
    // ANCHOR: receive_funds
    #[storage(read, write), payable]
    fn receive_funds();
    // ANCHOR_END: receive_funds

    // ANCHOR: send_funds
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
    // ANCHOR_END: send_funds
}
// ANCHOR: abi
```

Let's focus on the ABI declaration and inspect it line-by-line.

### The ABI Declaration

```sway
library;

abi Wallet {
    // ANCHOR: receive_funds
    #[storage(read, write), payable]
    fn receive_funds();
    // ANCHOR_END: receive_funds

    // ANCHOR: send_funds
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
    // ANCHOR_END: send_funds
}
```

---

In the first line, `abi Wallet {`, we declare the name of this _Application Binary Interface_, or ABI. We are naming this ABI `Wallet`. To import this ABI into either a script for calling or a contract for implementing, you would use

```sway
use wallet_abi::Wallet;
```

---

In the second line,

```sway
    #[storage(read, write), payable]
    fn receive_funds();
```

we are declaring an ABI method called `receive_funds` which, when called, should receive funds into this wallet. Note that we are simply defining an interface here, so there is no _function body_ or implementation of the function. We only need to define the interface itself. In this way, ABI declarations are similar to [trait declarations](../advanced/traits.md). This particular ABI method does not take any parameters.

---

In the third line,

```sway
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
```

we are declaring another ABI method, this time called `send_funds`. It takes two parameters: the amount to send, and the address to send the funds to.

>**Note**: The ABI methods `receive_funds` and `send_funds` also require the annotation `#[storage(read, write)]` because their implementations require reading and writing a storage variable that keeps track of the wallet balance, as we will see shortly. Refer to [Purity](
../blockchain-development/purity.md#Purity) for more information on storage annotations.

## Implementing an ABI for a Smart Contract

Now that we've discussed how to define the interface, let's discuss how to use it. We will start by implementing the above ABI for a specific contract.

Implementing an ABI for a contract is accomplished with `impl <ABI name> for Contract` syntax. The `for Contract` syntax can only be used to implement an ABI for a contract; implementing methods for a struct should use `impl Foo` syntax.

```sway
impl Wallet for Contract {
    #[storage(read, write), payable]
    fn receive_funds() {
        if msg_asset_id() == AssetId::base() {
            // If we received the base asset then keep track of the balance.
            // Otherwise, we're receiving other native assets and don't care
            // about our balance of coins.
            storage.balance.write(storage.balance.read() + msg_amount());
        }
    }

    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address) {
        let sender = msg_sender().unwrap();
        match sender {
            Identity::Address(addr) => assert(addr == OWNER_ADDRESS),
            _ => revert(0),
        };

        let current_balance = storage.balance.read();
        assert(current_balance >= amount_to_send);

        storage.balance.write(current_balance - amount_to_send);

        // Note: `transfer()` is not a call and thus not an
        // interaction. Regardless, this code conforms to
        // checks-effects-interactions to avoid re-entrancy.
        transfer(
            Identity::Address(recipient_address),
            AssetId::base(),
            amount_to_send,
        );
    }
}
```

You may notice once again the similarities between [traits](../advanced/traits.md) and ABIs. And, indeed, as a bonus, you can define methods in addition to the interface surface of an ABI, just like a trait. These pre-implemented ABI methods automatically become available as part of the contract interface that implements the corresponding ABI.

Note that the above implementation of the ABI follows the [Checks, Effects, Interactions](https://docs.soliditylang.org/en/v0.6.11/security-considerations.html#re-entrancy) pattern.

## The `ContractId` type

Contracts have an associated `ContractId` type in Sway. The `ContractId` type allows for Sway programs to refer to contracts in the Sway language. Please refer to the [ContractId](../basics/blockchain_types.md#contractid-type) section of the book for more information on `ContractId`s.

## Calling a Smart Contract from a Script

>**Note**: In most cases, calling a contract should be done from the [Rust SDK](../testing/testing-with-rust.md) or the [TypeScript SDK](https://docs.fuel.network/docs/fuels-ts) which provide a more ergonomic UI for interacting with a contract. However, there are situations where manually writing a script to call a contract is required.

Now that we have defined our interface and implemented it for our contract, we need to know how to actually _call_ our contract. Let's take a look at a contract call:

```sway
script;

use wallet_abi::Wallet;

fn main() {
    let contract_address = 0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b;
    let caller = abi(Wallet, contract_address);
    let amount_to_send = 200;
    let recipient_address = Address::from(0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b);
    caller
        .send_funds {
            gas: 10000,
            coins: 0,
            asset_id: b256::zero(),
        }(amount_to_send, recipient_address);
}

```

The main new concept is the `abi cast`: `abi(AbiName, contract_address)`. This returns a `ContractCaller` type which can be used to call contracts. The methods of the ABI become the methods available on this contract caller: `send_funds` and `receive_funds`. We then directly call the contract ABI method as if it was just a regular method. You also have the option of specifying the following special parameters inside curly braces right before the main list of parameters:

1. `gas`: a `u64` that represents the gas being forwarded to the contract when it is called.
2. `coins`: a `u64` that represents how many coins are being forwarded with this call.
3. `asset_id`: a `b256` that represents the ID of the _asset type_ of the coins being forwarded.

Each special parameter is optional and assumes a default value when skipped:

1. The default value for `gas` is the context gas (i.e. the content of the special register `$cgas`). Refer to the [FuelVM specifications](https://fuellabs.github.io/fuel-specs/master/vm) for more information about context gas.
2. The default value for `coins` is 0.
3. The default value for `asset_id` is `b256::zero()`.

## Impl Self Contracts

In some cases, it may be more convenient to avoid declaring an ABI and implement the contract directly, as shown in the example below.

Notice how there is no ABI specified in the `impl` item. In this case, the compiler will automatically create an ABI named as the package containing this `impl Contract` item, and will include each function in the ABI.

```sway
impl Contract {
    #[storage(read, write), payable]
    fn receive_funds() {
        if msg_asset_id() == AssetId::base() {
            // If we received the base asset then keep track of the balance.
            // Otherwise, we're receiving other native assets and don't care
            // about our balance of coins.
            storage.balance.write(storage.balance.read() + msg_amount());
        }
    }

    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address) {
        let sender = msg_sender().unwrap();
        match sender {
            Identity::Address(addr) => assert(addr == OWNER_ADDRESS),
            _ => revert(0),
        };

        let current_balance = storage.balance.read();
        assert(current_balance >= amount_to_send);

        storage.balance.write(current_balance - amount_to_send);

        // Note: `transfer()` is not a call and thus not an
        // interaction. Regardless, this code conforms to
        // checks-effects-interactions to avoid re-entrancy.
        transfer(
            Identity::Address(recipient_address),
            AssetId::base(),
            amount_to_send,
        );
    }
}
```

Without an ABI, there is no way for scripts and other contracts to use `abi(...)` and call this contract, but it can still be tested and called using any of available SDKs, as any other contract.

The ABI name will be the "upper camel case" version of the package name containing the "impl Contract" item. `CONTRACT_ID` is a compiler special constant that references the contract being implemented in this file.

```sway
#[test]
fn tests() {
    let w = abi(WalletSmartContractSelfImpl, CONTRACT_ID);
    w.receive_funds();
}
```


---

### File: docs/nightly/sway/docs/book/src/testing/index.md

# Testing

Sway aims to provide facilities for both unit testing and integration testing.

**Unit testing** refers to "in-language" test functions annotated with `#[test]`.

**Integration testing** refers to the testing of your Sway project's integration
within some wider application. You can add integration testing to your Sway+Rust
projects today using the cargo generate template and Rust SDK.

- [Unit Testing](./unit-testing.md)
- [Testing with Rust](./testing-with-rust.md)


---

### File: docs/nightly/sway/docs/book/src/testing/testing-with-rust.md

# Testing with Rust

A common use of Sway is for writing contracts or scripts that exist as part of a
wider Rust application. In order to test the interaction between our Sway code
and our Rust code we can add integration testing.

## Adding Rust Integration Testing

To add Rust integration testing to a Forc project we can use [the `sway-test-rs`
cargo generate
template](https://github.com/FuelLabs/sway/tree/master/templates/sway-test-rs).
This template makes it easier for Sway developers to add the boilerplate required when
setting up their Rust integration testing.

Let's add a Rust integration test to [the fresh project we created in the introduction](../introduction/forc_project.md).

### 1. Enter the project

To recap, here's what our empty project looks like:

```console
$ cd my-fuel-project
$ tree .
├── Forc.toml
└── src
    └── main.sw
```

### 2. Install `cargo generate`

We're going to add a Rust integration test harness using a cargo generate
template. Let's make sure we have the `cargo generate` command installed!

```console
cargo install cargo-generate
```

> _**Note**: You can learn more about cargo generate by visiting the
> [cargo-generate repository](https://github.com/cargo-generate/cargo-generate)._

### 3. Generate the test harness

Let's generate the default test harness with the following:

```console
cargo generate --init fuellabs/sway templates/sway-test-rs --name my-fuel-project --force
```

`--force` forces your `--name` input to retain your desired casing for the `{{project-name}}`
placeholder in the template. Otherwise, `cargo-generate` automatically converts it to `kebab-case`.
With `--force`, this means that both `my_fuel_project` and `my-fuel-project` are valid project names,
depending on your needs.

> _**Note**: `templates/sway-test-rs` can be replaced with `templates/sway-script-test-rs` or `templates/sway-predicate-test-rs` to generate a test
> harness for scripts and predicates respectively.

If all goes well, the output should look as follows:

```console
⚠️   Favorite `fuellabs/sway` not found in config, using it as a git repository: https://github.com/fuellabs/sway
🤷   Project Name : my-fuel-project
🔧   Destination: /home/user/path/to/my-fuel-project ...
🔧   Generating template ...
[1/3]   Done: Cargo.toml
[2/3]   Done: tests/harness.rs
[3/3]   Done: tests
🔧   Moving generated files into: `/home/user/path/to/my-fuel-project`...
✨   Done! New project created /home/user/path/to/my-fuel-project
```

Let's have a look at the result:

```console
$ tree .
├── Cargo.toml
├── Forc.toml
├── build.rs
├── src
│   └── main.sw
└── tests
    └── harness.rs
```

We have three new files!

- The `Cargo.toml` is the manifest for our new test harness and specifies the
  required dependencies including `fuels` the Fuel Rust SDK.
- The `tests/harness.rs` contains some boilerplate test code to get us started,
  though doesn't call any contract methods just yet.
- The `build.rs` is a build script that compiles the Sway project with `forc build`
  whenever `cargo test` is run.

### 4. Build the forc project

Before running the tests, we need to build our contract so that the necessary
ABI, storage and bytecode artifacts are available. We can do so with `forc build`:

```console
$ forc build
  Creating a new `Forc.lock` file. (Cause: lock file did not exist)
    Adding std git+https://github.com/fuellabs/sway?tag=v0.24.5#e695606d8884a18664f6231681333a784e623bc9
   Created new lock file at /home/user/path/to/my-fuel-project/Forc.lock
  Compiled library "std".
  Compiled contract "my-fuel-project".
  Bytecode size is 60 bytes.
```

At this point, our project should look like the following:

```console
$ tree
├── Cargo.toml
├── Forc.lock
├── Forc.toml
├── build.rs
├── out
│   └── debug
│       ├── my-fuel-project-abi.json
│       ├── my-fuel-project.bin
│       └── my-fuel-project-storage_slots.json
├── src
│   └── main.sw
└── tests
    └── harness.rs
```

We now have an `out` directory with our required JSON files!

> _**Note**: This step may no longer be required in the future as we plan to
> enable the integration testing to automatically build the artifacts as
> necessary so that files like the ABI JSON are always up to date._

### 5. Build and run the tests

Now we're ready to build and run the default integration test.

```console
$ cargo test
    Updating crates.io index
   Compiling version_check v0.9.4
   Compiling proc-macro2 v1.0.46
   Compiling quote v1.0.21
   ...
   Compiling fuels v0.24.0
   Compiling my-fuel-project v0.1.0 (/home/user/path/to/my-fuel-project)
    Finished test [unoptimized + debuginfo] target(s) in 1m 03s
     Running tests/harness.rs (target/debug/deps/integration_tests-373971ac377845f7)

running 1 test
test can_get_contract_id ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.36s
```

> _**Note**: The first time we run `cargo test`, cargo will spend some time
> fetching and building the dependencies for Fuel's Rust SDK. This might take a
> while, but only the first time!_

If all went well, we should see some output that looks like the above!

## Writing Tests

Now that we've learned how to setup Rust integration testing in our project,
let's try to write some of our own tests!

First, let's update our contract code with a simple counter example:

```sway
contract;

abi TestContract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64;

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
}

impl TestContract for Contract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64 {
        storage.counter.write(value);
        value
    }

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64 {
        let incremented = storage.counter.read() + amount;
        storage.counter.write(incremented);
        incremented
    }
}

```

To test our `initialize_counter` and `increment_counter` contract methods from
the Rust test harness, we could update our `tests/harness.rs` file with the
following:

<!--TODO add test here once examples are tested-->

```rust,ignore
use fuels::{prelude::*, types::ContractId};

// Load abi from json
abigen!(Contract(
    name = "MyContract",
    abi = "out/debug/my-fuel-project-abi.json"
));

async fn get_contract_instance() -> (MyContract<WalletUnlocked>, ContractId) {
    // Launch a local network and deploy the contract
    let mut wallets = launch_custom_provider_and_get_wallets(
        WalletsConfig::new(
            Some(1),             /* Single wallet */
            Some(1),             /* Single coin (UTXO) */
            Some(1_000_000_000), /* Amount per coin */
        ),
        None,
        None,
    )
    .await
    .unwrap();
    let wallet = wallets.pop().unwrap();

    let id = Contract::load_from(
        "./out/debug/my-fuel-project.bin",
        LoadConfiguration::default().set_storage_configuration(
            StorageConfiguration::load_from(
                "./out/debug/my-fuel-project-storage_slots.json",
            )
            .unwrap(),
        ),
    )
    .unwrap()
    .deploy(&wallet, TxPolicies::default())
    .await
    .unwrap();

    let instance = MyContract::new(id.clone(), wallet);

    (instance, id.into())
}

#[tokio::test]
async fn initialize_and_increment() {
    let (contract_instance, _id) = get_contract_instance().await;
    // Now you have an instance of your contract you can use to test each function

    let result = contract_instance
        .methods()
        .initialize_counter(42)
        .call()
        .await
        .unwrap();

    assert_eq!(42, result.value);

    // Call `increment_counter()` method in our deployed contract.
    let result = contract_instance
        .methods()
        .increment_counter(10)
        .call()
        .await
        .unwrap();

    assert_eq!(52, result.value);
}
```

Let's build our project once more and run the test:

```console
forc build
```

```console
$ cargo test
   Compiling my-fuel-project v0.1.0 (/home/mindtree/programming/sway/my-fuel-project)
    Finished test [unoptimized + debuginfo] target(s) in 11.61s
     Running tests/harness.rs (target/debug/deps/integration_tests-373971ac377845f7)

running 1 test
test initialize_and_increment ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.25s
```

When cargo runs our test, our test uses the SDK to spin up a local in-memory
Fuel network, deploy our contract to it, and call the contract methods via the
ABI.

You can add as many functions decorated with `#[tokio::test]` as you like, and
`cargo test` will automatically test each of them!


---

### File: docs/nightly/sway/docs/book/src/testing/testing_with_forc_call.md

# Forc Call

`forc-call` is a command-line tool for interacting with deployed Fuel contracts. It allows you to make contract calls, query contract state, and interact with any deployed contract on the Fuel network - all from your command line!

The `forc call` command is part of the Forc toolchain and is installed alongside other Forc tools.

## Getting Started

Here are a few examples of what you can do with `forc call`:

```sway
contract;

abi ContractABI {
  fn add(a: u64, b: u64) -> u64;
}

impl ContractABI for Contract {
  fn add(a: u64, b: u64) -> u64 {
    a + b
  }
}
```

### List callable functions of a contract given it's ABI file

```bash
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
  --abi ./out/debug/counter-contract-abi.json \
  --list-functions
```

Output:

```log
Available functions in contract: 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d

add(a: u64, b: u64) -> u64
  forc call \
    --abi ./out/debug/counter-contract-abi.json \
    0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
    add "0" "0"
```

### List functions from multiple contracts with additional ABIs

```bash
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
  --abi ./out/debug/counter-contract-abi.json \
  --contract-abi 0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07:./token-abi.json \
  --contract-abi 0x1234567890abcdef:https://example.com/pool-abi.json \
  --list-functions
```

### Call a simple addition function on a deployed contract (in dry-run mode)

```bash
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
  --abi ./out/debug/counter-contract-abi.json \
  add 1 2
```

### Call a contract with labeled addresses for better trace readability

```bash
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
  --abi ./out/debug/counter-contract-abi.json \
  transfer 0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07 \
  --label 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d:MainContract \
  --label 0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07:TokenContract \
  -vvv
```

### Directly send funds to an address

```bash
forc call 0x2c7Fd852EF2BaE281e90ccaDf18510701989469f7fc4b042F779b58a39919Eec --amount 2 --mode=live
```

### Query the owner of a deployed [DEX contract](https://github.com/mira-amm/mira-v1-core) on testnet

```bash
forc call \
  --testnet \
  --abi https://raw.githubusercontent.com/mira-amm/mira-v1-periphery/refs/heads/main/fixtures/mira-amm/mira_amm_contract-abi.json \
  0xd5a716d967a9137222219657d7877bd8c79c64e1edb5de9f2901c98ebe74da80 \
  owner
```

## Usage

Forc call has **3** usage modes:

### List functions

Syntax for `forc call` for listing supported functions from the ABI - with example command to perform call operation:

```bash
forc call --abi <ABI-PATH/URL> <CONTRACT_ID> --list-functions
```

You can also list functions from multiple contracts by providing additional contract ABIs:

```bash
forc call --abi <MAIN-ABI-PATH/URL> <MAIN-CONTRACT_ID> \
  --contract-abi <CONTRACT_ID>:<ABI-PATH/URL> \
  --contract-abi <ANOTHER-CONTRACT_ID>:<ABI-PATH/URL> \
  --list-functions
```

Where the following arguments are required:

- `ABI-PATH/URL` is the path or URL to the contract's JSON ABI file
- `CONTRACT_ID` is the ID of the deployed contract you want to interact with
- `--contract-abi` (optional) allows you to specify additional contracts and their ABIs to list functions from multiple contracts at once

### Transfer assets

Syntax for `forc call` for transferring assets:

```bash
forc call <RECEIVER_ADDRESS> --amount <AMOUNT> --mode=live
```

Where the following arguments are required:

- `RECEIVER_ADDRESS` is address of the receiver (identity or contract).
- `AMOUNT` is the amount of assets to transfer.

Note: only live mode `--mode=live` is supported; transfers cannot be simulated.

### Call contracts

Syntax for `forc call` for contract calls:

```bash
forc call [OPTIONS] --abi <ABI-PATH/URL> <CONTRACT_ID> <SELECTOR> [ARGS]...
```

Where the following arguments are required:

- `CONTRACT_ID` is the ID of the deployed contract you want to interact with
- `ABI-PATH/URL` is the path or URL to the contract's JSON ABI file
- `SELECTOR` is the function name (selector) you want to call
- `ARGS` are the arguments to pass to the function

## Type Encoding

When passing arguments to contract functions, values are encoded according to their Sway types.
Here's how to format different types:

| Types                                         | Example input                                                        | Notes                                                                                          |
|-----------------------------------------------|----------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| bool                                          | `true` or `false`                                                    |                                                                                                |
| u8, u16, u32, u64, u128, u256                 | `42`                                                                 |                                                                                                |
| b256                                          | `0x0000000000000000000000000000000000000000000000000000000000000042` or `0000000000000000000000000000000000000000000000000000000000000042` | `0x` prefix is optional |
| bytes, RawSlice                               | `0x42` or `42`                                                       | `0x` prefix is optional                                                                                               |
| String, StringSlice, StringArray (Fixed-size) | `"abc"`                                                              |                                                                                                |
| Tuple                                         | `(42, true)`                                                         | The types in tuple can be different                                                                                               |
| Array (Fixed-size), Vector (Dynamic)          | `[42, 128]`                                                          | The types in array or vector must be the same; i.e. you cannot have `[42, true]`              |
| Struct                                        | `{42, 128}`                                                          | Since structs are packed encoded, the attribute names are not encoded; i.e. `{42, 128}`; this could represent the following `struct Polygon { x: u64, y: u64 }` |
| Enum                                          | `(Active: true)` or `(1: true)`       | Enums are key-val pairs with keys as being variant name (case-sensitive) or variant index (starting from 0) and values as being the variant value; this could represent the following `enum MyEnum { Inactive, Active(bool) }` |

## ABI Support

The ABI (Application Binary Interface) can be provided in two ways.

### Local file

```bash
forc call <CONTRACT_ID> --abi ./path/to/abi.json <FUNCTION> [ARGS...]
```

### Remote ABI file/URL

```bash
forc call <CONTRACT_ID> --abi https://example.com/abi.json <FUNCTION> [ARGS...]
```

## Network Configuration

```bash
forc call --node-url http://127.0.0.1:4000 ...
# or
forc call --target local ...
```

## Advanced Usage

### Using Wallets

```sh
# utilising the forc-wallet
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --wallet
```

```sh
# with an explicit signing key
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --signing-key <KEY>
```

### Asset Transfers

```sh
# Native asset transfer
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --amount 100 --live
```

```sh
# Custom asset transfer
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> \
    --amount 100 \
    --asset-id 0x1234... \
    --live
```

### Gas Configuration

```sh
# Set gas price
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --gas-price 1

# Forward gas to contract
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --gas-forwarded 1000

# Set maximum fee
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --max-fee 5000
```

### Transaction Tracing

When you need to debug contract interactions or understand the execution flow, `forc call` provides detailed transaction traces with verbosity level 2 or higher (`-vv` or `-v=2`).

```sh
# Enable transaction tracing
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> -vv
```

The transaction trace provides a hierarchical view of all contract calls, showing:

- Gas consumption for each call (`[gas_amount]`)
- Contract addresses being called
- Return values and data
- Emitted logs and events
- Nested contract calls with proper indentation
- Overall transaction result and gas usage

#### Enhancing Traces with Labels

For better readability, you can label contract addresses in transaction traces using the `--label` flag:

```sh
# Add human-readable labels to contract addresses
forc call <CONTRACT_ID> \
  --abi <PATH> \
  <FUNCTION> \
  --label <CONTRACT_ID>:MainContract \
  --label <OTHER_CONTRACT_ID>:TokenContract \
  -vv
```

**Without labels:**

```log
├─ [8793] 0x2af09151f8276611ba65f14650970657bc42c1503d6502ffbb4d085ec37065dd::transfer(100, 0x123)
│    └─ ← ()
```

**With labels:**

```log
├─ [8793] TokenContract::transfer(100, 0x123)
│    └─ ← ()
```

#### Improving Trace Decoding with Additional ABIs

For complex multi-contract interactions, you can provide additional contract ABIs to improve function signature and return data decoding:

```sh
# Add additional contract ABIs for better trace decoding
forc call <CONTRACT_ID> \
  --abi <MAIN_ABI_PATH> \
  <FUNCTION> \
  --contract-abi <OTHER_CONTRACT_ID>:./external-abi.json \
  --contract-abi <THIRD_CONTRACT_ID>:https://example.com/abi.json \
  -vv
```

This helps decode:

- Function names
- Function parameters in readable format
- Return values in structured format instead of raw hex

#### Example Transaction Trace Output

```bash
forc call 0x9275a76531bce733cfafdbcb6727ea533ebbdc358d685152169b3c4eaa47b965 \
  --abi ./demo/demo-caller-abi.json \
  call_increment_count \
  --label 0x9275a76531bce733cfafdbcb6727ea533ebbdc358d685152169b3c4eaa47b965:DemoCaller \
  --label 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42:Counter \
  --contract-abi 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42:./counter-abi.json \
  -vv
```

**Output:**

```log
Traces:
  [Script]
    ├─ [124116] DemoCaller::call_increment_count()
    │    ├─ [111500] Counter::increment()
    │    │    └─ ← ()
    │    ├─ emit AsciiString { data: "incremented count" }
    │    ├─ [86284] Counter::get_count()
    │    │    └─ ← 0x0000000000000002
    │    ├─ emit 2
    │    ├─ emit AsciiString { data: "done" }
    │    ├─ [72699] Counter::increment()
    │    │    └─ ← ()
    │    ├─ [48287] Counter::get_count()
    │    │    └─ ← 0x0000000000000003
    │    └─ ← 0x0000000000000003
    └─ ← [Return] val: 1
  [ScriptResult] result: Success, gas_used: 89279

Transaction successfully executed.
Gas used: 160676
```

#### Understanding the Trace Format

- `[Script]` - The root transaction script
- `├─ [gas_amount] ContractLabel::function_name(args)` - A contract call with gas consumption and decoded function info
- `│    └─ ← value` - Return value from the contract call
- `emit data` - Log/event emitted by the contract
- Indentation shows the call hierarchy (nested calls are indented further)
- `[ScriptResult]` - Final transaction result with gas used by the script
- `Gas used: <gas_used>` - Total gas used by the transaction

This tracing feature is particularly useful for:

- Debugging failed transactions
- Understanding gas consumption patterns
- Analyzing complex multi-contract interactions
- Verifying expected contract behavior

### Common Use Cases

#### Contract State Queries

```sh
# Read contract state
forc call <CONTRACT_ID> --abi <PATH> get_balance

# Query with parameters
forc call <CONTRACT_ID> --abi <PATH> get_user_info 0x1234...

# Update contract state
forc call <CONTRACT_ID> --abi <PATH> update_state 42 --live
```

#### Token Operations

```sh
# Transfer assets/tokens to an address
forc call <ADDRESS> --amount 100 --live
```

#### Multi-Contract Debugging

```sh
# Debug complex multi-contract interactions
forc call <MAIN_CONTRACT_ID> \
  --abi <MAIN_ABI_PATH> \
  complex_operation \
  --label <MAIN_CONTRACT_ID>:MainContract \
  --label <TOKEN_CONTRACT_ID>:TokenContract \
  --label <POOL_CONTRACT_ID>:LiquidityPool \
  --contract-abi <TOKEN_CONTRACT_ID>:./token-abi.json \
  --contract-abi <POOL_CONTRACT_ID>:./pool-abi.json \
  -vv
```

### CLI Parameters Reference

#### Trace Enhancement Options

- `--label <contract_id>:<label>` - Add human-readable labels for contract addresses in traces
  - Can be used multiple times
  - Contract ID can include or omit `0x` prefix
  - Example: `--label 0x123:MainContract`

- `--contract-abi <contract_id>:<abi_path>` - Specify additional contract ABIs for better trace decoding
  - Can be used multiple times
  - Supports both local files and URLs
  - Contract ID can include or omit `0x` prefix
  - Example: `--contract-abi 0x123:./abi.json` or `--contract-abi 0x456:https://example.com/abi.json`

- `-v, -vv, -vvv` - Verbosity levels for trace output
  - `-v`: Show decoded logs
  - `-vv`: Additionally show transaction traces
  - `-vvv`: Additionally show receipts and script JSON

## Tips and Tricks

- Use `--mode simulate` to estimate gas costs before making live transactions
- External contracts are automatically detected (via internal simulations), but can be manually specified with `--external-contracts`
- For complex parameter types (tuples, structs, enums), refer to the parameter types table above
- Always verify contract addresses and ABIs before making live calls
- Use environment variables for sensitive data like signing keys: `SIGNING_KEY=<key>`
- **Use labels for better trace readability**: Add `--label` flags to replace long contract addresses with meaningful names in traces
- **Provide additional ABIs for multi-contract calls**: Use `--contract-abi` to decode function calls and return values from external contracts
- **Combine labels and ABIs**: Use both together for the most readable and informative transaction traces

## Troubleshooting

### Common issues and solutions

- **ABI Mismatch**:
  - Ensure the ABI matches the deployed contract
  - Verify function selectors match exactly
  - Check that additional contract ABIs match their respective contracts

- **Parameter Type Errors**:
  - Check parameter formats in the types table
  - Ensure correct number of parameters

- **Network Issues**:
  - Verify node connection
  - Check network selection (testnet/mainnet)

- **Transaction Failures**:
  - Use simulation mode to debug
  - Check gas settings
  - Verify wallet has sufficient balance

- **Trace Decoding Issues**:
  - Ensure contract ABIs are correctly specified
  - Verify contract addresses in labels match deployed contracts
  - Check that ABI files are accessible (for both local files and URLs)


---

### File: docs/nightly/sway/docs/book/src/testing/unit-testing.md

# Unit Testing

<!-- This section should explain unit testing in Sway -->
<!-- unit_test:example:start -->
Forc provides built-in support for building and executing tests for a package.

Tests are written as free functions with the `#[test]` attribute.
<!-- unit_test:example:end -->

For example:

```sway
#[test]
fn test_meaning_of_life() {
    assert(6 * 7 == 42);
}
```

Each test function is ran as if it were the entry point for a
[script](../sway-program-types/scripts.md). Tests "pass" if they return
successfully, and "fail" if they revert or vice versa while [testing failure](#testing-failure).

If the project has failing tests `forc test` will exit with exit status `101`.

## Building and Running Tests

We can build and execute all tests within a package with the following:

```console
forc test
```

The output should look similar to this:

```console
  Compiled library "std".
  Compiled library "lib_single_test".
  Bytecode size is 92 bytes.
   Running 1 tests
      test test_meaning_of_life ... ok (170.652µs)
   Result: OK. 1 passed. 0 failed. Finished in 1.564996ms.
```

Visit the [`forc test`](../forc/commands/forc_test.md) command reference to find
the options available for `forc test`.

## Testing Failure

<!-- This section should explain support for failing unit tests in Sway -->
<!-- unit_test_fail:example:start -->
Forc supports testing failing cases for test functions declared with `#[test(should_revert)]`.
<!-- unit_test_fail:example:end -->

For example:

```sway
#[test(should_revert)]
fn test_meaning_of_life() {
    assert_eq(6 * 6, 42);
}
```

It is also possible to specify an expected revert code, like the following example.

```sway
#[test(should_revert = "18446744073709486084")]
fn test_meaning_of_life() {
    assert_eq(6 * 6, 42);
}
```

Tests with `#[test(should_revert)]` are considered to be passing if they are reverting.

Available information about reverts is not shown by default in passing tests that have `should_revert`. To see revert information, use the `--reverts` flag, `forc test --reverts`:

```console
  test test_meaning_of_life ... ok (52.432µs, 508 gas)
       revert code: ffffffffffff0003
        └─ error message: Failing call to `std::assert::assert_eq`
```

## Calling Contracts

Unit tests can call contract functions. An example for such calls can be seen below.

```sway
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

To test the `test_function()`, a unit test like the following can be written.

```sway
#[test]
fn test_success() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == true);
}
```

It is also possible to test failure with contract calls as well.

```sway
#[test(should_revert)]
fn test_fail() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == false);
}
```

<!-- This section should explain how the `CONTRACT_ID` variable works in Sway unit tests -->
<!-- contract_id:example:start -->
> **Note:** When running `forc test`, your contract will be built twice: first *without* unit tests in order to determine the contract's ID, then a second time *with* unit tests with the `CONTRACT_ID` provided to their namespace. This `CONTRACT_ID` can be used with the `abi` cast to enable contract calls within unit tests.
<!-- contract_id:example:end -->

Unit tests can call methods of external contracts if those contracts are added as contract dependencies, i.e. in the [`contract-dependencies`](../forc/manifest_reference.md#the-contract-dependencies-section) section of the manifest file. An example of such calls is shown below:

```sway
contract;

abi CallerContract {
    fn test_false() -> bool;
}

impl CallerContract for Contract {
    fn test_false() -> bool {
        false
    }
}

abi CalleeContract {
    fn test_true() -> bool;
}

#[test]
fn test_multi_contract_calls() {
    let caller = abi(CallerContract, CONTRACT_ID);
    let callee = abi(CalleeContract, callee::CONTRACT_ID);

    let should_be_false = caller.test_false();
    let should_be_true = callee.test_true();
    assert(!should_be_false);
    assert(should_be_true);
}

```

Example `Forc.toml` for contract above:

```toml
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
name = "caller"

[dependencies]
std = { path = "../../../sway-lib-std/" }

[contract-dependencies]
callee = { path = "../callee" }

```

## Running Tests in Parallel or Serially

<!-- This section should explain how unit tests do not share storage -->
<!-- storage:example:start -->
By default, all unit tests in your project are run in parallel. Note that this does not lead to any data races in storage because each unit test has its own storage space that is not shared by any other unit test.
<!-- storage:example:end -->

By default, `forc test` will use all the available threads in your system. To request that a specific number of threads be used, the flag `--test-threads <val>` can be provided to `forc test`.

```console
forc test --test-threads 1
```

## Logs Inside Tests

<!-- This section should explain how log decoding works with Sway unit tests -->
<!-- unit_test_log::example::start -->
Forc has some capacity to help decode logs returned from the unit tests. You can use this feature to decode raw logs into a human readable format.

```sway
script;

fn main() {}

#[test]
fn test_fn() {
    let a = 10;
    log(a);
    let b = 30;
    log(b);
    assert_eq(a, 10);
    assert_eq(b, 30);
}
```

The above example shows a passing test that is logging two different variables, `a` and `b`, and their values are `10` and `30`, respectively. Logs are silenced by default in passing tests, and can be enabled using the `--logs` flag, `forc test --logs`:

```console
     Running 1 test, filtered 0 tests
      test test_fn ... ok (58.842µs, 0 gas)
Decoded log value: 10, log rb: 1515152261580153489
Decoded log value: 30, log rb: 1515152261580153489
```

The `--logs` flag prints decoded log values. If you want to see pretty-printed raw log receipts you can use the `--raw-logs --pretty` flags, `forc test --raw-logs --pretty`:

```console
      test test_fn ... ok (54.042µs, 0 gas)
Raw logs:
[
  {
    "LogData": {
      "data": "000000000000000a",
      "digest": "8d85f8467240628a94819b26bee26e3a9b2804334c63482deacec8d64ab4e1e7",
      "id": "0000000000000000000000000000000000000000000000000000000000000000",
      "is": 10368,
      "len": 8,
      "pc": 11212,
      "ptr": 67107840,
      "ra": 0,
      "rb": 1515152261580153489
    }
  },
  {
    "LogData": {
      "data": "000000000000001e",
      "digest": "48a97e421546f8d4cae1cf88c51a459a8c10a88442eed63643dd263cef880c1c",
      "id": "0000000000000000000000000000000000000000000000000000000000000000",
      "is": 10368,
      "len": 8,
      "pc": 11212,
      "ptr": 67106816,
      "ra": 0,
      "rb": 1515152261580153489
    }
  }
]
```

The `--logs` and `--raw-logs` flags can be combined to print both the decoded and raw logs.
<!-- unit_test_log::example::end -->


---

### File: docs/nightly/verified-addresses/docs/src/assets.md


# Verified Assets

## Using this section

You can find the current list of verified assets maintained by Fuel here: [verified-assets.json](https://verified-assets.fuel.network/assets.json)

Projects are welcome to use this information, but please note that it is provided at your own risk.

Additionally, you can download the latest asset information and icons in a single archive. This is useful if you want to locally cache the list or include it in a release pipeline for your tools and libraries: [verified-assets.zip](https://github.com/FuelLabs/verified-assets/)

For more information, please visit the verified assets repository [here](https://github.com/FuelLabs/verified-assets/).

## Ethereum Sepolia Testnet

| Name | Address | Decimals |
|------|---------|----------|
| `Ethereum` |  | `18` |
| `Fuel` | [`0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550`](https://sepolia.etherscan.io/address/0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550) | `9` |
| `USDC` | [`0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238`](https://sepolia.etherscan.io/address/0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238) | `6` |
| `USDe` | [`0xc6387efad0f184a90b34f397c3d6fd63135ef790`](https://sepolia.etherscan.io/address/0xc6387efad0f184a90b34f397c3d6fd63135ef790) | `18` |
| `sUSDe` | [`0xb8f4f4eafc1d2a3c0a4d519bbf1114c311cc9b1b`](https://sepolia.etherscan.io/address/0xb8f4f4eafc1d2a3c0a4d519bbf1114c311cc9b1b) | `18` |
| `wstETH` | [`0xB82381A3fBD3FaFA77B3a7bE693342618240067b`](https://sepolia.etherscan.io/address/0xB82381A3fBD3FaFA77B3a7bE693342618240067b) | `18` |

## Ethereum Foundry

| Name | Address | Decimals |
|------|---------|----------|
| `Ethereum` |  | `18` |

## Ethereum L1

| Name | Address | Decimals |
|------|---------|----------|
| `Ethereum` |  | `18` |
| `Fuel` | [`0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c`](https://etherscan.io/address/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c) | `9` |
| `WETH` | [`0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`](https://etherscan.io/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) | `18` |
| `weETH` | [`0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee`](https://etherscan.io/address/0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee) | `18` |
| `rsETH` | [`0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7`](https://etherscan.io/address/0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7) | `18` |
| `rETH` | [`0xae78736cd615f374d3085123a210448e74fc6393`](https://etherscan.io/address/0xae78736cd615f374d3085123a210448e74fc6393) | `18` |
| `wbETH` | [`0xa2E3356610840701BDf5611a53974510Ae27E2e1`](https://etherscan.io/address/0xa2E3356610840701BDf5611a53974510Ae27E2e1) | `18` |
| `rstETH` | [`0x7a4EffD87C2f3C55CA251080b1343b605f327E3a`](https://etherscan.io/address/0x7a4EffD87C2f3C55CA251080b1343b605f327E3a) | `18` |
| `amphrETH` | [`0x5fD13359Ba15A84B76f7F87568309040176167cd`](https://etherscan.io/address/0x5fD13359Ba15A84B76f7F87568309040176167cd) | `18` |
| `Manta mBTC` | [`0x4041381e947CFD3D483d67a25C6aa9Dc924250c5`](https://etherscan.io/address/0x4041381e947CFD3D483d67a25C6aa9Dc924250c5) | `18` |
| `Manta mETH` | [`0x8CdF550C04Bc9B9F10938368349C9c8051A772b6`](https://etherscan.io/address/0x8CdF550C04Bc9B9F10938368349C9c8051A772b6) | `18` |
| `Manta mUSD` | [`0x3f24E1d7a973867fC2A03fE199E5502514E0e11E`](https://etherscan.io/address/0x3f24E1d7a973867fC2A03fE199E5502514E0e11E) | `18` |
| `pumpBTC` | [`0xf469fbd2abcd6b9de8e169d128226c0fc90a012e`](https://etherscan.io/address/0xf469fbd2abcd6b9de8e169d128226c0fc90a012e) | `8` |
| `FBTC` | [`0xc96de26018a54d51c097160568752c4e3bd6c364`](https://etherscan.io/address/0xc96de26018a54d51c097160568752c4e3bd6c364) | `8` |
| `SolvBTC` | [`0x7a56e1c57c7475ccf742a1832b028f0456652f97`](https://etherscan.io/address/0x7a56e1c57c7475ccf742a1832b028f0456652f97) | `18` |
| `SolvBTC.BBN` | [`0xd9d920aa40f578ab794426f5c90f6c731d159def`](https://etherscan.io/address/0xd9d920aa40f578ab794426f5c90f6c731d159def) | `18` |
| `Mantle mETH` | [`0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa`](https://etherscan.io/address/0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa) | `18` |
| `sDAI` | [`0x83f20f44975d03b1b09e64809b757c47f942beea`](https://etherscan.io/address/0x83f20f44975d03b1b09e64809b757c47f942beea) | `18` |
| `USDT` | [`0xdAC17F958D2ee523a2206206994597C13D831ec7`](https://etherscan.io/address/0xdAC17F958D2ee523a2206206994597C13D831ec7) | `6` |
| `USDC` | [`0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) | `6` |
| `USDe` | [`0x4c9edd5852cd905f086c759e8383e09bff1e68b3`](https://etherscan.io/address/0x4c9edd5852cd905f086c759e8383e09bff1e68b3) | `18` |
| `sUSDe` | [`0x9d39a5de30e57443bff2a8307a4256c8797a3497`](https://etherscan.io/address/0x9d39a5de30e57443bff2a8307a4256c8797a3497) | `18` |
| `rsUSDe` | [`0x82f5104b23FF2FA54C2345F821dAc9369e9E0B26`](https://etherscan.io/address/0x82f5104b23FF2FA54C2345F821dAc9369e9E0B26) | `18` |
| `wstETH` | [`0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0`](https://etherscan.io/address/0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0) | `18` |
| `ezETH` | [`0xbf5495Efe5DB9ce00f80364C8B423567e58d2110`](https://etherscan.io/address/0xbf5495Efe5DB9ce00f80364C8B423567e58d2110) | `18` |
| `pzETH` | [`0x8c9532a60e0e7c6bbd2b2c1303f63ace1c3e9811`](https://etherscan.io/address/0x8c9532a60e0e7c6bbd2b2c1303f63ace1c3e9811) | `18` |
| `Re7LRT` | [`0x84631c0d0081FDe56DeB72F6DE77abBbF6A9f93a`](https://etherscan.io/address/0x84631c0d0081FDe56DeB72F6DE77abBbF6A9f93a) | `18` |
| `steakLRT` | [`0xBEEF69Ac7870777598A04B2bd4771c71212E6aBc`](https://etherscan.io/address/0xBEEF69Ac7870777598A04B2bd4771c71212E6aBc) | `18` |

## Fuel Devnet

| Name | Asset ID | Contract Address | Decimals |
|------|----------|------------------|----------|
| `Ethereum` | `0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07` |  | `9` |

## Fuel Testnet

| Name | Asset ID | Contract Address | Decimals |
|------|----------|------------------|----------|
| `Ethereum` | `0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07` |  | `9` |
| `FUEL` | `0x324d0c35a4299ef88138a656d5272c5a3a9ccde2630ae055dacaf9d13443d53b` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |
| `USDC` | `0xc26c91055de37528492e7e97d91c6f4abe34aae26f2c4d25cff6bfe45b5dc9a9` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `6` |
| `USDe` | `0x86a1beb50c844f5eff9afd21af514a13327c93f76edb89333af862f70040b107` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |
| `sUSDe` | `0xd2886b34454e2e0de47a82d8e6314b26e1e1312519247e8e2ef137672a909aeb` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |
| `wstETH` | `0xb42cd9ddf61898da1701adb3a003b0cf4ca6df7b5fe490ec2c295b1ca43b33c8` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |

## Fuel Mainnet

| Name | Asset ID | Contract Address | Decimals |
|------|----------|------------------|----------|
| `Ethereum` | `0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07` |  | `9` |
| `FUEL` | `0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `stFUEL` | `0x5505d0f58bea82a052bc51d2f67ab82e9735f0a98ca5d064ecb964b8fd30c474` | `0x2181f1b8e00756672515807cab7de10c70a9b472a4a9b1b6ca921435b0a1f49b` | `9` |
| `WETH` | `0xa38a5a8beeb08d95744bc7f58528073f4052b254def59eba20c99c202b5acaa3` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `weETH` | `0x239ed6e12b7ce4089ee245244e3bf906999a6429c2a9a445a1e1faf56914a4ab` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rsETH` | `0xbae80f7fb8aa6b90d9b01ef726ec847cc4f59419c4d5f2ea88fec785d1b0e849` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rETH` | `0xf3f9a0ed0ce8eac5f89d6b83e41b3848212d5b5f56108c54a205bb228ca30c16` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `wbETH` | `0x7843c74bef935e837f2bcf67b5d64ecb46dd53ff86375530b0caf3699e8ffafe` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rstETH` | `0x962792286fbc9b1d5860b4551362a12249362c21594c77abf4b3fe2bbe8d977a` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `amphrETH` | `0x05fc623e57bd7bc1258efa8e4f62b05af5471d73df6f2c2dc11ecc81134c4f36` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Manta mBTC` | `0xaf3111a248ff7a3238cdeea845bb2d43cf3835f1f6b8c9d28360728b55b9ce5b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Manta mETH` | `0xafd219f513317b1750783c6581f55530d6cf189a5863fd18bd1b3ffcec1714b4` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Manta mUSD` | `0x89cb9401e55d49c3269654dd1cdfb0e80e57823a4a7db98ba8fc5953b120fef4` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `pumpBTC` | `0x0aa5eb2bb97ca915288b653a2529355d4dc66de2b37533213f0e4aeee3d3421f` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `8` |
| `FBTC` | `0xb5ecb0a1e08e2abbabf624ffea089df933376855f468ade35c6375b00c33996a` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `8` |
| `SolvBTC` | `0x1186afea9affb88809c210e13e2330b5258c2cef04bb8fff5eff372b7bd3f40f` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `SolvBTC.BBN` | `0x7a4f087c957d30218223c2baaaa365355c9ca81b6ea49004cfb1590a5399216f` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Mantle mETH` | `0x642a5db59ec323c2f846d4d4cf3e58d78aff64accf4f8f6455ba0aa3ef000a3b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `sDAI` | `0x9e46f919fbf978f3cad7cd34cca982d5613af63ff8aab6c379e4faa179552958` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `USDT` | `0xa0265fb5c32f6e8db3197af3c7eb05c48ae373605b8165b6f4a51c5b0ba4812e` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `6` |
| `USDC` | `0x286c479da40dc953bddc3bb4c453b608bba2e0ac483b077bd475174115395e6b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `6` |
| `USDe` | `0xb6133b2ef9f6153eb869125d23dcf20d1e735331b5e41b15a6a7a6cec70e8651` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `sUSDe` | `0xd05563025104fc36496c15c7021ad6b31034b0e89a356f4f818045d1f48808bc` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rsUSDe` | `0x78d4522ec607f6e8efb66ea49439d1ee48623cf763f9688a8eada025def033d9` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `wstETH` | `0x1a7815cc9f75db5c24a5b0814bfb706bb9fe485333e98254015de8f48f84c67b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `ezETH` | `0x91b3559edb2619cde8ffb2aa7b3c3be97efd794ea46700db7092abeee62281b0` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `pzETH` | `0x1493d4ec82124de8f9b625682de69dcccda79e882b89a55a8c737b12de67bd68` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Re7LRT` | `0xf2fc648c23a5db24610a1cf696acc4f0f6d9a7d6028dd9944964ab23f6e35995` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `steakLRT` | `0x4fc8ac9f101df07e2c2dec4a53c8c42c439bdbe5e36ea2d863a61ff60afafc30` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `USDF` | `0x33a6d90877f12c7954cca6d65587c25e9214c7bed2231c188981c7114c1bdb78` |  | `9` |

## Binance Smart Chain

| Name | Address | Decimals |
|------|---------|----------|
| `Fuel` | [`0x5c8daEabc57E9249606D3bD6d1E097eF492eA3C5`](https://bscscan.com/address/0x5c8daEabc57E9249606D3bD6d1E097eF492eA3C5) | `9` |
| `USDT` | [`0x55d398326f99059ff775485246999027b3197955`](https://bscscan.com/address/0x55d398326f99059ff775485246999027b3197955) | `18` |
| `USDC` | [`0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d`](https://bscscan.com/address/0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d) | `18` |


---

### File: docs/nightly/verified-addresses/docs/src/contracts.md

# Verified Contracts

## Ethereum Mainnet

Contract Name | Contract Address
--- | ---
FuelChainState | [`0xf3D20Db1D16A4D0ad2f280A5e594FF3c7790f130`](https://etherscan.io/address/0xf3D20Db1D16A4D0ad2f280A5e594FF3c7790f130)
FuelERC20GatewayV4 | [`0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67`](https://etherscan.io/address/0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67)
FuelMessagePortal | [`0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf`](https://etherscan.io/address/0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf)
The Rig (Liquid Staking) | [`0x9bA9d8781Ac7ce5AdB8B8eC48aAb521d0Db5cd7E`](https://etherscan.io/address/0x9bA9d8781Ac7ce5AdB8B8eC48aAb521d0Db5cd7E)
Fuel Vesting | [`0xde8a1c2d142bc8f3bf3181a2e301a37471508fe1`](https://etherscan.io/address/0xde8a1c2d142bc8f3bf3181a2e301a37471508fe1)
Fuel Migrator | [`0x50Ed39b58f66338B84E67e6Ff9a2bf00725EdFE8`](https://etherscan.io/address/0x50Ed39b58f66338B84E67e6Ff9a2bf00725EdFE8)
Sequencer Interface | [`0xca0c6B264f0F9958Ec186eb2EAa208966187D866`](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866)
Sequencer Proxy | [`0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3`](https://etherscan.io/address/0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3)
Fuel Stream X | [`0x481aeEB9bdFe08f050d22F0b352356691c4B0b59`](https://etherscan.io/address/0x481aeEB9bdFe08f050d22F0b352356691c4B0b59)
Reward Distributor | [`0xC20c2EA5fC5f26200f3339512f336c2ecE41FC18`](https://etherscan.io/address/0xC20c2EA5fC5f26200f3339512f336c2ecE41FC18)
Vault | [`0xd57d30D06969E5A98516e9f8D009C6F39EC169eE`](https://etherscan.io/address/0xd57d30D06969E5A98516e9f8D009C6F39EC169eE)

## Fuel Mainnet

Contract Name | Contract Address
--- | ---
FuelL2BridgeId | [`0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8`](https://app.fuel.network/contract/0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8/minted-assets)
The Rig (Liquid Staking) | [`0x2181f1b8e00756672515807cab7de10c70a9b472a4a9b1b6ca921435b0a1f49b`](https://app.fuel.network/contract/0x2181f1b8e00756672515807cab7de10c70a9b472a4a9b1b6ca921435b0a1f49b/minted-assets)
L2 Staking | [`0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c`](https://app.fuel.network/contract/0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c/assets)

## Ethereum Testnet

Contract Name | Contract Address
--- | ---
FuelChainState | [`0xf38F1e65adc58fc74BaaA132f645Aa5307F2d304`](https://sepolia.etherscan.io/address/0xf38F1e65adc58fc74BaaA132f645Aa5307F2d304)
FuelERC20GatewayV4 | [`0xd1d5a4379dccC46D5c8D1c6c2656ce705698e359`](https://sepolia.etherscan.io/address/0xd1d5a4379dccC46D5c8D1c6c2656ce705698e359)
FuelMessagePortal | [`0x01855B78C1f8868DE70e84507ec735983bf262dA`](https://sepolia.etherscan.io/address/0x01855B78C1f8868DE70e84507ec735983bf262dA)
The Rig (Liquid Staking) | [`0x2aDd14eA87ce50b48F16b1eF967bf2C90632BB44`](https://sepolia.etherscan.io/address/0x2aDd14eA87ce50b48F16b1eF967bf2C90632BB44)
Fuel Vesting | [`0x7E2DB7DabaB2A8294292ecAde3F1328B2BDfc730`](https://sepolia.etherscan.io/address/0x7E2DB7DabaB2A8294292ecAde3F1328B2BDfc730)
Fuel Migrator | [`0x41d047B393C12Db1a48766690C12134999228965`](https://sepolia.etherscan.io/address/0x41d047B393C12Db1a48766690C12134999228965)
Sequencer Interface | [`0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4`](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4)
Sequencer Proxy | [`0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD`](https://sepolia.etherscan.io/address/0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD)
Fuel Stream X | [`0x130F143e0F6d87371ca510e11340C2F3cD407a2b`](https://sepolia.etherscan.io/address/0x130F143e0F6d87371ca510e11340C2F3cD407a2b)
Reward Distributor | [`0x7c8deB33b992629130CE160f766881A191d874ce`](https://sepolia.etherscan.io/address/0x7c8deB33b992629130CE160f766881A191d874ce)
Vault | [`0xDC337a28d62eC3295F896171FA82C39c2a8e7c0A`](https://sepolia.etherscan.io/address/0xDC337a28d62eC3295F896171FA82C39c2a8e7c0A)

## Fuel Testnet

Contract Name | Contract Address
--- | ---
FuelL2BridgeId | [`0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471`](https://app-testnet.fuel.network/contract/0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471/minted-assets)
The Rig (Liquid Staking) | [`0x31b83901d35a0df4ec2c1857a420cd0e92cdb77caa08dbc912cdeb90ffa48288`](https://app-testnet.fuel.network/contract/0x31b83901d35a0df4ec2c1857a420cd0e92cdb77caa08dbc912cdeb90ffa48288/minted-assets)
L2 Staking | [`0x1fc685e1c63bbec4784079e60d4124537388f5b96773f16dfad454fae1e4f32e`](https://app-testnet.fuel.network/contract/0x1fc685e1c63bbec4784079e60d4124537388f5b96773f16dfad454fae1e4f32e/assets)


---

### File: docs/nightly/verified-addresses/docs/src/index.md

# Verified Addresses

This section serves as a reference for all verified assets, contract addresses, and security council addresses across the Fuel ecosystem.

The addresses are sourced from the following repositories:

- [Asset Addresses](https://github.com/FuelLabs/verified-assets)
- [Contract Addresses](https://github.com/FuelLabs/fuel-bridge/tree/main/packages/solidity-contracts/deployments)

The chain IDs for Fuel Ignition (mainnet) and the testnet are as follows:

- Testnet: [`0`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition-test/chain_config.json#L41)
- Mainnet: [`9889`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition/chain_config.json#L41)


---

### File: docs/nightly/verified-addresses/docs/src/security-council.md

# Fuel Bridge Security Council

## Threshold Requirement: 10/13

Entity Name | Address
--- | ---
Fuel Labs | [`0x958470a2ADe72b7a01A2e160F3286767b9623Ad7`](https://etherscan.io/address/0x958470a2ADe72b7a01A2e160F3286767b9623Ad7)
Fuel Labs | [`0x81ACA96D4Ae0932d2F3463a043392efcCB1F05b6`](https://etherscan.io/address/0x81ACA96D4Ae0932d2F3463a043392efcCB1F05b6)
Fuel Labs | [`0x796C3f536C6bf5CB7661C9A0570da0e1ECD303Dd`](https://etherscan.io/address/0x796C3f536C6bf5CB7661C9A0570da0e1ECD303Dd)
Stefan George | [`0x9F7dfAb2222A473284205cdDF08a677726d786A0`](https://etherscan.io/address/0x9F7dfAb2222A473284205cdDF08a677726d786A0)
Fuel Labs | [`0xC8Bd2Ead61e54C53C5A1836352c29F10383FBad2`](https://etherscan.io/address/0xC8Bd2Ead61e54C53C5A1836352c29F10383FBad2)
Razzle Dazzel Technologies | [`0x515Fa9b26E195a043582377F51F9A9bAD2D10c7d`](https://etherscan.io/address/0x515Fa9b26E195a043582377F51F9A9bAD2D10c7d)
Delphi Labs | [`0xd4c29D8ddC7D3E326030270f35d9FD4973AbBE09`](https://etherscan.io/address/0xd4c29D8ddC7D3E326030270f35d9FD4973AbBE09)
Chorus One | [`0x5F5e0C904153789a9E978c286180b4191950d886`](https://etherscan.io/address/0x5F5e0C904153789a9E978c286180b4191950d886)
Simply Staking | [`0x446f9d40cA491cf0788dacCAc4D16d5d8B4015Cc`](https://etherscan.io/address/0x446f9d40cA491cf0788dacCAc4D16d5d8B4015Cc)
Alpha Analytics | [`0xAA52e167e8Ad426054DCF0fd5BD5481348F4FfC8`](https://etherscan.io/address/0xAA52e167e8Ad426054DCF0fd5BD5481348F4FfC8)
Kintsugi Technologies | [`0x8a34B78Feb23b97b5ccDf83D9aDC7669C34D346F`](https://etherscan.io/address/0x8a34B78Feb23b97b5ccDf83D9aDC7669C34D346F)
CryptoCrew Validators | [`0x7cdbF64f57f0D623D924d2b4c17664c1Cd9f93d4`](https://etherscan.io/address/0x7cdbF64f57f0D623D924d2b4c17664c1Cd9f93d4)


---

### File: docs/node-operator/docs/src/fuel-ignition/index.md

# Running a Fuel Ignition Node

Below is a summary of important information to help you get started with running a node for the Layer 2 Fuel Ignition blockchain.

For the latest version of the Fuel client, please visit [this link](https://github.com/FuelLabs/fuel-core).

## Understanding Fuel Ignition's Consensus Mechanism

Fuel Ignition operates on a Proof of Authority (PoA) consensus mechanism. Here’s a brief overview:

**Validators**: In PoA, there are specific entities, known as validators or "authorities", who are given the responsibility to create new blocks and validate transactions. Unlike other consensus mechanisms like Proof of Work (PoW) or Proof of Stake (PoS), where validators are chosen based on computational power or stake, PoA validators are selected based on their reputation and trustworthiness within the network.

**Benefits of PoA**: PoA provides faster transaction times and requires less computational power, making it more energy-efficient. The security and integrity of the network are maintained by the trustworthiness of the selected validators.

## Hardware Requirements

|  Hardware  | Minimum  | Recommended |
|------------|----------|-------------|
|  Processor |  2 Cores |  8 Cores    |
|  Memory    |  8 GB    |  16 GB      |
|  Storage   |  500 GB  |  1 TB       |

For low API traffic, an AWS m5.large instance should be sufficient. However, we recommend an AWS m5.4xlarge instance to match the configuration we use for running the network.

> For routine tasks such as deploying simple contracts and testing contract interactions locally, you do not need to meet all the hardware requirements listed above.

## Getting Started

Depending on your requirements, you can choose one of the following setups:

1. **[Run a Local Fuel Ignition Node](./local-node.md):** This setup allows you to run a node that operates solely in your local environment.
2. **[Connect to the Fuel Ignition Testnet](./testnet-node.md):** With this setup, your local node will connect and sync with Fuel Ignition.
3. **[Connect to the Fuel Ignition Mainnet](./mainnet-node.md):** With this setup, your local node will connect and sync with the Mainnet version of Fuel Ignition.


---

### File: docs/node-operator/docs/src/fuel-ignition/local-node.md

# Running a local Fuel node

In addition to deploying and testing on the Fuel Testnet, you can also run a local Fuel Node.

There are two types of Fuel networks that can be run:

1. In-memory network (without persistence)
2. Local network with persistence

## Using `forc node` to run a Local Node

> If you wish to still use the `fuel-core` binary directly, you can skip this section and continue with the steps below.

Make sure you have the [latest version of `fuelup` installed or updated](https://docs.fuel.network/guides/contract-quickstart/#installation). `forc node` abstracts all the flags and configuration options of the `fuel-core` binary and is intended for ease of use. To run a local node using `forc`, you can use the following command:

```sh
forc node local
```

This command will start a local node with the default configuration (with state persistence). The default configuration is highlighted in green at the top of the command output.

If you want to specify a custom configuration, you can use the `--help` flag to see the available options. For example:

```sh
forc node local --help
```

### Dry-run mode

Users of this new plugin may want to review the parameters before running the node. To accommodate this, `forc-node` includes a dry-run mode, which can be enabled using:

```sh
forc-node --dry-run local
```

Instead of starting the node, this command will print the exact command that would be run, allowing you to verify the parameters beforehand.

## Using `fuel-core` binary to run a local node

If you wish to still use the `fuel-core` binary directly, you can follow the steps below.

## In-memory local node (without state persistence)

An in-memory node does not persist the blockchain state anywhere, it is only stored in memory as long as the node is active and running.

First ensure your environments [open files limit](https://askubuntu.com/questions/162229/how-do-i-increase-the-open-files-limit-for-a-non-root-user) `ulimit` is increased, example:

```sh
ulimit -S -n 32768
```

After ensuring your file limit is increased, to spin-up a local in-memory Fuel node download or copy the local snapshot from [here](https://github.com/FuelLabs/chain-configuration/tree/master/local), then run the following command:

```sh
fuel-core run --db-type in-memory --debug --snapshot ./your/path/to/chain_config_folder
```

To deploy a contract to the local node, run the following command:

```sh
forc deploy <signing-key> --node-url 127.0.0.1:4000/v1/graphql
```

Or to deploy with the default signer that is pre-funded by fuel-core:

```sh
forc deploy --default-signer --node-url 127.0.0.1:4000/v1/graphql
```

## Chain Configuration

To modify the initial state of the chain, you must configure the `state_config.json` file in your chain configuration folder.

For simplicity, clone the [repository](https://github.com/FuelLabs/chain-configuration/tree/master) into the directory of your choice.

When using the `--snapshot` flag later, you can replace `./your/path/to/chain_config_folder` with the `local` folder of the repository you just cloned `./chain-configuration/local/`.

To start the node with a custom configuration, you can use the command below:

```sh
fuel-core run --snapshot ./your/path/to/chain_config_folder --db-type in-memory --debug
```

To find an example `local` chain configuration folder for a specific `fuel-core` version, refer to the [`chain-configuration/local`](https://github.com/FuelLabs/chain-configuration/tree/master/local) repo.

### Funding a wallet locally

You can edit the `coins` array inside `state_config.json` to modify the initial assets owned by a given address.

The `owner` address must be a `B256` type address (begins with `0x`) instead of a `Bech32` type (begins with `fuel`).

The `amount` is a numerical value. In the example below, the value translates to 1 ETH.

```json
"coins": [
  {
    "tx_id": "0x0000000000000000000000000000000000000000000000000000000000000001",
    "output_index": 0,
    "tx_pointer_block_height": 0,
    "tx_pointer_tx_idx": 0,
    "owner": "0x488284d46414347c78221d3bad71dfebcff61ab2ae26d71129701d50796f714d",
    "amount": 1000000000,
    "asset_id": "0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07"
  }
]
```

## Local node (with state persistence)

This node does persist the blockchain state locally.
To run a local node with persistence a chain configuration file is required.

To start the node, run the following command:

```sh
fuel-core run --ip 127.0.0.1 --port 4000 --snapshot ./your/path/to/chain_config_folder --db-path ./.fueldb --debug
```

## Connecting to the local node from a browser wallet

To connect to the local node using a browser wallet, import the network address as:

```sh
http://127.0.0.1:4000/v1/graphql
```


---

### File: docs/node-operator/docs/src/fuel-ignition/mainnet-node.md

# Running a local Fuel node connected to Mainnet using P2P

> Fuel is preparing for the next major client release, upgrading the network from version 0.40.x to 0.41.x. This will be a required upgrade for all node operators.
> The **mainnet upgrade is scheduled for March 6**. You can upgrade immediately to the [0.41.6](https://github.com/FuelLabs/fuel-core/releases/tag/v0.41.6) release and sync with the current network using the latest release.
> This release brings database optimizations for some API queries. To take full advantage of these improvements, we recommend re-syncing the chain from the genesis block. While not mandatory, doing so will ensure the best performance.

## Installation

To install the Fuel toolchain, you can use the `fuelup-init` script.
This will install `forc`, `forc-client`, `forc-fmt`, `forc-lsp`, `forc-wallet` as well as `fuel-core` in `~/.fuelup/bin`.

```sh
curl https://install.fuel.network | sh
```

> Having problems? Visit the [installation guide](https://docs.fuel.network/guides/installation/) or post your question in our [forum](https://forum.fuel.network/).

## Getting a mainnet Ethereum API Key

An API key from any RPC provider that supports the Sepolia network will work. Relayers will help listen to events from the Ethereum network. We recommend either [Infura](https://www.infura.io/) or [Alchemy](https://www.alchemy.com/)

The endpoints should look like the following:

### Infura

```sh
https://mainnet.infura.io/v3/{YOUR_API_KEY}
```

### Alchemy

```sh
https://eth-mainnet.g.alchemy.com/v2/{YOUR_API_KEY}
```

Note that using other network endpoints will result in the relayer failing to start.

## Using `forc node` to run a Mainnet Node

> If you wish to still use the `fuel-core` binary directly, you can skip this section and continue with the steps below.

Make sure you have the [latest version of `fuelup` installed or updated](https://docs.fuel.network/guides/contract-quickstart/#installation). `forc node` abstracts all the flags and configuration options of the `fuel-core` binary and is intended for ease of use. To run a mainnet node using `forc`, you can use the following command:

```sh
forc node ignition
```

This command will prompt for two things:

1. You will be asked to create a keypair if you don't already have one.
2. You will be asked to provide an Ethereum RPC endpoint that you retrieved from the [Getting a mainnet Ethereum API Key](#getting-a-mainnet-ethereum-api-key) section above.

The default configuration is highlighted in green at the top of the command output.

If you want to specify a custom configuration, you can use the `--help` flag to see the available options. For example:

```sh
forc node ignition --help
```

### Dry-run mode

Users of this new plugin may want to review the parameters before running the node. To accommodate this, `forc-node` includes a dry-run mode, which can be enabled using:

```sh
forc-node --dry-run ignition
```

Instead of starting the node, this command will print the exact command that would be run, allowing you to verify the parameters beforehand.

## Using `fuel-core` binary to run a local node

If you wish to still use the `fuel-core` binary directly, you can follow the steps below.

## Generating a P2P Key

Generate a new P2P key pairing by running the following command:

```sh
fuel-core-keygen new --key-type peering
{
  "peer_id":"16Uiu2HAmEtVt2nZjzpXcAH7dkPcFDiL3z7haj6x78Tj659Ri8nrs",
  "secret":"b0ab3227974e06d236d265bd1077bb0522d38ead16c4326a5dff2f30edf88496",
  "type":"peering"
}
### Do not share or lose this private key! Press any key to complete. ###
```

Make sure you save this somewhere safe so you don't need to generate a new key pair in the future.

## Chain Configuration

To run a local node with persistence, you must have a folder with the following chain configuration files:

For simplicity, clone the [repository](https://github.com/FuelLabs/chain-configuration/tree/master) into the directory of your choice.

When using the `--snapshot` flag later, you can replace `./your/path/to/chain_config_folder` with the `ignition` folder of the repository you just cloned `./chain-configuration/ignition/`.

## Running a Local Node

First ensure your environments [open files limit](https://askubuntu.com/questions/162229/how-do-i-increase-the-open-files-limit-for-a-non-root-user) `ulimit` is increased, example:

```sh
ulimit -S -n 32768
```

> Please make sure you have the [latest version](https://docs.fuel.network/guides/installation/#updating-fuelup) of the Fuel toolchain installed and properly configured before continuing.

Finally to put everything together to start the node, run the following command:

```sh
fuel-core run \
--enable-relayer \
--service-name fuel-mainnet-node \
--keypair {P2P_PRIVATE_KEY} \
--relayer {ETHEREUM_RPC_ENDPOINT} \
--ip=0.0.0.0 --port 4000 --peering-port 30333 \
--db-path ~/.fuel-mainnet \
--snapshot ./your/path/to/chain_config_folder \
--utxo-validation --poa-instant false --enable-p2p \
--bootstrap-nodes /dnsaddr/mainnet.fuel.network \
--sync-header-batch-size 50 \
--relayer-v2-listening-contracts=0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf \
--relayer-da-deploy-height=20620434 \
--relayer-log-page-size=100 \
--sync-block-stream-buffer-size 30
```

For the full description details of each flag above, run:

```sh
fuel-core run --help
```

## Connecting to the local node from a browser wallet

To connect to the local node using a browser wallet, import the network address as:

```sh
http://0.0.0.0:4000/v1/graphql
```


---

### File: docs/node-operator/docs/src/fuel-ignition/testnet-node.md

# Running a local Fuel node connected to Testnet using P2P

> Fuel is getting ready for our next major client release, which will upgrade the network from version 0.40.x to 0.41.x. This will be a required upgrade for any node operators.
> We are targeting **February 20 for the testnet upgrade**. You can upgrade immediately to the [0.41.6](https://github.com/FuelLabs/fuel-core/releases/tag/v0.41.6) release and sync with the current network using the latest release.
> This update includes several improvements, such as database optimizations for some API queries. To fully benefit from these changes, you will need to re-sync the chain from the genesis block. While this isn't required for operation, it is recommended for optimal performance.

## Installation

To install the Fuel toolchain, you can use the `fuelup-init` script.
This will install `forc`, `forc-client`, `forc-fmt`, `forc-lsp`, `forc-wallet` as well as `fuel-core` in `~/.fuelup/bin`.

```sh
curl https://install.fuel.network | sh
```

> Having problems? Visit the [installation guide](https://docs.fuel.network/guides/installation/) or post your question in our [forum](https://forum.fuel.network/).

## Getting a Sepolia (Ethereum Testnet) API Key

An API key from any RPC provider that supports the Sepolia network will work. Relayers will help listen to events from the Ethereum network. We recommend either [Infura](https://www.infura.io/) or [Alchemy](https://www.alchemy.com/)

The endpoints should look like the following:

### Infura

```sh
https://sepolia.infura.io/v3/{YOUR_API_KEY}
```

### Alchemy

```sh
https://eth-sepolia.g.alchemy.com/v2/{YOUR_API_KEY}
```

Note that using other network endpoints will result in the relayer failing to start.

## Using `forc node` to run a Testnet Node

> If you wish to still use the `fuel-core` binary directly, you can skip this section and continue with the steps below.

Make sure you have the [latest version of `fuelup` installed or updated](https://docs.fuel.network/guides/contract-quickstart/#installation). `forc node` abstracts all the flags and configuration options of the `fuel-core` binary and is intended for ease of use. To run a testnet node using `forc`, you can use the following command:

```sh
forc node testnet
```

This command will prompt for two things:

1. You will be asked to create a keypair if you don't already have one.
2. You will be asked to provide an Ethereum RPC endpoint that you retrieved from the [Getting a Sepolia (Ethereum Testnet) API Key](#getting-a-sepolia-ethereum-testnet-api-key) section above.

The default configuration is highlighted in green at the top of the command output.

If you want to specify a custom configuration, you can use the `--help` flag to see the available options. For example:

```sh
forc node testnet --help
```

### Dry-run mode

Users of this new plugin may want to review the parameters before running the node. To accommodate this, `forc-node` includes a dry-run mode, which can be enabled using:

```sh
forc-node --dry-run testnet
```

Instead of starting the node, this command will print the exact command that would be run, allowing you to verify the parameters beforehand.

## Using `fuel-core` binary to run a local node

If you wish to still use the `fuel-core` binary directly, you can follow the steps below.

## Generating a P2P Key

Generate a new P2P key pairing by running the following command:

```sh
fuel-core-keygen new --key-type peering
{
  "peer_id":"16Uiu2HAmEtVt2nZjzpXcAH7dkPcFDiL3z7haj6x78Tj659Ri8nrs",
  "secret":"b0ab3227974e06d236d265bd1077bb0522d38ead16c4326a5dff2f30edf88496",
  "type":"peering"
}
### Do not share or lose this private key! Press any key to complete. ###
```

Make sure you save this somewhere safe so you don't need to generate a new key pair in the future.

## Chain Configuration

To run a local node with persistence, you must have a folder with the following chain configuration files:

For simplicity, clone the [repository](https://github.com/FuelLabs/chain-configuration/tree/master) into the directory of your choice.

When using the `--snapshot` flag later, you can replace `./your/path/to/chain_config_folder` with the `ignition-test` folder of the repository you just cloned `./chain-configuration/ignition-test/`.

## Running a Local Node

First ensure your environments [open files limit](https://askubuntu.com/questions/162229/how-do-i-increase-the-open-files-limit-for-a-non-root-user) `ulimit` is increased, example:

```sh
ulimit -S -n 32768
```

Finally to put everything together to start the node, run the following command:

```sh
fuel-core run \
--service-name=fuel-sepolia-testnet-node \
--keypair {P2P_PRIVATE_KEY} \
--relayer {ETHEREUM_RPC_ENDPOINT} \
--ip=0.0.0.0 --port=4000 --peering-port=30333 \
--db-path=~/.fuel-sepolia-testnet \
--snapshot ./your/path/to/chain_config_folder \
--utxo-validation --poa-instant false --enable-p2p \
--bootstrap-nodes /dnsaddr/testnet.fuel.network \
--sync-header-batch-size 50 \
--enable-relayer \
--relayer-v2-listening-contracts=0x01855B78C1f8868DE70e84507ec735983bf262dA \
--relayer-da-deploy-height=5827607 \
--relayer-log-page-size=500 \
--sync-block-stream-buffer-size 30
```

For the full description details of each flag above, run:

```sh
fuel-core run --help
```

## Connecting to the local node from a browser wallet

To connect to the local node using a browser wallet, import the network address as:

```sh
http://0.0.0.0:4000/v1/graphql
```


---

### File: docs/node-operator/docs/src/fuel-sequencer/index.md

# Running a Fuel Sequencer Node or Validator

Below is a summary of key information to help you get started with running a node for the Fuel Sequencer blockchain.

For more details, please refer to the deployment [repository](https://github.com/FuelLabs/fuel-sequencer-deployments/).

## Hardware Requirements

| Hardware   | Minimum  | Recommended |
|------------|---------|-------------|
| Processor  | 4 Cores | 8 Cores     |
| Memory     | 8 GB    | 16 GB       |
| Storage    | 200 GB  | 1 TB        |

## Port Configuration

Unless otherwise configured, the following ports should be available:

- **Sequencer**: 26656, 26657, 9090, 1317  
- **Sidecar**: 8080  
- **Ethereum**: 8545, 8546  

These components interact with each other, so any changes to the port configuration must be reflected in the corresponding components. Specifically:

- Changes to **Sequencer ports** must be updated in the **Sidecar's runtime flags**.
- Changes to the **Sidecar port** must be updated in the **Sequencer's app config**.
- Changes to **Ethereum ports** must be updated in the **Sidecar's runtime flags**.

## Getting Started

Depending on your needs, you can choose one of the following setups:

1. **[Running a Mainnet Fuel Sequencer Node](./mainnet-node.md):** Your local node will connect to and sync with the mainnet Fuel Sequencer network.
2. **[Running a Mainnet Fuel Sequencer Validator](./mainnet-validator.md):** Your local node will connect to, sync with, and validate transactions on the mainnet Fuel Sequencer network.
3. **[Running a Testnet Fuel Sequencer Node](./testnet-node.md):** Your local node will connect to and sync with the testnet Fuel Sequencer network.
4. **[Running a Testnet Fuel Sequencer Validator](./testnet-validator.md):** Your local node will connect to, sync with, and validate transactions on the testnet Fuel Sequencer network.


---

### File: docs/node-operator/docs/src/fuel-sequencer/mainnet-node.md

# Run Sequencer Node

## Prerequisites

This guide assumes that Golang is installed to run Cosmovisor. We recommend using version **1.21 or later**. You can download it [here](https://go.dev/dl/).

## Run the Node

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-mainnet-1.3.2
  - For example:
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-mainnet-1/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-mainnet-1.3.2/fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-mainnet-1.3.2
```

Initialise the node directory, giving your node a meaningful name:

```sh
fuelsequencerd init <node-name> --chain-id seq-mainnet-1
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10fuel"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = false`.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "fc5fd264190e4a78612ec589994646268b81f14e@80.64.208.207:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1258291` (1.2MiB)
  - Set `max_txs_bytes = 23068672` (22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-mainnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

### Running the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

#### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

#### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## Ethereum Bridge Event Handling

The Sidecar subscribes to a limited set of specific events emitted by the Ethereum bridge contracts. Each event type corresponds directly to a whitelisted message type, eliminating the need for generic authorization wrappers. The Sidecar implements dedicated handlers for each event type, ensuring efficient and secure processing of Ethereum-originated operations.

Proto-encoding of authorization transactions is performed by the Sequencer app, not the Ethereum contracts, significantly reducing gas costs and computational overhead. This architecture maintains all original security guarantees while optimizing for cost and efficiency.

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-mainnet#set-up-cosmovisor


---

### File: docs/node-operator/docs/src/fuel-sequencer/mainnet-validator.md

# Run Sequencer Validator

## Typical Setup

The validator setup will consist of a Fuel Sequencer, Sidecar, and a connection to an Ethereum Mainnet Node.

![fuel sequencer validator](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/fuel-sequencer-validator.png)

## Prerequisites

The guide assumes that Golang is installed in order to run Cosmovisor. We recommend installing version `1.21+`.

## Run an Ethereum Mainnet Full Node

To ensure the highest performance and reliability of the Sequencer infrastructure, **running your own Ethereum Mainnet full node is a requirement**. Avoiding the use of third-party services for Ethereum node operations significantly helps the Sequencer network's liveness. Please note these recommended node configurations:

```bash
--syncmode=snap
--gcmode=full
```

## Configure the Sequencer

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-mainnet-1.3.2
  - For example:
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-mainnet-1.3.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-mainnet-1/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-mainnet-1.3.2/fuelsequencerd-seq-mainnet-1.3.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-mainnet-1.3.2
```

Initialise the node directory, giving your node a meaningful name:

```sh
fuelsequencerd init <node-name> --chain-id seq-mainnet-1
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10fuel"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = true`.
  - Ensure that `address` is where the Sidecar will run.
- Configure `[api]`:
  - Set `swagger=true` (optional).
  - Set `rpc-max-body-bytes = 1153434` (optional - relevant for public REST).
- Configure `[commitments]`:
  - Set `api-enabled = true` (optional - relevant for public REST).
- Configure `[state-sync]`:
  - Set `snapshot-interval = 1000` (optional - to provide state-sync service).
- Configure:
  - Set `rpc-read-timeout = 10` (optional - relevant for public REST).
  - Set `rpc-write-timeout = 0` (optional - relevant for public REST).

> **WARNING**: leaving the `[commitments]` API accessible to anyone can lead to DoS! It is highly recommended to handle whitelisting or authentication by a reverse proxy like [Traefik](https://traefik.io/traefik/) for gRPC if the commitments API is enabled.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "fc5fd264190e4a78612ec589994646268b81f14e@80.64.208.207:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1258291` (1.2MiB)
  - Set `max_txs_bytes = 23068672` (22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-mainnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

## Run the Sidecar

At this point you should already be able to run `fuelsequencerd start-sidecar` with the right flags, to run the Sidecar. However, **it is highly recommended to run the Sidecar as a background service**.

It is also very important to ensure that you provide all the necessary flags when running the Sidecar to ensure that it can connect to an Ethereum node and to the Sequencer node, and is also accessible by the Sequencer node. The most important flags are:

- `host`: host for the gRPC server to listen on
- `port`: port for the gRPC server to listen on
- `eth_ws_url`: Ethereum node WebSocket endpoint
- `eth_rpc_url`: Ethereum node RPC endpoint
- `eth_contract_address`: address in hex format of the contract to monitor for logs. This MUST be set to `0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3`.
- `sequencer_grpc_url`: Sequencer node gRPC endpoint

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sidecar
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=<HOME>/go/bin/fuelsequencerd start-sidecar \
    --host "0.0.0.0" \
    --sequencer_grpc_url "127.0.0.1:9090" \
    --eth_ws_url "<ETHEREUM_NODE_WS>" \
    --eth_rpc_url "<ETHEREUM_NODE_RPC>" \
    --eth_contract_address "0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3"
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sidecar</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/fuelsequencerd</string>
        <string>start-sidecar</string>
        <string>--host</string>
        <string>0.0.0.0</string>
        <string>--sequencer_grpc_url</string>
        <string>127.0.0.1:9090</string>
        <string>--eth_ws_url</string>
        <string>[ETHEREUM_NODE_WS]</string>
        <string>--eth_rpc_url</string>
        <string>[ETHEREUM_NODE_RPC]</string>
        <string>--eth_contract_address</string>
        <string>0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.err</string>
</dict>
</plist>
```

</details>

## Run the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## Creating an Account

To run a validator, you will need to have a Sequencer account address. Generate an address with a key name:

```sh
fuelsequencerd keys add <NAME> # for a brand new key

# or

fuelsequencerd keys add <NAME> --recover # to create from a mnemonic
```

This will give you an output with an address (e.g. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) and a private mnemonic, if you generated a brand new key. Store the mnemonic safely.

Fuel Sequencer addresses also have an Ethereum-compatible (i.e. hex) format. To generate the hex address corresponding to your Sequencer address, run the following:

```sh
fuelsequencerd keys parse <ADDRESS>
```

This will give an output in this form:

```text
bytes: FF8162F37072354EB1E222084DA0D4221E93550F
human: fuelsequencer
```

Adding the `0x` prefix to the address in the first line gives you your Ethereum-compatible address, used to deposit into and interact with your Sequencer address from Ethereum. In this case, it's `0xFF8162F37072354EB1E222084DA0D4221E93550F`.

## Funding the Account

Ensure your mainnet Ethereum account (EOA) has sufficient ETH to cover gas fees and FUEL tokens to transfer to your Sequencer account.

### Important Addresses  

- [**FUEL Token:** `0x675B68AA4d9c2d3BB3F0397048e62E6B7192079c`](https://etherscan.io/address/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c)  
- [**Sequencer Interface (Bridge):** `0xca0c6B264f0F9958Ec186eb2EAa208966187D866`](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866)  

### Token Approval  

Before proceeding, you must **approve** the Fuel token contract to allow the transfer of tokens.  

In the [Fuel Token Etherscan contract UI](https://etherscan.io/token/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c#writeProxyContract), use the **`approve (0x095ea7b3)`** function:  

- **Spender (`address`)**: Set this to the **Sequencer Interface (Bridge)** address: [`0xca0c6B264f0F9958Ec186eb2EAa208966187D866`](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866).  
- **Value (`uint256`)**: Enter the number of tokens to approve, **including 9 additional decimal places**. For unlimited approval, use:  

  ```sh
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  ```

![Mainnet Etherscan Approval UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-etherscan-approval-ui.png)

### Bridging Tokens  

To bridge tokens, connect your Ethereum wallet by clicking **"Connect to Web3"** in the top left. Then, use the **`depositFor (0x36efd6f)`** function to fund your sequencer account.  

Transfer your FUEL tokens using the [Sequencer Interface (Bridge)Etherscan UI](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866).  

![Mainnet Etherscan UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-etherscan-ui.png)  

- **Amount (`uint256`)**: Enter the number of tokens to send, **including 9 additional decimal places**.  
- **Recipient address**: Enter the Ethereum-compatible address you generated earlier (e.g., `0xFF8162F37072354EB1E222084DA0D4221E93550F`).  

Click **"Write"** to confirm the transaction. The transfer may take **~20 minutes** to process.  

### Verifying Funds

To verify your funds, enter your sequencer account address (i.e. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) in the [mainnet block explorer](https://fuel-seq.simplystaking.xyz/fuel-mainnet/statesync).  

![Mainnet Block Explorer](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-blockexplorer.png)  

> **⚠ WARNING:** Always test with a small transfer before bridging FUEL tokens.

## Withdrawals

Withdrawals can be easily initiated through the CLI and will be settled on Ethereum approximately 3 days later, as the commitment and bridge finalizations must be completed first.

Identify the account from which you wish to withdraw. Use the following command to list all previously created account names matching your account address above:

```sh
fuelsequencerd keys list
```

Example output:

```sh
address: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
  name: my-mainnet-validator
  pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Al6W+Ttrscm/8njeMOt79T0BOdphfWGXrDLij+O3g19N"}'
  type: local
```

Verify that this is the correct address and account name from which you wish to withdraw.

To initiate the withdrawal, use the following command where `<eth-destination-address>` is any Ethereum address you wish to withdraw to and `<amount-in-fuel>` is the amount of FUEL you wish to withdraw:

Note: The amount in FUEL must include 9 decimal places.

```sh
fuelsequencerd tx bridge withdraw-to-ethereum <eth-destination-address> <amount-in-fuel> \
  --from=<key> \
  --gas-prices=10fuel \
  --gas=auto \
  --gas-adjustment 1.5 \
  --node="https://fuel-rpc.polkachu.com/" \
  --chain-id="seq-mainnet-1"
```

For example:

```sh
fuelsequencerd tx bridge withdraw-to-ethereum 0xd70080dE4535db4A64798a23619Db64fB28fD079 1fuel \
    --from=my-mainnet-validator \
    --gas-prices=10fuel \
    --gas=auto \
    --gas-adjustment 1.5 \
    --node="https://fuel-rpc.polkachu.com/" \
    --chain-id="seq-mainnet-1"
```

Review the transaction details and confirm the transaction by typing `yes` when prompted:

```sh
gas estimate: 106942
auth_info:
  fee:
    amount:
    - amount: "1069420"
      denom: fuel
    gas_limit: "106942"
    granter: ""
    payer: ""
  signer_infos: []
  tip: null
body:
  extension_options: []
  memo: ""
  messages:
  - '@type': /fuelsequencer.bridge.v1.MsgWithdrawToEthereum
    amount:
      amount: "1"
      denom: fuel
    from: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
    to: 0xd70080dE4535db4A64798a23619Db64fB28fD079
  non_critical_extension_options: []
  timeout_height: "0"
signatures: []
confirm transaction before signing and broadcasting [y/N]:
```

If the transaction is successful, you will receive a transaction hash, which you can paste and monitor the status of your withdrawal [here](https://fuel-seq.simplystaking.xyz/fuel-mainnet/):

```sh
code: 0
codespace: ""
data: ""
events: []
gas_used: "0"
gas_wanted: "0"
height: "0"
info: ""
logs: []
raw_log: ""
timestamp: ""
tx: null
txhash: AD541CE1DCDBD8638C5DFD3C7AF3A3AAF8B9CD0AF265C3AFD96633CE8FAF4CF4
```

![Block Explorer Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-blockexplorer-withdrawal.png)

After verifying your withdrawal on the shared sequencer explorer, visit [Simply Staking](https://stake.simplystaking.com/fuel) and connect your wallet. Navigate to the **Withdrawal** tab on the right to monitor the progress of your withdrawal.

![Simply Staking Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-simplystaking-withdrawal.png)

Once the 3-day waiting period has passed, the withdrawal will require manual action to pull the funds out.

<!-- TODO: ![Final Withdrawal Screenshot](pic) -->

## Create the Validator

To create the validator, a prerequisite is to have at least 1FUEL, with enough extra to pay for gas fees. You can check your balance from the explorer.

[//]: # (TODO: steps on how to deposit FUEL tokens to a Sequencer address)

Once you have FUEL tokens, run the following to create a validator, using the name of the account that you created in the previous steps:

```sh
fuelsequencerd tx staking create-validator path/to/validator.json \
    --from <NAME> \
    --gas auto \
    --gas-prices 10fuel \
    --gas-adjustment 1.5 \
    --chain-id seq-mainnet-1
```

...where validator.json contains:

```json
{
 "pubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"<PUBKEY>"},
 "amount": "1000000000fuel",
 "moniker": "<MONIKER>",
 "identity": "<OPTIONAL-IDENTITY>",
 "website": "<OPTIONAL-WEBSITE>",
 "security": "<OPTIONAL-EMAIL>",
 "details": "<OPTIONAL-DETAILS>",
 "commission-rate": "0.05",
 "commission-max-rate": "<MAX-RATE>",
 "commission-max-change-rate": "<MAX-CHANGE-RATE>",
 "min-self-delegation": "1"
}
```

...where the pubkey can be obtained using `fuelsequencerd tendermint show-validator`.

### What to Expect

- The Sequencer should show block syncing.
- The Sidecar should show block extraction. Occasionally it also receives requests for events.

### Tendermint KMS

If you will be using `tmkms`, make sure that in the config:

- Chain ID is set to `seq-mainnet-1` wherever applicable
- `account_key_prefix = "fuelsequencerpub"`
- `consensus_key_prefix = "fuelsequencervalconspub"`
- `sign_extensions = true`
- `protocol_version = "v0.34"`

### Additional Advanced Configuration

Sidecar flags:

- `development`: starts the sidecar in development mode.
- `eth_max_block_range`: max number of Ethereum blocks queried at one go.
- `eth_min_logs_query_interval`: minimum wait between successive queries for logs.
- `unsafe_eth_start_block`: the Ethereum block to start querying from.
- `unsafe_eth_end_block`: the last Ethereum block to query. Incorrect use can cause the validator to propose empty blocks, leading to slashing!
- `sequencer_path_to_cert_file`: path to the certificate file of the Sequencer infrastructure for secure communication. Specify this value if the Sequencer infrastructure was set up using TLS.
- `sidecar_path_to_cert_file`: path to the certificate file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `sidecar_path_to_key_file`: path to the private key file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `prometheus_enabled`: enables serving of prometheus metrics.
- `prometheus_listen_address`: address to listen for prometheus collectors (default ":8081").
- `prometheus_max_open_connections`: max number of simultaneous connections (default 3).
- `prometheus_namespace`: instrumentation namespace (default "sidecar").
- `prometheus_read_header_timeout`: amount of time allowed to read request headers (default 10s).
- `prometheus_write_timeout`: maximum duration before timing out writes of the response (default 10s).

Sidecar client flags:

- `sidecar_grpc_url`: the sidecar's gRPC endpoint.
- `query_timeout`: how long to wait before the request times out.

## Bridge Event Validation and Sequencer Consensus

Validators process specific event types emitted by the Ethereum bridge contracts, each mapped to a whitelisted message type. The Sidecar provides these events to the Sequencer app using dedicated handlers for each message type, streamlining validation and processing.

Proto-encoding of authorization transactions is handled by the Sequencer app, resulting in lower gas costs and improved efficiency. The system preserves all security guarantees, with validators participating in consensus on the ordering and inclusion of these events.

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-mainnet#set-up-cosmovisor


---

### File: docs/node-operator/docs/src/fuel-sequencer/testnet-node.md

# Run Sequencer Node

## Prerequisites

This guide assumes that Golang is installed to run Cosmovisor. We recommend using version **1.21 or later**. You can download it [here](https://go.dev/dl/).

## Run the Node

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-testnet-2.2
  - For example:
    - `fuelsequencerd-seq-testnet-2.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-testnet-2.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-testnet-2/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-testnet-2.2/fuelsequencerd-seq-testnet-2.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-testnet-2.2
```

Initialise node directory:

```sh
fuelsequencerd init <node-name> --chain-id seq-testnet-2
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10test"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = false`.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "3a0b4118c01addd33d5add81783805d5add2fb17@80.64.208.17:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1153434` (1.1MiB)
  - Set `max_txs_bytes = 23068670` (~22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-testnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

### Running the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

#### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

#### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-mainnet#set-up-cosmovisor


---

### File: docs/node-operator/docs/src/fuel-sequencer/testnet-validator.md

# Run Sequencer Validator

## Typical Setup

The validator setup will consist of a Fuel Sequencer, Sidecar, and a connection to an Ethereum Sepolia Node.

![fuel sequencer validator](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/fuel-sequencer-validator.png)

## Prerequisites

This guide assumes that Golang is installed to run Cosmovisor. We recommend using version **1.21 or later**. You can download it [here](https://go.dev/dl/).

## Run an Ethereum Sepolia Full Node

To ensure the highest performance and reliability of the Sequencer infrastructure, **running your own Ethereum Sepolia full node is a requirement**. Avoiding the use of third-party services for Ethereum node operations significantly helps the Sequencer network's liveness. Please note these recommended node configurations:

```bash
--syncmode=snap
--gcmode=full
```

## Configure the Sequencer

Obtain binary and genesis from this repository:

- Binary from: https://github.com/FuelLabs/fuel-sequencer-deployments/releases/tag/seq-testnet-2.2
  - For example:
    - `fuelsequencerd-seq-testnet-2.2-darwin-arm64` for Apple Silicon
    - `fuelsequencerd-seq-testnet-2.2-darwin-amd64` for Linux x64
- Genesis from: https://github.com/FuelLabs/fuel-sequencer-deployments/blob/main/seq-testnet-2/genesis.json

Download the right binary based on your architecture to `$GOPATH/bin/` with the name `fuelsequencerd`:

- `echo $GOPATH` to ensure it exists. If not, `go` might not be installed.
- Make sure that your `GOPATH` is set properly in your `.bashrc` or `.zshrc` file. Run `source ~/.bashrc` or `source ~/.zshrc` to apply the changes.

```bash
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
```

- `mkdir $GOPATH/bin/` if the directory does not exist.
- `wget <url/to/binary>` to download the binary, or any equivalent approach. For example:

```bash
wget https://github.com/FuelLabs/fuel-sequencer-deployments/releases/download/seq-testnet-2.2/fuelsequencerd-seq-testnet-2.2-darwin-arm64
```

- `cp <binary> $GOPATH/bin/fuelsequencerd` to copy the binary to the `GOPATH/bin/` directory.
- `chmod +x $GOPATH/bin/fuelsequencerd` to make the binary executable.
- `fuelsequencerd version` to verify that the binary is working.

Try the binary:

```sh
fuelsequencerd version  # expect seq-testnet-2.2
```

Initialise the node directory, giving your node a meaningful name:

```sh
fuelsequencerd init <node-name> --chain-id seq-testnet-2
```

Copy the downloaded genesis file to `~/.fuelsequencer/config/genesis.json`:

```sh
cp <path/to/genesis.json> ~/.fuelsequencer/config/genesis.json
```

Configure the node (part 1: `~/.fuelsequencer/config/app.toml`):

- Set `minimum-gas-prices = "10test"`.
- Configure `[sidecar]`:
  - Ensure that `enabled = true`.
  - Ensure that `address` is where the Sidecar will run.
- Configure `[api]`:
  - Set `swagger=true` (optional).
  - Set `rpc-max-body-bytes = 1153434` (optional - relevant for public REST).
- Configure `[commitments]`:
  - Set `api-enabled = true` (optional - relevant for public REST).
- Configure `[state-sync]`:
  - Set `snapshot-interval = 1000` (optional - to provide state-sync service).
- Configure:
  - Set `rpc-read-timeout = 10` (optional - relevant for public REST).
  - Set `rpc-write-timeout = 0` (optional - relevant for public REST).

> **WARNING**: leaving the `[commitments]` API accessible to anyone can lead to DoS! It is highly recommended to handle whitelisting or authentication by a reverse proxy like [Traefik](https://traefik.io/traefik/) for gRPC if the commitments API is enabled.

Configure the node (part 2: `~/.fuelsequencer/config/config.toml`):

- Configure `[p2p]`:
  - Set `persistent_peers = "fc5fd264190e4a78612ec589994646268b81f14e@80.64.208.207:26656"`.
- Configure `[mempool]`:
  - Set `max_tx_bytes = 1258291` (1.2MiB)
  - Set `max_txs_bytes = 23068672` (22MiB)
- Configure `[rpc]`:
  - Set `max_body_bytes = 1153434` (optional - relevant for public RPC).

> Note: Ensuring consistent CometBFT mempool parameters across all network nodes is important to reduce transaction delays. This includes `mempool.size`, `mempool.max_txs_bytes`, and `mempool.max_tx_bytes` in [config.toml](https://docs.cometbft.com/v0.38/core/configuration) and `minimum-gas-prices` in [app.toml](https://docs.cosmos.network/main/learn/advanced/config), as pointed out above.

### Install Cosmovisor

To install Cosmovisor, run `go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest`

Set the environment variables:

<details>
  <summary>If you're running on a zsh terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.zshrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.zshrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.zshrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.zshrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.zshrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.zshrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.zshrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.zshrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.zshrc`
</details>

<details>
  <summary>If you're running on a bash terminal...</summary>

  ```zsh
  echo "# Setup Cosmovisor" >> ~/.bashrc
  echo "export DAEMON_NAME=fuelsequencerd" >> ~/.bashrc
  echo "export DAEMON_HOME=$HOME/.fuelsequencer" >> ~/.bashrc
  echo "export DAEMON_ALLOW_DOWNLOAD_BINARIES=true" >> ~/.bashrc
  echo "export DAEMON_LOG_BUFFER_SIZE=512" >> ~/.bashrc
  echo "export DAEMON_RESTART_AFTER_UPGRADE=true" >> ~/.bashrc
  echo "export UNSAFE_SKIP_BACKUP=true" >> ~/.bashrc
  echo "export DAEMON_SHUTDOWN_GRACE=15s" >> ~/.bashrc
  
  # You can check https://docs.cosmos.network/main/tooling/cosmovisor for more configuration options.
  ```

  Apply to your current session: `source ~/.bashrc`
</details>

You can now test that cosmovisor was installed properly:

```sh
cosmovisor version
```

Initialise Cosmovisor directories (hint: `whereis fuelsequencerd` for the path):

```sh
cosmovisor init <path/to/fuelsequencerd>
```

At this point `cosmovisor run` will be the equivalent of running `fuelsequencerd`, however you should _not_ run the node for now.

### Configure State Sync

State Sync allows a node to get synced up quickly.

To configure State Sync, you will need to set these values in `~/.fuelsequencer/config/config.toml` under `[statesync]`:

- `enable = true` to enable State Sync
- `rpc_servers = ...`
- `trust_height = ...`
- `trust_hash = ...`

The last three values can be obtained from [the explorer](https://fuel-seq.simplystaking.xyz/fuel-testnet/statesync).

You will need to specify at least two comma-separated RPC servers in `rpc_servers`. You can either refer to the list of alternate RPC servers above or use the same one twice.

## Run the Sidecar

At this point you should already be able to run `fuelsequencerd start-sidecar` with the right flags, to run the Sidecar. However, **it is highly recommended to run the Sidecar as a background service**.

It is also very important to ensure that you provide all the necessary flags when running the Sidecar to ensure that it can connect to an Ethereum node and to the Sequencer node, and is also accessible by the Sequencer node. The most important flags are:

- `host`: host for the gRPC server to listen on
- `port`: port for the gRPC server to listen on
- `eth_ws_url`: Ethereum node WebSocket endpoint
- `eth_rpc_url`: Ethereum node RPC endpoint
- `eth_contract_address`: address in hex format of the contract to monitor for logs.  This MUST be set to `0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD`.
- `sequencer_grpc_url`: Sequencer node gRPC endpoint

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sidecar
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=<HOME>/go/bin/fuelsequencerd start-sidecar \
    --host "0.0.0.0" \
    --sequencer_grpc_url "127.0.0.1:9090" \
    --eth_ws_url "<ETHEREUM_NODE_WS>" \
    --eth_rpc_url "<ETHEREUM_NODE_RPC>" \
    --eth_contract_address "0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD"
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sidecar</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/fuelsequencerd</string>
        <string>start-sidecar</string>
        <string>--host</string>
        <string>0.0.0.0</string>
        <string>--sequencer_grpc_url</string>
        <string>127.0.0.1:9090</string>
        <string>--eth_ws_url</string>
        <string>[ETHEREUM_NODE_WS]</string>
        <string>--eth_rpc_url</string>
        <string>[ETHEREUM_NODE_RPC]</string>
        <string>--eth_contract_address</string>
        <string>0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sidecar.err</string>
</dict>
</plist>
```

</details>

## Run the Sequencer

At this point you should already be able to run `cosmovisor run start` to run the Sequencer. However, **it is highly recommended to run the Sequencer as a background service**.

Some examples are provided below for Linux and Mac. You will need to replicate the environment variables defined when setting up Cosmovisor.

### Linux

On Linux, you can use `systemd` to run the Sequencer in the background. Knowledge of how to use `systemd` is assumed here.

Here's an example service file with some placeholder (`<...>`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```sh
[Unit]
Description=Sequencer Node
After=network.target

[Service]
Type=simple
User=<USER>
ExecStart=/home/<USER>/go/bin/cosmovisor run start
Restart=on-failure
RestartSec=3
LimitNOFILE=4096

Environment="DAEMON_NAME=fuelsequencerd"
Environment="DAEMON_HOME=/home/<USER>/.fuelsequencer"
Environment="DAEMON_ALLOW_DOWNLOAD_BINARIES=true"
Environment="DAEMON_LOG_BUFFER_SIZE=512"
Environment="DAEMON_RESTART_AFTER_UPGRADE=true"
Environment="UNSAFE_SKIP_BACKUP=true"
Environment="DAEMON_SHUTDOWN_GRACE=15s"

[Install]
WantedBy=multi-user.target
```

</details>

### Mac

On Mac, you can use `launchd` to run the Sequencer in the background. Knowledge of how to use `launchd` is assumed here.

Here's an example plist file with some placeholder (`[...]`) values that must be filled-in:

<details>
  <summary>Click me...</summary>

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fuel.sequencer</string>

    <key>ProgramArguments</key>
    <array>
        <string>/Users/[User]/go/bin/cosmovisor</string>
        <string>run</string>
        <string>start</string>
    </array>

    <key>UserName</key>
    <string>[User]</string>

    <key>EnvironmentVariables</key>
    <dict>
        <key>DAEMON_NAME</key>
        <string>fuelsequencerd</string>
        <key>DAEMON_HOME</key>
        <string>/Users/[User]/.fuelsequencer</string>
        <key>DAEMON_ALLOW_DOWNLOAD_BINARIES</key>
        <string>true</string>
        <key>DAEMON_LOG_BUFFER_SIZE</key>
        <string>512</string>
        <key>DAEMON_RESTART_AFTER_UPGRADE</key>
        <string>true</string>
        <key>UNSAFE_SKIP_BACKUP</key>
        <string>true</string>
        <key>DAEMON_SHUTDOWN_GRACE</key>
        <string>15s</string>
    </dict>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
    </dict>

    <key>HardResourceLimits</key>
    <dict>
        <key>NumberOfFiles</key>
        <integer>4096</integer>
    </dict>

    <key>StandardOutPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.out</string>
    <key>StandardErrorPath</key>
    <string>/Users/[User]/Library/Logs/fuel-sequencer.err</string>
</dict>
</plist>
```

</details>

## Creating an Account

To run a validator, you will need to have a Sequencer account address. Generate an address with a key name:

```sh
fuelsequencerd keys add <NAME> # for a brand new key

# or

fuelsequencerd keys add <NAME> --recover # to create from a mnemonic
```

This will give you an output with an address (e.g. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) and a private mnemonic, if you generated a brand new key. Store the mnemonic safely.

Fuel Sequencer addresses also have an Ethereum-compatible (i.e. hex) format. To generate the hex address corresponding to your Sequencer address, run the following:

```sh
fuelsequencerd keys parse <ADDRESS>
```

This will give an output in this form:

```text
bytes: FF8162F37072354EB1E222084DA0D4221E93550F
human: fuelsequencer
```

Adding the `0x` prefix to the address in the first line gives you your Ethereum-compatible address, used to deposit into and interact with your Sequencer address from Ethereum. In this case, it's `0xFF8162F37072354EB1E222084DA0D4221E93550F`.

## Funding the Account

Ensure your Ethereum account (EOA) has sufficient ETH to cover gas fees.

### Important Addresses  

- [**FUEL Token:** `0xd7Fc4e8FB2c05567C313f4C9b9e07641a361a550`](https://sepolia.etherscan.io/token/0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550)  
- [**Sequencer Interface (Bridge):** `0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4`](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4)  

### Token Faucet  

To obtain testnet tokens, visit [Fuel's official Ethereum testnet staking UI](https://app-testnet.fuel.network/staking/on-ethereum) with any Ethereum EOA that has not previously received FUEL tokens from the faucet.  

Click **"Faucet Fuel Token"** to receive `100 FUEL` tokens for testing.  

![Testnet Fuel Faucet](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-fuel-faucet.png)  

### Token Approval  

Before proceeding, you must **approve** the Fuel token contract to allow the transfer of tokens.  

In the [Fuel Token Etherscan contract UI](https://sepolia.etherscan.io/token/0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550#writeProxyContract), use the **`approve (0x095ea7b3)`** function:  

- **Spender (`address`)**: Set this to the **Sequencer Interface (Bridge)** address: [`0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4`](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4).  
- **Value (`uint256`)**: Enter the number of tokens to approve, **including 9 additional decimal places**. For unlimited approval, use:  

  ```sh
  0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
  ```

![Testnet Etherscan Approval UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-etherscan-approval-ui.png)

### Bridging Tokens  

To bridge tokens, connect your Ethereum wallet by clicking **"Connect to Web3"** in the top left. Then, use the **`depositFor (0x36efd6f)`** function to fund your sequencer account.  

Transfer your FUEL tokens using the [Sequencer Interface (Bridge) Etherscan UI](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4#writeProxyContract).  

![Testnet Etherscan UI](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-etherscan-ui.png)  

- **Amount (`uint256`)**: Enter the number of tokens to send, **including 9 additional decimal places**.  
- **Recipient address**: Enter the Ethereum-compatible address you generated earlier (e.g., `0xFF8162F37072354EB1E222084DA0D4221E93550F`).  

Click **"Write"** to confirm the transaction. The transfer may take **~20 minutes** to process.  

### Verifying Funds

To verify your funds, enter your sequencer account address (i.e. `fuelsequencer1l7qk9umswg65av0zygyymgx5yg0fx4g0dpp2tl`) in the [testnet block explorer](https://fuel-seq.simplystaking.xyz/fuel-testnet/statesync).  

![Testnet Block Explorer](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/mainnet-blockexplorer.png)  

> **⚠ WARNING:** Always test with a small transfer before bridging FUEL tokens.

## Withdrawals

Withdrawals can be easily initiated through the CLI and will be settled on Sepolia approximately 3 days later, as the commitment and bridge finalizations must be completed first.

Identify the account from which you wish to withdraw. Use the following command to list all previously created account names matching your account address above:

```sh
fuelsequencerd keys list
```

Example output:

```sh
address: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
  name: my-testnet-validator
  pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"Al6W+Ttrscm/8njeMOt79T0BOdphfWGXrDLij+O3g19N"}'
  type: local
```

Verify that this is the correct address and account name from which you wish to withdraw.

To initiate the withdrawal, use the following command where `<eth-destination-address>` is any Sepolia address you wish to withdraw to and `<amount-in-fuel>` is the amount of TEST (FUEL) you wish to withdraw:

Note: The amount in TEST (FUEL) must include 9 decimal places.

```sh
fuelsequencerd tx bridge withdraw-to-ethereum <eth-destination-address> <amount-in-fuel> \
  --from=<key> \
  --gas-prices=10test \
  --gas=auto \
  --gas-adjustment 1.5 \
  --node="https://testnet-rpc-fuel-seq.simplystaking.xyz/" \
  --chain-id="seq-testnet-2"
```

For example:

```sh
fuelsequencerd tx bridge withdraw-to-ethereum 0xd70080dE4535db4A64798a23619Db64fB28fD079 1test \
    --from=my-testnet-validator \
    --gas-prices=10test \
    --gas=auto \
    --gas-adjustment 1.5 \
    --node="https://testnet-rpc-fuel-seq.simplystaking.xyz/" \
    --chain-id="seq-testnet-2"
```

Review the transaction details and confirm the transaction by typing `yes` when prompted:

```sh
gas estimate: 106713
auth_info:
  fee:
    amount:
    - amount: "1067130"
      denom: test
    gas_limit: "106713"
    granter: ""
    payer: ""
  signer_infos: []
  tip: null
body:
  extension_options: []
  memo: ""
  messages:
  - '@type': /fuelsequencer.bridge.v1.MsgWithdrawToEthereum
    amount:
      amount: "1"
      denom: test
    from: fuelsequencer1zzu4804kp6m6whzza6r75g7mnme2ahqkjuw4kf
    to: 0xd70080dE4535db4A64798a23619Db64fB28fD079
  non_critical_extension_options: []
  timeout_height: "0"
signatures: []
confirm transaction before signing and broadcasting [y/N]: 
```

If the transaction is successful, you will receive a transaction hash, which you can paste and monitor the status of your withdrawal [here](https://fuel-seq.simplystaking.xyz/fuel-testnet/):

```sh
code: 0
codespace: ""
data: ""
events: []
gas_used: "0"
gas_wanted: "0"
height: "0"
info: ""
logs: []
raw_log: ""
timestamp: ""
tx: null
txhash: FF51288FB916CEE4538E17FB70E438278143FAD2B613D98362A562B02C07253F
```

![Block Explorer Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-blockexplorer-withdrawal.png)

After verifying your withdrawal on the shared sequencer explorer, visit [Simply Staking](https://stake.simplystaking.com/fuel-testnet) and connect your wallet. Navigate to the **Withdrawal** tab on the right to monitor the progress of your withdrawal.

![Simply Staking Withdrawal](https://raw.githubusercontent.com/FuelLabs/node-operator/refs/heads/main/assets/sepolia-simplystaking-withdrawal.png)

Once the 3-day waiting period has passed, the withdrawal will require manual action to pull the funds out.

## Create the Validator

To create the validator, a prerequisite is to have at least 1TEST, with enough extra to pay for gas fees. You can check your balance from the explorer.

[//]: # (TODO: steps on how to deposit TEST tokens to a Sequencer address)

Once you have TEST tokens, run the following to create a validator, using the name of the account that you created in the previous steps:

```sh
fuelsequencerd tx staking create-validator path/to/validator.json \
    --from <NAME> \
    --gas auto \
    --gas-prices 10test \
    --gas-adjustment 1.5 \
    --chain-id seq-testnet-2
```

...where validator.json contains:

```json
{
 "pubkey": {"@type":"/cosmos.crypto.ed25519.PubKey","key":"<PUBKEY>"},
 "amount": "1000000000test",
 "moniker": "<MONIKER>",
 "identity": "<OPTIONAL-IDENTITY>",
 "website": "<OPTIONAL-WEBSITE>",
 "security": "<OPTIONAL-EMAIL>",
 "details": "<OPTIONAL-DETAILS>",
 "commission-rate": "0.05",
 "commission-max-rate": "<MAX-RATE>",
 "commission-max-change-rate": "<MAX-CHANGE-RATE>",
 "min-self-delegation": "1"
}
```

...where the pubkey can be obtained using `fuelsequencerd tendermint show-validator`.

### What to Expect

- The Sequencer should show block syncing.
- The Sidecar should show block extraction. Occasionally it also receives requests for events.

### Tendermint KMS

If you will be using `tmkms`, make sure that in the config:

- Chain ID is set to `seq-testnet-2` wherever applicable
- `account_key_prefix = "fuelsequencerpub"`
- `consensus_key_prefix = "fuelsequencervalconspub"`
- `sign_extensions = true`
- `protocol_version = "v0.34"`

### Additional Advanced Configuration

Sidecar flags:

- `development`: starts the sidecar in development mode.
- `eth_max_block_range`: max number of Ethereum blocks queried at one go.
- `eth_min_logs_query_interval`: minimum wait between successive queries for logs.
- `unsafe_eth_start_block`: the Ethereum block to start querying from.
- `unsafe_eth_end_block`: the last Ethereum block to query. Incorrect use can cause the validator to propose empty blocks, leading to slashing!
- `sequencer_path_to_cert_file`: path to the certificate file of the Sequencer infrastructure for secure communication. Specify this value if the Sequencer infrastructure was set up using TLS.
- `sidecar_path_to_cert_file`: path to the certificate file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `sidecar_path_to_key_file`: path to the private key file of the sidecar server for secure communication. Specify this value if you want to set up a sidecar server with TLS.
- `prometheus_enabled`: enables serving of prometheus metrics.
- `prometheus_listen_address`: address to listen for prometheus collectors (default ":8081").
- `prometheus_max_open_connections`: max number of simultaneous connections (default 3).
- `prometheus_namespace`: instrumentation namespace (default "sidecar").
- `prometheus_read_header_timeout`: amount of time allowed to read request headers (default 10s).
- `prometheus_write_timeout`: maximum duration before timing out writes of the response (default 10s).

Sidecar client flags:

- `sidecar_grpc_url`: the sidecar's gRPC endpoint.
- `query_timeout`: how long to wait before the request times out.

## References

Based on material from:

- https://docs.cosmos.network/main/tooling/cosmovisor
- https://docs.osmosis.zone/overview/validate/joining-testnet#set-up-cosmovisor


---

### File: docs/node-operator/docs/src/index.md

# Running a Node

This guide is designed to swiftly introduce you to the process of running a local node for the Fuel blockchain.

## What is a Node?

In the context of the Fuel blockchain, a node, often referred to as a 'client', is a piece of software that downloads and maintains a copy of the Fuel blockchain. It verifies the authenticity of every block and transaction, ensuring that your copy is always up-to-date and in sync with the network.

## Why Run Your Own Node?

Running your own node provides several advantages:

1. **Query Freedom:** By hosting your own node, you can execute a higher number of queries without encountering any rate limits.
2. **Network Independence:** Having your own node ensures that you're not reliant on third-party services, giving you full control over your interactions with the Fuel blockchain.

## Types Of Networks

There are two networks you can currently run the nodes for

1. Fuel Ignition: Fuel V2 layer 2 rollup to go on Ethereum Mainnet.

2. Fuel's proposed cosmos based blockchain shared sequencer design prioritizes speed and efficiency, rapidly processing cross-chain transactions. Our fast sequencing empowers developers to build versatile, low-latency cross-chain applications, mitigating typical multi-chain fragmentation.

## Getting Started

Depending on which network you wish to participate in follow the following sections.

1. [Fuel Ignition](./fuel-ignition/index.md)
2. [Fuel Shared Sequencer](./fuel-sequencer/index.md)


---

### File: docs/sway-by-example-lib/docs/src/base-asset.md

# Base Asset

Examples of base asset in Sway

```sway
contract;

use std::{
    auth::{
        msg_sender,
    },
    call_frames::{
        msg_asset_id,
    },
    contract_id::ContractId,
    context::{
        balance_of,
        msg_amount,
    },
    asset::{
        transfer,
    },
};

abi MyContract {
    #[payable]
    fn deposit();
    fn withdraw(amount: u64);
    fn get_balance() -> u64;
}

impl MyContract for Contract {
    #[payable]
    fn deposit() {
        require(msg_asset_id() == AssetId::base(), "not base asset");
        require(msg_amount() > 0, "amount = 0");
    }

    fn withdraw(amount: u64) {
        transfer(msg_sender().unwrap(), AssetId::base(), amount);
    }

    fn get_balance() -> u64 {
        balance_of(ContractId::this(), AssetId::base())
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/big-numbers.md

# Big Numbers

Examples of Big Numbers in Sway

```sway
contract;

// Storage declaration
storage {
    big_number: u256 = 0,
}

// ABI definition
abi BigNumberContract {

    #[storage(write)]
    fn set_big_number(value: u256);

    #[storage(read)]
    fn get_big_number() -> u256;

    #[storage(write)]
    fn add_u64_to_big_number(value: u64);

    #[storage(write)]
    fn multiply_big_number_by_u64(value: u64);
}

// Implementation of the ABI
impl BigNumberContract for Contract {
    /// Sets the big number to a new value.
    ///
    /// # Arguments
    ///
    /// * `value`: [u256] - The new value to set.
    ///
    /// # Storage Access
    ///
    /// * Writes: `1`
    #[storage(write)]
    fn set_big_number(value: u256) {
        // Write the new value to the storage variable `big_number`.
        storage.big_number.write(value);
    }

    /// Returns the current big number.
    ///
    /// # Returns
    ///
    /// * [u256] - The current big number.
    ///
    /// # Storage Access
    ///
    /// * Reads: `1`
    #[storage(read)]
    fn get_big_number() -> u256 {
        // Read and return the value of the storage variable `big_number`.
        storage.big_number.read()
    }

    /// Adds a `u64` value to the current big number.
    ///
    /// # Arguments
    ///
    /// * `value`: [u64] - The value to add.
    ///
    /// # Storage Access
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    #[storage(write)]
    fn add_u64_to_big_number(value: u64) {
        // Read the current value of the storage variable `big_number`.
        let current_value = storage.big_number.read();
        // Convert the `u64` value to `u256`.
        let value_as_u256 = value.as_u256();
        // Add the converted value to the current value.
        let new_value = current_value + value_as_u256;
        // Write the new value back to the storage variable `big_number`.
        storage.big_number.write(new_value);
    }

    /// Multiplies the current big number by a `u64` value.
    ///
    /// # Arguments
    ///
    /// * `value`: [u64] - The value to multiply by.
    ///
    /// # Storage Access
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    #[storage(write)]
    fn multiply_big_number_by_u64(value: u64) {
        // Read the current value of the storage variable `big_number`.
        let current_value = storage.big_number.read();
        // Convert the `u64` value to `u256`.
        let value_as_u256 = value.as_u256();
        // Multiply the current value by the converted value.
        let new_value = current_value * value_as_u256;
        // Write the new value back to the storage variable `big_number`.
        storage.big_number.write(new_value);
    }
}


```


---

### File: docs/sway-by-example-lib/docs/src/blockchain-types.md

# Blockchain Types

Examples of blockchain data types in Sway

```sway
contract;

// Address
// Contract Id
// Identity

abi MyContract {
    fn test_func() -> Identity;
}

impl MyContract for Contract {
    fn test_func() -> Identity {
        // Address
        let b: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
        let addr: Address = Address::from(b);
        let b: b256 = addr.into();

        // Contract id
        let b: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
        let my_contract_id: ContractId = ContractId::from(b);
        let b: b256 = my_contract_id.into();

        // Identity type
        let raw_addr: b256 = 0xddec0e7e6a9a4a4e3e57d08d080d71a299c628a46bc609aab4627695679421ca;
        let addr = Address::from(raw_addr);
        let my_id: Identity = Identity::Address(addr);

        // Match on identity
        let id: Address = match my_id {
            Identity::Address(addr) => addr,
            Identity::ContractId(id) => revert(0),
        };

        my_id
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/compound-types.md

# Compound Types

Examples of compound data types in Sway

```sway
contract;

// Compound types
// - Tuples
// - destructuring
// - Structs
// - Arrays

struct Point {
    x: u64,
    y: u64,
}

abi MyContract {
    fn test_func() -> Point;
}

impl MyContract for Contract {
    fn test_func() -> Point {
        // Tuples
        let t: (u64, bool) = (42, true);
        // Access tuple value
        assert(t.0 == 42);
        assert(t.1);

        // Destructuring a tuple (type annotation is optional)
        let (num, boo) = t;

        // Tuple of length 1
        let one: (u64, ) = (123, );

        // Struct
        let p = Point { x: 1, y: 2 };
        // Access struct fields
        assert(p.x == 1);
        assert(p.y == 2);

        // Array
        let u_arr: [u8; 5] = [1, 2, 3, 4, 5];
        let s_arr: [str; 4] = ["cat", "dog", "snake", "fish"];

        let struct_arr: [Point; 2] = [Point { x: 1, y: 2 }, Point { x: 11, y: 22 }];

        // Mutating array
        let mut mut_arr: [bool; 2] = [true, false];
        mut_arr[1] = true;

        p
    }

}

```


---

### File: docs/sway-by-example-lib/docs/src/configurable-constants.md

# Configurable Constants

Examples of configurable constants in Sway

```sway
contract;

// Configurable constants

configurable {
    MY_NUM: u64 = 123,
    OWNER: Address = Address::from(0x3333333333333333333333333333333333333333333333333333333333333333),
    POINT: Point = Point { x: 1, y: 2 },
}

struct Point {
    x: u64,
    y: u64,
}

abi MyContract {
    fn test_func() -> (u64, Address, Point);
}

impl MyContract for Contract {
    fn test_func() -> (u64, Address, Point) {
        (MY_NUM, OWNER, POINT)
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/constants.md

# Constants

Examples of constants in Sway

```sway
contract;

// Constants

// 0x0000000000000000000000000000000000000000000000000000000000000000
const ZERO_B256: b256 = b256::min();
const ZERO_ADDRESS = Address::from(ZERO_B256);

// Associated constants
struct Point {
    x: u64,
    y: u64,
}

impl Point {
    const ZERO: Point = Point { x: 0, y: 0 };
}

abi MyContract {
    fn test_func() -> Point;
}

impl MyContract for Contract {
    fn test_func() -> Point {
        // Can also define a constant inside a function
        const MY_NUM: u64 = 123;
        Point::ZERO
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/enums.md

# Enums

Examples of enums in Sway

```sway
contract;

// Enums
// - Basics
// - Enums of structs
// - Enum of enums

enum Color {
    Red: (),
    Blue: (),
    Green: (),
}

// Enums of structs
struct Point {
    x: u64,
    y: u64,
}

enum Shape {
    Circle: (Point, u64),
    Triangle: [Point; 3],
}

// Enum of enums
enum Error {
    Auth: AuthError,
    Transfer: TransferError,
}

enum AuthError {
    NotOwner: (),
    NotApproved: (),
}

enum TransferError {
    TransferToZeroAddress: (),
    InsufficientBalance: (),
}

abi MyContract {
    fn test_func() -> Error;
}

impl MyContract for Contract {
    fn test_func() -> Error {
        let color = Color::Blue;

        let circle = Shape::Circle((Point { x: 0, y: 0 }, 1));
        let triangle = Shape::Triangle([
            Point { x: 0, y: 0 },
            Point { x: 1, y: 1 },
            Point { x: 2, y: 0 },
        ]);

        let error = Error::Auth(AuthError::NotOwner);

        error
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/functions.md

# Functions

Examples of functions in Sway

```sway
contract;

// Functions
// - Internal and external functions
// - ref mut
// - Return multiple outputs

abi MyContract {
    fn test_func() -> (u64, bool);
}

fn eq(x: u64, y: u64) -> bool {
    x == y
}

fn inc(ref mut num: u64) {
    num += 1;
}

fn swap_mut(ref mut pair: (u64, u64)) {
    let tmp = pair.0;
    pair.0 = pair.1;
    pair.1 = tmp;
}

fn swap(x: u64, y: u64) -> (u64, u64) {
    (y, x)
}

impl MyContract for Contract {
    fn test_func() -> (u64, bool) {
        assert(eq(11, 11));
        assert(!eq(11, 12));

        let mut num: u64 = 123;
        inc(num);
        assert(num == 123 + 1);

        let mut pair = (12, 13);
        swap_mut(pair);
        assert(pair.0 == 13);
        assert(pair.1 == 12);

        let x = 1;
        let y = 2;
        let (y, x) = swap(x, y);
        assert(y == 1);
        assert(x == 2);
        (123, true)
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/hashing.md

# Hashing with Keccak256

Example of how to compute hash in Sway using Keccak256

```sway
contract;

use std::hash::*;
use std::bytes::Bytes;
use std::codec::encode;

abi HashFunction {
    fn hash(_text: str, _num: u64, _addr: b256) -> b256;
    fn collision(_text: str, _anotherText: str) -> b256;
    fn guess(_word: str) -> bool;
}

impl HashFunction for Contract {
    fn hash(_text: str, _num: u64, _addr: b256) -> b256 {
        keccak256({
            let mut bytes = Bytes::new();
            bytes.append(Bytes::from(encode(_text)));
            bytes.append(Bytes::from(encode(_num)));
            bytes.append(Bytes::from(encode(_addr)));
            bytes
        })
    }

    // The collision function is not strictly necessary unless you have a specific use case that requires hashing two strings together. 
    // If your primary goal is to hash individual strings you can remove the collision function.
    fn collision(_text: str, _anotherText: str) -> b256 {
        keccak256({
            let mut bytes = Bytes::new();
            bytes.append(Bytes::from(encode(_text)));
            bytes.append(Bytes::from(encode(_anotherText)));
            bytes
        })
    }

    fn guess(_word: str) -> bool {
        let answer: b256 = 0x60298f78cc0b47170ba79c10aa3851d7648bd96f2f8e46a19dbc777c36fb0c00;
        keccak256({
            let mut bytes = Bytes::new();
            bytes.append(Bytes::from(encode(_word)));
            bytes
        }) == answer
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/hello-sway.md

# Hello Sway

The `contract` keyword at the top defines one of the four program types found in Sway. Others being libraries, scripts and predicates.

```sway
// The underlying smart contracts written in Sway are no different than those in Solidity
// Some bytecode is deployed with an API and state to interact with
contract;

// The ABI (Application Binary Interface) clearly defines the signature of the functions present in the contract
abi HelloModular {
    // The "annotation" storage indicates the impure actions of the function
    // In this case the greet() function only has reading capabilities.
    // Note: Storage can only be found in contract type programs
    #[storage(read)]
    fn my_lucky_number() -> u64;
}

// Storage contains all of the state available in the contract 
storage {
    lucky_number: u64 = 777,
}

// The actual implementation of ABI for the contract
impl HelloModular for Contract {
    #[storage(read)]
    fn my_lucky_number() -> u64 {
        storage.lucky_number.read()
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/if.md

# If Statements

Examples of if statements in Sway

```sway
contract;

// if, else if, else
// if let

abi MyContract {
    fn test_func(x: u64) -> u64;
}

impl MyContract for Contract {
    fn test_func(x: u64) -> u64 {
        // if, else if, else
        if x < 10 {
            // do something
        } else if x < 20 {
            // do something else
        } else {
            // do something else
        }

        // if let
        let mut y = 0;
        if x < 10 {
            y = x * x;
        } else {
            y = x + 1;
        }

        // Assign the outcome of if statements to the variable y
        let y = if x < 10 {
            // do something, for example
            x * x
        } else {
            // do something else, for example
            x + 1
        }; // Notice semicolon here

        y
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/imports.md

# Imports

Examples of imports in Sway

```sway
contract;

// Imports
// - Internal
mod imports_library;
use imports_library::*;

// - External
use math_lib::full_math::*;

// - Standard library (std)
use std::{
    identity::*,
    auth::msg_sender,
};

// - Sway standards
use standards::src20::SRC20;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}

```

## Project Structures

### Internal

```bash

└── imports
    ├── Forc.toml
    └── src
        ├── imports_library.sw
        └── main.sw

```

### External

```bash

├── imports
│   ├── Forc.toml
│   └── src
│       ├── imports_library.sw
│       └── main.sw
└── math_lib
    ├── Forc.toml
    └── src
        ├── Q64x64.sw
        ├── full_math.sw
        └── math_lib.sw

```

All external imports must be defined as dependencies within `Forc.toml`

```toml
[project]
authors = ["Kin Chan"]
entry = "main.sw"
license = "Apache-2.0"
name = "imports"

[dependencies]
standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.7.1" }
math_lib = { path = "../math_lib/" }

```


---

### File: docs/sway-by-example-lib/docs/src/index.md

# Sway By Example

Library of compiled Sway programs to showcase accessible code for the Sway language.


---

### File: docs/sway-by-example-lib/docs/src/library.md

# Library

Example on how to create a library in Sway and how to use it in your Smart Contract.
This example also showcases how to use different types of imports in Sway depending on external library or library from the same project.

```sway
contract;

// 1. Importing within the same project
// Using "mod" keyword, you can import an internal library that has been defined in this project.
mod sqrt_lib;

// It is a good practice to import in ABI
// It is also a good practice to define events and custom errors using this way

// Using "use" keyword imports in a library. This method is used to import an external lilbray that is defined outside the main `src` directory.
// use sqrt_lib::math_sqrt;
// $ tree
// .
// ├── my_project
// │   ├── Cargo.toml
// │   ├── Forc.toml
// │   └─── src
// │       └── main.sw
// │
// └── external_lib
//     ├── Cargo.toml
//     ├── Forc.toml
//     └─── src
//         └── lib.sw
// External library is outside the src directory of our project. Thus, it needs to be added as a dependency in the Forc.toml of our project.
// [dependencies]
// external_lib = { path = "../external_lib" }


// 2. Importing the standard library
// The standard library consists of
//   a. language primitives
//   b. blockchain contextual operations
//   c. native asset management
//   etc.
// Functions like msg.sender(), block.timestamp(),etc are found here https://github.com/FuelLabs/sway/tree/master/sway-lib-std
// use std::{
//     identity::*,
//     address::*,
//     constants::*,
//     auth::msg_sender,
// };


// 3. Importing from a different project
// If any library is not listed as a dependency, but present in forc.toml, you can use it as below.
// Math libraries copied from https://github.com/sway-libs/concentrated-liquidity/
// use math_lib::full_math::*;

use ::sqrt_lib::math_sqrt;

abi TestMath {
    fn test_square_root(x: u256) -> u256;
}

impl TestMath for Contract {
    fn test_square_root(x: u256) -> u256 {
        math_sqrt(x)
    }
}
```


---

### File: docs/sway-by-example-lib/docs/src/logging.md

# Logging

Examples of logging in Sway

```sway

contract;

use std::logging::log;

abi MyContract {
    fn test_func(val: u64);
}

impl MyContract for Contract {
    fn test_func(val: u64) {
        log(val);
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/match.md

# Match Statements

Examples of match statements in Sway

```sway
contract;

// Control flow
// Assign variable
// Enum

abi MyContract {
    fn test_function(x: u64, y: Option<u64>) -> u64;
}

fn do_something() {}

fn do_something_else() {}

impl MyContract for Contract {
    fn test_function(x: u64, y: Option<u64>) -> u64 {
        // Control flow
        match x {
            0 => do_something(),
            _ => do_something_else(),
        }

        // Assign variable
        let res: str = match x {
            0 => "a",
            1 => "b",
            2 => "c",
            _ => "d",
        };

        // Enum
        let z = match y {
            Option::Some(val) => val + 1,
            Option::None => 0,
        };

        z
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/options.md

# Options

Examples of options in Sway

```sway
contract;

// Option<T> = Some(T) | None

abi MyContract {
    fn test_func() -> (Option<bool>, Option<bool>, Option<bool>);
}

impl MyContract for Contract {
    fn test_func() -> (Option<bool>, Option<bool>, Option<bool>) {
        let liked = Option::Some(true);
        let disliked = Option::Some(false);
        let none = Option::None;
        (liked, disliked, none)
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/predicate.md

# Predicate

Examples of a predicate program type in Sway

|                                | Predicates | Contracts |
|--------------------------------|------------|-----------|
| Access data on chain           |      ❌     |     ✅     |
| Read data from smart contracts |      ❌     |     ✅     |
| Check date or time             |      ❌     |     ✅     |
| Read block hash or number      |      ❌     |     ✅     |
| Read input coins               |      ✅     |     ✅     |
| Read output coins              |      ✅     |     ✅     |
| Read transaction scripts       |      ✅     |     ✅     |
| Read transaction bytecode      |      ✅     |     ✅     |

```sway
predicate;

use std::{
    auth::predicate_address,
    inputs::{
        input_amount,
    },
    outputs::{
        output_amount,
    },
    tx::{
        tx_id,
        tx_witnesses_count
    },
    constants::ZERO_B256,
};

// Configurables
configurable {
    FLOOR: u64 = 1,
}

fn input_output_checks() -> bool {
    if (100 >= input_amount(0).unwrap() && 100 >= output_amount(0).unwrap()) {
        return true
    }
    return false
}

// Primitive Arguments 
fn main(a: u64, b: str, c: bool, d: b256) -> bool {
    // This predicate's own address
    let this_predicate_root = predicate_address();

    if (a == 0 || b == "a" || c == false ||  d == ZERO_B256) {
        return false
    }

    if tx_witnesses_count() < 1 { 
        return false
    }

    // While loop 
    let mut x = 10;
    while x != FLOOR { 
        x -= 1; 
    }

    return input_output_checks()
}

```


---

### File: docs/sway-by-example-lib/docs/src/primitive-types.md

# Primitive Types

Examples of primitive data types in Sway

```sway
contract;

// Primitive types
// - Unsigned integers
// - Strings
// - Boolean
// - 256 bits = 32 bytes

abi MyContract {
    fn test_func() -> bool;
}

impl MyContract for Contract {
    fn test_func() -> bool {
        // Unsigned integers
        // 0 <= u8 <= 2**8 - 1
        let u_8: u8 = 123;
        // 0 <= u16 <= 2**16 - 1
        let u_16: u16 = 123;
        // 0 <= u32 <= 2**32 - 1
        let u_32: u32 = 123;
        // 0 <= u64 <= 2**64 - 1
        let u_64: u64 = 123;
        // 0 <= u256 <= 2**256 - 1 
        // Since u256 are bigger than registers they are stored in memory rather than registers
        let u256: u256 = 123;

        let u_64_max = u64::max();

        // String slice
        let s_slice: str = "fuel";

        // Fixed length string array
        let s_array: str[4] = __to_str_array("fuel");

        // Boolean
        let boo: bool = true;
        // 256 bits = 32 bytes
        let b_256: b256 = 0x1111111111111111111111111111111111111111111111111111111111111111;

        true
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/results.md

# Results

Examples of if statements in Sway

```sway
contract;

// Result<T, E> = Ok(T) | Err(E)

enum MathError {
    DivByZero: (),
}

fn div(x: u64, y: u64) -> Result<u64, MathError> {
    if y == 0 {
        return Result::Err(MathError::DivByZero);
    }

    Result::Ok(x / y)
}

abi MyContract {
    fn test_div(x: u64, y: u64) -> u64;
}

impl MyContract for Contract {
    fn test_div(x: u64, y: u64) -> u64 {
        let res = div(x, y);
        match res {
            Result::Ok(val) => val,
            Result::Err(err) => revert(0),
        }
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/script.md

# Script

Examples of a script program type in Sway

|                                | Predicates | Scripts  |
|--------------------------------|------------|-----------|
| Access data on chain           |      ❌     |     ✅     |
| Read data from smart contracts |      ❌     |     ✅     |
| Check date or time             |      ❌     |     ✅     |
| Read block hash or number      |      ❌     |     ✅     |
| Read input coins               |      ✅     |     ✅     |
| Read output coins              |      ✅     |     ✅     |
| Read transaction scripts       |      ✅     |     ✅     |
| Read transaction bytecode      |      ✅     |     ✅     |

```sway
script;

abi ContractA {
    fn test_func(x: u64) -> Identity;
}

const CONTRACTA_ID = 0x79fa8779bed2f36c3581d01c79df8da45eee09fac1fd76a5a656e16326317ef0;

fn main(a: u64) {
    let c = abi(ContractA, CONTRACTA_ID);

    // Call a contract multiple times
    log(c.test_func(a));
    log(c.test_func(a + 32));
}

```


---

### File: docs/sway-by-example-lib/docs/src/solidity.md

# Solidity

A quick `Solidity` → `Sway` cross reference for the most commonly used items

- block.timestamp
- msg.sender
- etc

If something is missing here you can most likely find it in the Sway STD Library

```sway
contract;

use std::{
    identity::Identity,
    block::{ height, timestamp },
    auth::msg_sender,
    hash::*,
    constants::*,
};

abi SolidityCheatsheet {
    fn get_blocknumber() -> u32;
    fn get_blocktime() -> u64;
    fn get_msg_sender() -> Identity;
    fn get_bytes32() -> b256;
    fn get_hash() -> b256;
    fn get_u256_number() -> u256;
}

impl SolidityCheatsheet for Contract {
    fn get_blocknumber() -> u32 {
        return height(); // block.number equivalent
    }
    
    fn get_blocktime() -> u64 {
        return timestamp(); // block.timestamp equivalent
    }
    
    fn get_msg_sender() -> Identity {
        return msg_sender().unwrap(); // msg.sender equivalent
    }
    
    fn get_bytes32() -> b256 {
        return 45.as_u256().as_b256(); // u64 to u256 to b256
    }
    
    fn get_hash() -> b256 {
        return sha256("Sway is the way"); // hashing of fixed size string
    }

    fn get_u256_number() -> u256 {
        return u256::from((u64::min(), u64::min(), u64::min(), u64::min())); // big number equivalent
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/src20.md

# SRC20

Examples of a SRC 20 contract in Sway

```sway
contract;

use standards::src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent,};
use std::{auth::msg_sender, string::String};

configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

impl SRC20 for Contract {
    /// Returns the total number of individual assets minted by a contract.
    ///
    /// # Additional Information
    ///
    /// For this single asset contract, this is always one.
    ///
    /// # Returns
    ///
    /// * [u64] - The number of assets that this contract has minted.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let assets = src_20_abi.total_assets();
    ///     assert(assets == 1);
    /// }
    /// ```
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    /// Returns the total supply of coins for the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the total supply, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u64>] - The total supply of an `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let supply = src_20_abi.total_supply(DEFAULT_SUB_ID);
    ///     assert(supply.unwrap() != 0);
    /// }
    /// ```
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }

    /// Returns the name of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the name, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The name of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let name = src_20_abi.name(DEFAULT_SUB_ID);
    ///     assert(name.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    /// Returns the symbol of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the symbol, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The symbol of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let symbol = src_20_abi.symbol(DEFAULT_SUB_ID);
    ///     assert(symbol.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    /// Returns the number of decimals the asset uses.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the decimals, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u8>] - The decimal precision used by `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let decimals = src_20_abi.decimals(DEFAULT_SUB_ID);
    ///     assert(decimals.unwrap() == 9u8);
    /// }
    /// ```
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();

        log(SetNameEvent {
            asset,
            name: Some(String::from_ascii_str(from_str_array(NAME))),
            sender,
        });

        log(SetSymbolEvent {
            asset,
            symbol: Some(String::from_ascii_str(from_str_array(SYMBOL))),
            sender,
        });

        log(SetDecimalsEvent {
            asset,
            decimals: DECIMALS,
            sender,
        });

        log(TotalSupplyEvent {
            asset,
            supply: TOTAL_SUPPLY,
            sender,
        });
    }
}
```


---

### File: docs/sway-by-example-lib/docs/src/storage-map.md

# Storage Map

Examples of storage map in Sway

```sway
contract;

use std::{
    hash::Hash,
    auth::msg_sender
};

// StorageMap
// - basic (insert, read, update, remove)
// - nested

abi MyContract {
    #[storage(read, write)]
    fn basic_examples();

    #[storage(read, write)]
    fn nested_examples();
}

storage {
    balance_of: StorageMap<Identity, u64> = StorageMap {},
    allowance: StorageMap<(Identity, Identity), u64> = StorageMap {},
}

const ADDR: b256 = 0x1000000000000000000000000000000000000000000000000000000000000000;

impl MyContract for Contract {
    #[storage(read, write)]
    fn basic_examples() {
        let sender = msg_sender().unwrap();

        // Insert
        storage.balance_of.insert(sender, 123);
        // Read
        let bal = storage.balance_of.get(sender).try_read().unwrap_or(0);
        // Update
        storage.balance_of.insert(sender, bal + 1);
        // Remove
        storage.balance_of.remove(sender);
    }

    #[storage(read, write)]
    fn nested_examples() {
        let sender = msg_sender().unwrap();
        let spender = Identity::Address(Address::from(ADDR));

        // Read
        let val = storage.allowance.get((sender, spender)).try_read().unwrap_or(0);
        // Insert / update
        storage.allowance.insert((sender, spender), val + 1);
        // Remove
        storage.allowance.remove((sender, spender));
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/structs.md

# Structs

Examples of structs in Sway

```sway
contract;

// Structs
// - Create, read and update
// - Shorthand notation
// - Destructure

struct Point {
    x: u64,
    y: u64,
}

// Nested struct
struct Line {
    p0: Point,
    p1: Point,
}

abi MyContract {
    fn test_func() -> Line;
}

impl MyContract for Contract {
    fn test_func() -> Line {
        // Create, read and update
        let mut p0 = Point { x: 1, y: 2 };

        p0.x = 11;

        // Shorthand
        let x: u64 = 123;
        let y: u64 = 123;

        let p1 = Point { x, y };

        // Nested structs
        let line = Line { p0, p1 };

        // Destructure
        let Line {
            p0: Point { x: x0, y: y0 },
            p1: Point { x: x1, y: y1l },
        } = line;

        line
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/tuples.md

# Tuples

Examples of tuples in Sway

```sway
contract;

// Tuples
// - Create, read, update
// - Nested
// - Destructure and "_"

abi MyContract {
    fn test_func() -> (u64, (str, bool));
}

impl MyContract for Contract {
    fn test_func() -> (u64, (str, bool)) {
        let mut tuple: (u64, bool, u64) = (1, false, 2);
        tuple.0 = 123;
        let x = tuple.0;

        let nested = (1, ("Fuel", false));
        let s = nested.1.0;

        let (n, (s, b)) = nested;
        // Skip variables for 0 and 1.1 
        let (_, (s, _)) = nested;

        nested
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/variables.md

# Variables

Examples of variables in Sway

```sway
contract;

abi MyContract {
    fn test_func() -> u64;
}

impl MyContract for Contract {
    fn test_func() -> u64 {
        // Immutable
        // 0 <= u64 <= 2**64 - 1
        let x = 5;
        // Cannot re-assign x to another value
        // x = 6;

        // Mutable
        let mut y = 5;
        y = 6;

        // Type annotations
        let i: u32 = 123;

        y
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/vector.md

# Vector

Examples of vectors in Sway

```sway
contract;

use std::{storage::storage_vec::*};

// storage vector, heap

abi MyContract {
    #[storage(read, write)]
    fn storage_vec_examples();
    fn heap_vec_examples();
}

storage {
    nums: StorageVec<u64> = StorageVec {},
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn storage_vec_examples() {
        // push
        // pop
        // get
        // set
        // remove - moves all elements down by one 
        // swap remove - remove element, move last element
        // len
        // clear - sets length to zero
        // loop

        // push
        storage.nums.push(100);
        storage.nums.push(200);
        storage.nums.push(300);
        storage.nums.push(400);
        storage.nums.push(500);
        storage.nums.push(600);

        // pop - remove last - returns Option<num>
        let last = storage.nums.pop();

        // get
        let first = storage.nums.get(0).unwrap();
        let none = storage.nums.get(1000);

        // set
        storage.nums.set(0, 123);

        // remove - Returns value removed
        // Before remove [100, 200, 300, 400]
        // After  remove [100, 300, 400]
        let removed_val = storage.nums.remove(1);

        // swap remove
        // Before swap_remove [100, 300, 400, 500]
        // After  swap_remove [100, 500, 400]
        storage.nums.swap_remove(1);

        let len = storage.nums.len();

        // clear - sets length to zero
        storage.nums.clear();

        // Loop example
        let mut i = 0;
        while i < len {
            let val = storage.nums.get(i).unwrap();
            i += 1;
        }
    }

    fn heap_vec_examples() {
        // new
        // push
        // pop
        // remove
        // get
        // set
        // len
        let mut v: Vec<u64> = Vec::new();

        v.push(100);
        v.push(200);
        v.push(300);
        v.push(400);
        v.push(500);

        // Returns Option<u64>
        v.pop();

        // Before remove [100, 200, 300, 400]
        // After  remove [100, 300, 400]
        // Returns removed element
        v.remove(1);

        let val = v.get(1).unwrap();

        v.set(1, val + 1);

        let len = v.len();
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/verify-signature.md

# Verifying Signatures in Sway

Example of how to verify signatures in Sway

```sway
contract;

use std::hash::*;
use std::ecr::{ec_recover_address, EcRecoverError};
use std::bytes::Bytes;
use std::b512::B512;
use std::constants::ZERO_B256;
use std::codec::encode;

abi VerifySignature {
    fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256;
    fn GetEthSignedMessageHash(message_hash: b256) -> b256;
    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256;
    fn verify(signer: b256, to: b256, amount: u64, message: str, nonce: u64, signature: B512) -> bool;
    
}

fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256 {
        keccak256({
        let mut bytes = Bytes::new();
        bytes.append(Bytes::from(encode(to)));
        bytes.append(Bytes::from(encode(amount)));
        bytes.append(Bytes::from(encode(message)));
        bytes.append(Bytes::from(encode(nonce)));
        bytes
    })
    }

    fn GetEthSignedMessageHash(message_hash: b256) -> b256 {
        keccak256({
        let mut bytes = Bytes::new();
        bytes.append(Bytes::from(encode("\x19Fuel Signed Message:\n32")));
        bytes.append(Bytes::from(encode(message_hash)));
        bytes
    })
    }

    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256 {
        match ec_recover_address(signature, eth_signed_message_hash) {
            Ok(address) => address.bits(),
            Err(_) => ZERO_B256,
        }
    }

impl VerifySignature for Contract {


    fn GetMessageHash(to: b256, amount: u64, message: str, nonce: u64) -> b256{
        ::GetMessageHash(to, amount, message, nonce)
    }

    fn GetEthSignedMessageHash(message_hash: b256) -> b256 {
        ::GetEthSignedMessageHash(message_hash)
    }

    fn RecoverSigner(eth_signed_message_hash: b256, signature: B512) -> b256{
        ::RecoverSigner(eth_signed_message_hash, signature)
    }
    
   fn verify(signer: b256, to: b256, amount: u64, message: str, nonce: u64, signature: B512) -> bool {   
        let MessageHash = GetMessageHash(to, amount, message, nonce);
        let EthSignedMessage = GetEthSignedMessageHash(MessageHash);
        let RecoverSigner = RecoverSigner(EthSignedMessage, signature);
        RecoverSigner == signer
    }
}

```


---

### File: docs/sway-by-example-lib/docs/src/while-loop.md

# While Loop

Examples of while loop in Sway

```sway
contract;

// While loops
// continue and break

abi MyContract {
    fn example_1() -> u64;
    fn example_2() -> u64;
    fn example_3() -> u64;
}

impl MyContract for Contract {
    fn example_1() -> u64 {
        let mut total = 0;
        let mut i = 0;
        while i < 5 {
            i += 1;
            total += i;
        }

        // total = 1 + 2 + 3 + 4 + 5
        total
    }

    fn example_2() -> u64 {
        // continue - sum odds
        let mut total = 0;
        let mut i = 0;
        while i < 5 {
            i += 1;
            // Skip if even
            if i % 2 == 0 {
                continue;
            }
            total += i;
        }

        // total = 1 + 3 + 5
        total
    }

    fn example_3() -> u64 {
        // break
        let mut total = 0;
        let mut i = 0;
        while i < 5 {
            i += 1;
            if i > 3 {
                // Exit loop
                break;
            }
            total += i;
        }

        // total = 1 + 2 + 3
        total
    }
}

```


---

### File: docs/sway-libs/docs/book/src/admin/index.md

# Admin Library

The Admin library provides a way to block users without an "administrative status" from calling functions within a contract. The Admin Library differs from the [Ownership Library](../ownership/index.md) as multiple users may have administrative status. The Admin Library is often used when needing administrative calls on a contract that involve multiple users or a whitelist.

This library extends the [Ownership Library](../ownership/index.md). The Ownership library must be imported and used to enable the Admin library. Only the contract's owner may add and remove administrative users.

For implementation details on the Admin Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/admin/admin/).

## Importing the Admin Library

In order to use the Admin Library, the Admin and the Ownership Libraries must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Admin and the Ownership Libraries as dependencies to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add admin@0.26.0
forc add ownership@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Admin Library, be sure to include both the Admin and Ownership Libraries in your import statements.

```sway
use {admin::*, ownership::*};
```

## Integrating the Admin Library into the Ownership Library

To use the Admin library, be sure to set a contract owner for your contract. The following demonstrates setting a contract owner using the [Ownership Library](../ownership/).

```sway
use {admin::add_admin, ownership::initialize_ownership};

#[storage(read, write)]
fn my_constructor(new_owner: Identity) {
    initialize_ownership(new_owner);
}

#[storage(read, write)]
fn add_a_admin(new_admin: Identity) {
    // Can only be called by contract's owner set in the constructor above.
    add_admin(new_admin);
}
```

## Basic Functionality

### Adding an Admin

To add a new admin to a contract, call the `add_admin()` function.

```sway
#[storage(read, write)]
fn add_a_admin(new_admin: Identity) {
    // Can only be called by contract's owner.
    add_admin(new_admin);
}
```

> **NOTE** Only the contract's owner may call this function. Please see the example above to set a contract owner.

### Removing an Admin

To remove an admin from a contract, call the `revoke_admin()` function.

```sway
#[storage(read, write)]
fn remove_an_admin(old_admin: Identity) {
    // Can only be called by contract's owner.
    revoke_admin(old_admin);
}
```

> **NOTE** Only the contract's owner may call this function. Please see the example above to set a contract owner.

### Applying Restrictions

To restrict a function to only an admin, call the `only_admin()` function.

```sway
#[storage(read)]
fn only_owner_may_call() {
    only_admin();
    // Only an admin may reach this line.
}
```

> **NOTE:** Admins and the contract's owner are independent of one another. `only_admin()` will revert if called by the contract's owner.

To restrict a function to only an admin or the contract's owner, call the `only_owner_or_admin()` function.

```sway
#[storage(read)]
fn both_owner_or_admin_may_call() {
    only_owner_or_admin();
    // Only an admin may reach this line.
}
```

### Checking Admin Status

To check the administrative privileges of a user, call the `is_admin()` function.

```sway
#[storage(read)]
fn check_if_admin(admin: Identity) {
    let status = is_admin(admin);
    assert(status);
}
```


---

### File: docs/sway-libs/docs/book/src/asset/base.md

# Base Functionality

For implementation details on the Asset Library base functionality please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/base/index.html).

## Importing the Asset Library Base Functionality

In order to use base functionality the Asset Library, the Asset Library and the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Asset Library and the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add asset@0.26.0
forc add src20@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Asset Library Base Functionality and [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use asset::base::*;
use src20::*;
```

## Integration with the SRC-20 Standard

The [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) definition states that the following abi implementation is required for any Native Asset on Fuel:

```sway
abi SRC20 {
    #[storage(read)]
    fn total_assets() -> u64;
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64>;
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8>;
}
```

The Asset Library has the following complimentary functions for each function in the `SRC20` abi:

- `_total_assets()`
- `_total_supply()`
- `_name()`
- `_symbol()`
- `_decimals()`

The following ABI and functions are also provided to set your [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard storage values:

```sway
abi SetAssetAttributes {
    #[storage(write)]
    fn set_name(asset: AssetId, name: String);
    #[storage(write)]
    fn set_symbol(asset: AssetId, symbol: String);
    #[storage(write)]
    fn set_decimals(asset: AssetId, decimals: u8);
}
```

- `_set_name()`
- `_set_symbol()`
- `_set_decimals()`

> **NOTE** The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions will set the attributes of an asset *unconditionally*. External checks should be applied to restrict the setting of attributes.

## Setting Up Storage

Once imported, the Asset Library's base functionality should be available. To use them, be sure to add the storage block below to your contract which enables the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard.

```sway
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}
```

## Implementing the SRC-20 Standard with the Asset Library

To use the Asset Library's base functionly, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/) standard in combination with the Asset Library with no user defined restrictions or custom functionality.

```sway
use asset::base::{_decimals, _name, _symbol, _total_assets, _total_supply};
use src20::SRC20;
use std::{hash::Hash, storage::storage_string::*, string::String};

// The SRC-20 storage block
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

// Implement the SRC-20 Standard for this contract
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        // Pass the `total_assets` StorageKey to `_total_assets()` from the Asset Library.
        _total_assets(storage.total_assets)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        // Pass the `total_supply` StorageKey to `_total_supply()` from the Asset Library.
        _total_supply(storage.total_supply, asset)
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        // Pass the `name` StorageKey to `_name_()` from the Asset Library.
        _name(storage.name, asset)
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        // Pass the `symbol` StorageKey to `_symbol_()` function from the Asset Library.
        _symbol(storage.symbol, asset)
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        // Pass the `decimals` StorageKey to `_decimals_()` function from the Asset Library.
        _decimals(storage.decimals, asset)
    }
}
```

## Setting an Asset's SRC-20 Attributes

To set some the asset attributes for an Asset, use the `SetAssetAttributes` ABI provided by the Asset Library. The example below shows the implementation of the `SetAssetAttributes` ABI with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetAttributes` ABI to ensure only a single user has permissions to set an Asset's attributes.

The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions follows the SRC-20 standard for logging and will emit their respective log when called.

```sway
use asset::base::*;
use std::{hash::Hash, storage::storage_string::*, string::String};

storage {
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SetAssetAttributes for Contract {
    #[storage(write)]
    fn set_name(asset: AssetId, name: String) {
        _set_name(storage.name, asset, name);
    }

    #[storage(write)]
    fn set_symbol(asset: AssetId, symbol: String) {
        _set_symbol(storage.symbol, asset, symbol);
    }

    #[storage(write)]
    fn set_decimals(asset: AssetId, decimals: u8) {
        _set_decimals(storage.decimals, asset, decimals);
    }
}
```

> **NOTE** The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions will set the attributes of an asset *unconditionally*. External checks should be applied to restrict the setting of attributes.


---

### File: docs/sway-libs/docs/book/src/asset/index.md

# Asset Library

The Asset Library provides basic helper functions for the [SRC-20; Native Asset Standard](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/), [SRC-3; Mint and Burn Standard](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/), and the [SRC-7; Arbitrary Asset Metadata Standard](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/). It is intended to make development of Native Assets using Sway quick and easy while following the standard's specifications.

For implementation details on the Asset Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/).

## [SRC-20 Functionality](./base.md)

The Base or core of any Asset on the Fuel Network must follow the [SRC-20; Native Asset Standard](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/). The Asset Library's [Base](./base.md) section supports the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/)'s implementation.

## [SRC-3 Functionality](supply.md)

The [SRC-3; Mint and Burn Standard](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) prescribes an ABI for how Native Assets on the Fuel Network are minted and burned. The Asset Library's [supply](./supply.md) section supports the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/)'s implementation.

## [SRC-7 Functionality](./metadata.md)

The [SRC-7; Onchain Asset Metadata Standard](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) prescribes an ABI for stateful metadata associated with Native Assets on the Fuel Network. The Asset Library's [metadata](./metadata.md) section supports the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/)'s implementation.


---

### File: docs/sway-libs/docs/book/src/asset/metadata.md

# Metadata Functionality

For implementation details on the Asset Library metadata functionality please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/metadata/index.html).

## Importing the Asset Library Metadata Functionality

In order to use metadata functionality the Asset Library, the Asset Library and the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Asset Library and the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add asset@0.26.0
forc add src7@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Asset Library Base Functionality and [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use asset::metadata::{_metadata, _set_metadata, SetAssetMetadata, StorageMetadata};
use src7::*;
```

## Integration with the SRC-7 Standard

The [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) definition states that the following abi implementation is required for any Native Asset on Fuel which uses stateful metadata:

```sway
abi SRC7 {
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata>;
}
```

The Asset Library has the following complimentary data type for the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard:

- `StorageMetadata`

## Setting Up Storage

Once imported, the Asset Library's metadata functionality should be available. To use them, be sure to add the storage block below to your contract which enables the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard.

```sway
storage {
    metadata: StorageMetadata = StorageMetadata {},
}
```

## Using the `StorageMetadata` Type

### Setting Metadata

As described in the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard, the metadata type is a simple enum of the following types:

- `b256`
- `Bytes`
- `u64`
- `String`

To set some metadata of any of the above types for an Asset, you can use the `SetAssetMetadata` ABI provided by the Asset Library with the `_set_metadata()` function. Be sure to follow the [SRC-9](https://docs.fuel.network/docs/sway-standards/src-9-metadata-keys/) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetMetadata` ABI to ensure only a single user has permissions to set an Asset's metadata.

The `_set_metadata()` function follows the SRC-7 standard for logging and will emit the `SetMetadataEvent` when called.

```sway
use asset::metadata::*;
use src7::Metadata;

storage {
    metadata: StorageMetadata = StorageMetadata {},
}

impl SetAssetMetadata for Contract {
    #[storage(read, write)]
    fn set_metadata(asset: AssetId, key: String, metadata: Metadata) {
        // add your authentication logic here
        // eg. only_owner()
        _set_metadata(storage.metadata, asset, key, metadata);
    }
}
abi CustomSetAssetMetadata {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    );
}

impl CustomSetAssetMetadata for Contract {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    ) {
        let b256_metadata = Metadata::B256(bits256);
        let bytes_metadata = Metadata::Bytes(bytes);
        let int_metadata = Metadata::Int(int);
        let string_metadata = Metadata::String(string);

        // your authentication logic here

        // set whichever metadata you want
        storage.metadata.insert(asset, key, string_metadata);
    }
}
```

> **NOTE** The `_set_metadata()` function will set the metadata of an asset *unconditionally*. External checks should be applied to restrict the setting of metadata.

To set the metadata of an Asset, using only one of the above types, you can define a custom ABI and use it as such:

```sway
abi CustomSetAssetMetadata {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    );
}

impl CustomSetAssetMetadata for Contract {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    ) {
        let b256_metadata = Metadata::B256(bits256);
        let bytes_metadata = Metadata::Bytes(bytes);
        let int_metadata = Metadata::Int(int);
        let string_metadata = Metadata::String(string);

        // your authentication logic here

        // set whichever metadata you want
        storage.metadata.insert(asset, key, string_metadata);
    }
}
```

> **NOTE** The `_set_metadata()` function will set the metadata of an asset *unconditionally*. External checks should be applied to restrict the setting of metadata.

### Implementing the SRC-7 Standard with StorageMetadata

To use the `StorageMetadata` type, simply get the stored metadata with the associated `key` and `AssetId` using the provided `_metadata()` convenience function. The example below shows the implementation of the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard in combination with the Asset Library's `StorageMetadata` type and the `_metadata()` function with no user defined restrictions or custom functionality.

```sway
use asset::metadata::*;
use src7::{Metadata, SRC7};

storage {
    metadata: StorageMetadata = StorageMetadata {},
}

// Implement the SRC-7 Standard for this contract
impl SRC7 for Contract {
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        // Return the stored metadata
        storage.metadata.get(asset, key)
    }
}
```

### Getting Metadata

To get the metadata for an asset, apart from the above mentioned `_metadata()` convenience function, you can also use the `get()` method on the `StorageMetadata` type, which returns the `Metadata` type.

```sway
    use asset::metadata::*; // To access trait implementations you must import everything using the glob operator.
    let metadata: Option<Metadata> = storage.metadata.get(asset, key);
    match metadata.unwrap() {
        Metadata::B256(b256) => {
        // do something with b256
},
        Metadata::Bytes(bytes) => {
        // do something with bytes
},
        Metadata::Int(int) => {
        // do something with int
},
        Metadata::String(string) => {
        // do something with string
},
    }
    let metadata: Metadata = storage.metadata.get(asset, key).unwrap();

    if metadata.is_b256() {
        let b256: b256 = metadata.as_b256().unwrap();
        // do something with b256
    } else if metadata.is_bytes() {
        let bytes: Bytes = metadata.as_bytes().unwrap();
        // do something with bytes
    } else if metadata.is_u64() {
        let int: u64 = metadata.as_u64().unwrap();
        // do something with int
    } else if metadata.is_string() {
        let string: String = metadata.as_string().unwrap();
        // do something with string
    }
```

This results an `Option` type as the metadata may not be set for the asset and key combination.

If you know that the metadata is set, but you don't know the type, you can use a match statement to access the metadata.

```sway
    match metadata.unwrap() {
        Metadata::B256(b256) => {
        // do something with b256
},
        Metadata::Bytes(bytes) => {
        // do something with bytes
},
        Metadata::Int(int) => {
        // do something with int
},
        Metadata::String(string) => {
        // do something with string
},
    }
```

If you know that the metadata is set and you know the type, you can use the `as_*` methods to access the metadata. We also provide `is_*` methods to check if the metadata is of a specific type.

```sway
    let metadata: Metadata = storage.metadata.get(asset, key).unwrap();

    if metadata.is_b256() {
        let b256: b256 = metadata.as_b256().unwrap();
        // do something with b256
    } else if metadata.is_bytes() {
        let bytes: Bytes = metadata.as_bytes().unwrap();
        // do something with bytes
    } else if metadata.is_u64() {
        let int: u64 = metadata.as_u64().unwrap();
        // do something with int
    } else if metadata.is_string() {
        let string: String = metadata.as_string().unwrap();
        // do something with string
    }
```


---

### File: docs/sway-libs/docs/book/src/asset/supply.md

# Supply Functionality

For implementation details on the Asset Library supply functionality please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/asset/asset/supply/index.html).

## Importing the Asset Library Supply Functionality

In order to use the supply functionality of the Asset Library, the Asset Library and the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Asset Library and the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add asset@0.8.0
forc add src3@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Asset Library Supply Functionality and [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use asset::supply::*;
use src3::*;
```

## Integration with the SRC-3 Standard

The [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) definition states that the following abi implementation is required for any Native Asset on Fuel which mints and burns tokens:

```sway
abi SRC3 {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64);
    #[payable]
    #[storage(read, write)]
    fn burn(vault_sub_id: SubId, amount: u64);
}
```

The Asset Library has the following complimentary functions for each function in the `SRC3` abi:

- `_mint()`
- `_burn()`

> **NOTE** The `_mint()` and `_burn()` functions will mint and burn assets *unconditionally*. External checks should be applied to restrict the minting and burning of assets.

## Setting Up Storage

Once imported, the Asset Library's supply functionality should be available. To use them, be sure to add the storage block below to your contract which enables the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard.

```sway
storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}
```

## Implementing the SRC-3 Standard with the Asset Library

To use either function, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard in combination with the Asset Library with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the Asset Library's supply functionality to ensure only a single user has permissions to mint an Asset.

The `_mint()` and `_burn()` functions follows the SRC-20 standard for logging and will emit the `TotalSupplyEvent` when called.

```sway
use asset::supply::{_burn, _mint};
use src3::SRC3;

storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}

// Implement the SRC-3 Standard for this contract
impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        // Pass the StorageKeys to the `_mint()` function from the Asset Library.
        _mint(
            storage
                .total_assets,
            storage
                .total_supply,
            recipient,
            sub_id
                .unwrap_or(b256::zero()),
            amount,
        );
    }

    // Pass the StorageKeys to the `_burn_()` function from the Asset Library.
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        _burn(storage.total_supply, sub_id, amount);
    }
}
```

> **NOTE** The `_mint()` and `_burn()` functions will mint and burn assets *unconditionally*. External checks should be applied to restrict the minting and burning of assets.


---

### File: docs/sway-libs/docs/book/src/bigint/index.md

# Big Integers Library

<!--Include BigInt when BigInt is available-->
The Big Integers library provides a library to use extremely large numbers in Sway. It has 1 distinct types: `BigUint`. These types are heap allocated.

Internally the library uses the `Vec<u64>` type to represent the underlying values of the big integers.

For implementation details on the Big Integers Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/big_int/big_int/).

## Importing the Big Integers Library

In order to use the Big Integers Library, the Big Integers Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Big Integers Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add big_int@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Big Integers Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use big_int::*;
use big_int::BigUint;
```

In order to use any of the Big Integer types, import them into your Sway project like so:

```sway
use big_int::BigUint;
```

## Basic Functionality

<!--Uncomment when BigInt is available-->
<!--All the functionality is demonstrated with the `BigUint` type, but all of the same functionality is available for the other types as well.-->

### Minimum and Maximum Values

For the `BigUint` type, the minimum value is zero. There is no maximum value and the `BigUint` will grow to accommodate as large of a number as needed.

### Instantiating a Big Integer

#### Zero value

Once imported, a `Big Integer` type can be instantiated defining a new variable and calling the `new` function.

```sway
    let mut big_int = BigUint::new();
```

this newly initialized variable represents the value of `0`.

The `new` function is functionally equivalent to the `zero` function.

```sway
    let zero = BigUint::zero();
```

<!--#### Positive and Negative Values

As the signed variants can only represent half as high a number as the unsigned variants (but with either a positive or negative sign), the `try_from` and `neg_try_from` functions will only work with half of the maximum value of the unsigned variant.

You can use the `try_from` function to create a new positive `Big Integer` from a its unsigned variant.

```sway
[Snippet for positive_conversion not found]
```

You can use the `neg_try_from` function to create a new negative `Big Integer` from a its unsigned variant.

```sway
[Snippet for negative_conversion not found]
```
-->

### Basic Mathematical Functions

Basic arithmetic operations are working as usual.

```sway
    let big_uint_1 = BigUint::from(1u64);
    let big_uint_2 = BigUint::from(2u64);

    // Add
    let result: BigUint = big_uint_1 + big_uint_2;

    // Multiply
    let result: BigUint = big_uint_1 * big_uint_2;

    // Subtract
    let result: BigUint = big_uint_2 - big_uint_1;

    // Eq
    let result: bool = big_uint_1 == big_uint_2;

    // Ord
    let result: bool = big_uint_1 < big_uint_2;
```

#### Checking if a Big Integer is Zero

The library also provides a helper function to easily check if a `Big Integer` is zero.

```sway
fn is_zero() {
    let big_int = BigUint::zero();
    assert(big_int.is_zero());
}
```

### Type Conversions

The Big Integers Library offers a number of different conversions between mathematical types. These include the following:

- `u8`
- `u16`
- `u32`
- `u64`
- `U128`
- `u256`
- `Bytes`

To convert any of the above type to a Big Integer, you may use the `From` implementation.

```sway
    // u8
    let u8_big_int = BigUint::from(u8::max());

    // u16
    let u16_big_int = BigUint::from(u16::max());

    // u32
    let u32_big_int = BigUint::from(u32::max());

    // u64
    let u64_big_int = BigUint::from(u64::max());

    // U128
    let u128_big_int = BigUint::from(U128::max());

    // u256
    let u256_big_int = BigUint::from(u256::max());

    // Bytes
    let bytes_big_int = BigUint::from(Bytes::new());
```

To convert back to any of the above types, the `TryInto` implementation will be needed. If the Bit Integer does not fit into the conversion type, `None` will be returned.

```sway
    let big_uint = BigUint::zero();

    // u8
    let u8_result: Option<u8> = <BigUint as TryInto<u8>>::try_into(big_uint);

    // u16
    let u16_result: Option<u16> = <BigUint as TryInto<u16>>::try_into(big_uint);

    // u32
    let u32_result: Option<u32> = <BigUint as TryInto<u32>>::try_into(big_uint);

    // u64
    let u64_result: Option<u64> = <BigUint as TryInto<u64>>::try_into(big_uint);

    // U128
    let u128_big_int: Option<U128> = <BigUint as TryInto<U128>>::try_into(big_uint);

    // u256
    let u256_big_int: Option<u256> = <BigUint as TryInto<u256>>::try_into(big_uint);
```

The only exception is the `Bytes` type, which uses `Into`.

```sway
    // Bytes
    let bytes_big_int: Bytes = <BigUint as Into<Bytes>>::into(big_uint);
```

### Underlying Values

As mentioned previously, the big integers are internally represented by a `Vec<u64>`. To introspect these underlying values you may either get a copy of the data, inspect individual elements, or get the length.

To get a copy of the underlying data, you may call the `limbs()` function. Please note that modifying the copy will have no impact on the Big Integer.

```sway
    let limbs: Vec<u64> = big_int.limbs();
```

To introspect an individual element, you may use the `get_limb()` function.

```sway
    let limb: Option<u64> = big_int.get_limb(0);
```

To get the length of the underlying `Vec<u64>`, call the `number_of_limbs()` function.

```sway
    let number_of_limbs: u64 = big_int.number_of_limbs();
```

And to check whether two Big Integers have the same number of limbs, you may use the `equal_limb_size()` function.

```sway
    let result: bool = big_int_1.equal_limb_size(big_int_2);
```


---

### File: docs/sway-libs/docs/book/src/bytecode/index.md

# Bytecode Library

The Bytecode Library allows for on-chain verification and computation of bytecode roots for contracts and predicates.

A bytecode root for a contract and predicate is the Merkle root of the [binary Merkle tree](https://github.com/FuelLabs/fuel-specs/blob/master/src/protocol/cryptographic-primitives.md#binary-merkle-tree) with each leaf being 16KiB of instructions. This library will compute any contract's or predicate's bytecode root/address allowing for the verification of deployed contracts and generation of predicate addresses on-chain.

For implementation details on the Bytecode Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/bytecode/bytecode/).

## Importing the Bytecode Library

In order to use the Bytecode Library, the Bytecode Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Bytecode Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add bytecode@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Bytecode Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use bytecode::*;
```

## Using the Bytecode Library In Sway

Once imported, using the Bytecode Library is as simple as calling the desired function. Here is a list of function definitions that you may use.

- `compute_bytecode_root()`
- `compute_predicate_address()`
- `predicate_address_from_root()`
- `swap_configurables()`
- `verify_contract_bytecode()`
- `verify_predicate_address()`

## Known Issues

Please note that if you are passing the bytecode from the SDK and are including configurable values, the `Vec<u8>` bytecode provided must be copied to be mutable. The following can be added to make your bytecode mutable:

```sway
fn make_mutable(not_mutable_bytecode: Vec<u8>) {
    // Copy the bytecode to a newly allocated memory to avoid memory ownership error.
    let mut bytecode_slice = raw_slice::from_parts::<u8>(
        alloc_bytes(not_mutable_bytecode.len()),
        not_mutable_bytecode
            .len(),
    );
    not_mutable_bytecode
        .ptr()
        .copy_bytes_to(bytecode_slice.ptr(), not_mutable_bytecode.len());
    let mut bytecode_vec = Vec::from(bytecode_slice);
    // You may now use `bytecode_vec` in your computation and verification function calls
}
```

## Basic Functionality

The examples below are intended for internal contract calls. If you are passing bytecode from the SDK, please follow the steps listed above in known issues to avoid the memory ownership error.

## Swapping Configurables

Given some bytecode, you may swap the configurables of both Contracts and Predicates by calling the `swap_configurables()` function.

```sway
fn swap(
    my_bytecode: Vec<u8>,
    my_configurables: ContractConfigurables,
) {
    let mut my_bytecode = my_bytecode;
    let resulting_bytecode: Vec<u8> = swap_configurables(my_bytecode, my_configurables);
}
```

## Contracts

### Computing the Bytecode Root

To compute a contract's bytecode root you may call the `compute_bytecode_root()` function.

```sway
fn compute_bytecode(
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    let root: BytecodeRoot = compute_bytecode_root(my_bytecode, my_configurables);
}
```

### Verifying a Contract's Bytecode Root

To verify a contract's bytecode root you may call `verify_bytecode_root()` function.

```sway
fn verify_contract(
    my_contract: ContractId,
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    verify_contract_bytecode(my_contract, my_bytecode, my_configurables);
    // By reaching this line the contract has been verified to match the bytecode provided.
}
```

## Predicates

### Computing the Address from Bytecode

To compute a predicate's address you may call the `compute_predicate_address()` function.

```sway
fn compute_predicate(
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    let address: Address = compute_predicate_address(my_bytecode, my_configurables);
}
```

### Computing the Address from a Root

If you have the root of a predicate, you may compute it's corresponding predicate address by calling the `predicate_address_from_root()` function.

```sway
fn predicate_address(my_root: BytecodeRoot) {
    let address: Address = predicate_address_from_root(my_root);
}
```

### Verifying the Address

To verify a predicates's address you may call `verify_predicate_address()` function.

```sway
fn verify_predicate(
    my_predicate: Address,
    my_bytecode: Vec<u8>,
    my_configurables: Option<ContractConfigurables>,
) {
    let mut my_bytecode = my_bytecode;
    verify_predicate_address(my_predicate, my_bytecode, my_configurables);
    // By reaching this line the predicate bytecode matches the address provided.
}
```


---

### File: docs/sway-libs/docs/book/src/getting_started/index.md

# Getting Started

## Adding Sway Libs as a Dependency

To import any library, a dependency should be added to the project's `Forc.toml` file under `[dependencies]`.

```sway
[dependencies]
example = "0.0.0"
```

The library you wish to use may be added as a dependency with the `forc add` command. For example, to import the Ownership Library, use the following `forc` command:

```bash
forc add ownership@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

## Importing Sway Libs to Your Project

Once Sway Libs is a dependency to your project, you may then import a library in your Sway Smart Contract as so:

```sway
use <library>::<library_function>;
```

For example, to import the `only_owner()` from the Ownership Library, use the following statement at the top of your Sway file:

```sway
use ownership::only_owner;
```

> **NOTE:**
> All projects currently use `forc v0.69.0`, `fuels-rs v0.70.0` and `fuel-core v0.44.0`.

## Using Sway Libs

Once the library you require has been imported to your project, you may call or use any functions and structures the library provides.

In the following example, we import the Pausable Library and implement the `Pausable` ABI with it's associated functions.

```sway
use pausable::{_is_paused, _pause, _unpause, Pausable};

// Implement the Pausable ABI for our contract
impl Pausable for Contract {
    #[storage(write)]
    fn pause() {
        _pause(); // Call the provided pause function.
    }

    #[storage(write)]
    fn unpause() {
        _unpause(); // Call the provided unpause function.
    }

    #[storage(read)]
    fn is_paused() -> bool {
        _is_paused() // Call the provided is paused function.
    }
}
```

Any instructions related to using a specific library should be found within the [libraries](../index.md) section of the Sway Libs Book.

<!--
Uncomment this when https://github.com/FuelLabs/sway/pull/7229 is merged.
For implementation details on the libraries please see the [Sway Libs Docs]().
-->


---

### File: docs/sway-libs/docs/book/src/getting_started/running_tests.md

# Running Tests

There are two sets of tests that should be run: inline tests and sdk-harness tests. Please make sure you are using `forc v0.63.3` and `fuel-core v0.34.0`. You can check what version you are using by running the `fuelup show` command.

Make sure you are in the source directory of this repository `sway-libs/<you are here>`.

Run the inline tests:

```bash
forc test --path libs --release --locked
```

Once these tests have passed, run the sdk-harness tests:

```bash
forc test --path tests --release --locked && cargo test --manifest-path tests/Cargo.toml
```

> **NOTE:**
> This may take a while depending on your hardware, future improvements to Sway will decrease build times. After this has been run once, individual test projects may be built on their own to save time.


---

### File: docs/sway-libs/docs/book/src/index.md

# Sway Libraries

The purpose of Sway Libraries is to contain libraries which users can import and use that are not part of the standard library.

There are several types of libraries that Sway Libs encompasses. These include libraries that provide convenience functions, [Sway-Standards](https://github.com/FuelLabs/sway-standards) supporting libraries, data type libraries, security functionality libraries, and other tools valuable to blockchain development.

<!--
Uncomment when https://github.com/FuelLabs/sway/pull/7229 is merged.
For implementation details on the libraries please see the [Sway Libs Docs]().
-->

## Assets Libraries

Asset Libraries are any libraries that use [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on the Fuel Network.

### [Asset Library](./asset/index.md)

The [Asset](./asset/index.md) Library provides helper functions for the [SRC-20](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/), [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/), and [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standards.

## Access Control and Security Libraries

Access Control and Security Libraries are any libraries that are built and intended to provide additional safety when developing smart contracts.

### [Ownership Library](./ownership/index.md)

The [Ownership](./ownership/index.md) Library is used to apply restrictions on functions such that only a **single** user may call them.

### [Admin Library](./admin/index.md)

The [Admin](./admin/index.md) Library is used to apply restrictions on functions such that only a select few users may call them like a whitelist.

### [Pausable Library](./pausable/index.md)

The [Pausable](./pausable/index.md) Library allows contracts to implement an emergency stop mechanism.

### [Reentrancy Guard Library](./reentrancy/index.md)

The [Reentrancy Guard](./reentrancy/index.md) Library is used to detect and prevent reentrancy attacks.

## Cryptography Libraries

Cryptography Libraries are any libraries that provided cryptographic functionality beyond what the std-lib provides.

### [Bytecode Library](./bytecode/index.md)

The [Bytecode](./bytecode/index.md) Library is used for on-chain verification and computation of bytecode roots for contracts and predicates.

### [Merkle Library](./merkle/index.md)

The [Merkle Proof](./merkle/index.md) Library is used to verify Binary and Sparse Merkle Trees computed off-chain.

## Math Libraries

Math Libraries are libraries which provide mathematic functions or number types that are outside of the std-lib's scope.

### [Signed Integers](./signed_integers/index.md)

The [Signed Integers](./signed_integers/index.md) Library is an interface to implement signed integers.

### [Big Integers](./bigint/index.md)

The [Big Integers](./bigint/index.md) Library is an interface to implement extremely large integers.

## Data Structures Libraries

Data Structure Libraries are libraries which provide complex data structures which unlock additional functionality for Smart Contracts.

### [Queue](./queue/index.md)

The [Queue](./queue/index.md) Library is a linear data structure that provides First-In-First-Out (FIFO) operations.

## Upgradability Libraries

Upgradability Libraries are libraries which provide functions to implement contract upgrades.

### [Upgradability](./upgradability/index.md)

The [Upgradability](./upgradability/index.md) Library provides functions that can be used to implement contract upgrades via simple upgradable proxies.


---

### File: docs/sway-libs/docs/book/src/merkle/index.md

# Merkle Library

Merkle trees allow for on-chain verification of off-chain data. With the merkle root posted on-chain, the generation of proofs off-chain can provide verifiably true data.

The Merkle Library currently supports two different tree structures: Binary Trees and Sparse Trees. For information implementation specifications, please refer to the [Merkle Tree Specification](https://docs.fuel.network/docs/specs/protocol/cryptographic-primitives/#merkle-trees).

For implementation details on the Merkle Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/merkle/merkle/).

## Importing the Merkle Library

In order to use the Merkle Library, the Merkle Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Merkle Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add merkle@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Binary Merkle Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use merkle::binary::{leaf_digest, process_proof, verify_proof};
use merkle::common::{MerkleRoot, node_digest, ProofSet};
```

To import the Sparse Merkle Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use merkle::sparse::*;
use merkle::common::{MerkleRoot, ProofSet};
```

## Using the Binary Merkle Proof Library In Sway

Once imported, using the Binary Merkle Proof library is as simple as calling the desired function. Here is a list of function definitions that you may use.

- `leaf_digest()`
- `node_digest()`
- `process_proof()`
- `verify_proof()`

### Binary Sway Functionality

#### Computing Leaves and Nodes of a Binary Tree

The Binary Proof currently allows for you to compute leaves and nodes of a merkle tree given the appropriate hash digest.

To compute a leaf use the `leaf_digest()` function:

```sway
fn compute_leaf(hashed_data: b256) {
    let leaf: b256 = leaf_digest(hashed_data);
}
```

To compute a node given two leaves, use the `node_digest()` function:

```sway
fn compute_node(leaf_a: b256, leaf_b: b256) {
    let node: b256 = node_digest(leaf_a, leaf_b);
}
```

> **NOTE** Order matters when computing a node.

#### Computing the Merkle Root of a Binary Tree

To compute a Merkle root given a proof, use the `process_proof()` function.

```sway
fn process(key: u64, leaf: b256, num_leaves: u64, proof: ProofSet) {
    let merkle_root: MerkleRoot = process_proof(key, leaf, num_leaves, proof);
}
```

#### Verifying the Proof of a Binary Tree

To verify a proof against a merkle root, use the `verify_proof()` function.

```sway
fn verify(
    merkle_root: MerkleRoot,
    key: u64,
    leaf: b256,
    num_leaves: u64,
    proof: ProofSet,
) {
    assert(verify_proof(key, leaf, merkle_root, num_leaves, proof));
}
```

### Using the Binary Merkle Proof Library with Fuels-rs

To generate a Binary Merkle Tree and corresponding proof for your Sway Smart Contract, use the [Fuel-Merkle](https://github.com/FuelLabs/fuel-vm/tree/master/fuel-merkle) crate.

#### Importing Binary Into Your Project

To import the Fuel-Merkle crate, the following should be added to the project's `Cargo.toml` file under `[dependencies]`:

```sway
fuel-merkle = { version = "0.56.0" }
```

> **NOTE** Make sure to use the latest version of the [fuel-merkle](https://crates.io/crates/fuel-merkle) crate.

#### Importing Binary Into Your Rust File

The following should be added to your Rust file to use the Fuel-Merkle crate.

```rust
use fuel_merkle::binary::in_memory::MerkleTree;
```

#### Using Fuel-Merkle's Binary Tree

##### Generating A Binary Tree

To create a merkle tree using Fuel-Merkle is as simple as pushing your leaves in increasing order.

```rust
    // Create a new Merkle Tree and define leaves
    let mut tree = MerkleTree::new();
    let leaves = [b"A", b"B", b"C"].to_vec();

    // Hash the leaves and then push to the merkle tree
    for datum in &leaves {
        let mut hasher = Sha256::new();
        hasher.update(datum);
        let hash = hasher.finalize();
        tree.push(&hash);
    }
```

##### Generating And Verifying A Binary Proof

To generate a proof for a specific leaf, you must have the index or key of the leaf. Simply call the prove function:

```rust
    // Define the key or index of the leaf you want to prove and the number of leaves
    let key: u64 = 0;

    // Get the merkle root and proof set
    let (merkle_root, proof_set) = tree.prove(key).unwrap();

    // Convert the proof set from Vec<Bytes32> to Vec<Bits256>
    let mut bits256_proof: Vec<Bits256> = Vec::new();
    for itterator in proof_set {
        bits256_proof.push(Bits256(itterator));
    }
```

Once the proof has been generated, you may call the Sway Smart Contract's `verify_proof` function:

```rust
    // Create the merkle leaf
    let mut leaf_hasher = Sha256::new();
    leaf_hasher.update(leaves[key as usize]);
    let hashed_leaf_data = leaf_hasher.finalize();
    let merkle_leaf = leaf_sum(&hashed_leaf_data);

    // Get the number of leaves or data points
    let num_leaves: u64 = leaves.len() as u64;

    // Call the Sway contract to verify the generated merkle proof
    let result: bool = contract_instance
        .methods()
        .verify(
            Bits256(merkle_root),
            key,
            Bits256(merkle_leaf),
            num_leaves,
            bits256_proof,
        )
        .call()
        .await
        .unwrap()
        .value;
    assert!(result);
```

## Using the Sparse Merkle Proof Library In Sway

Once imported, using the Sparse Merkle Proof library is as simple as calling the desired function on the `Proof` type. Here is a list of function definitions that you may use.

- `root()`
- `verify()`

To explore additional utility and support functions available, please check out the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/merkle/merkle/).

### Sparse Sway Functionality

#### Computing the Merkle Root of a Sparse Tree

To compute a Sparse Merkle root given a proof, use the `root()` function. You must provide the appropriate `MerkleTreeKey` and leaf data. Please note that the leaf data should be `Some` if you are proving an inclusion proof, and `None` if your are proving an exclusion proof.

```sway
fn compute_root(key: MerkleTreeKey, leaf: Option<Bytes>, proof: Proof) {
    let merkle_root: MerkleRoot = proof.root(key, leaf);
}
```

#### Verifying the Proof of a Sparse Tree

To verify a proof against a merkle root, use the `verify()` function. You must provide the appropriate `MerkleTreeKey`, `MerkleRoot`, and leaf data. Please note that the leaf data should be `Some` if you are proving an inclusion proof, and `None` if your are proving an exclusion proof.

```sway
fn verify_proof(
    root: MerkleRoot,
    key: MerkleTreeKey,
    leaf: Option<Bytes>,
    proof: Proof,
) {
    let result: bool = proof.verify(root, key, leaf);
    assert(result);
}
```

#### Verifying an Inclusion Proof with Hashed Data

If you would like to verify an inclusion proof using only the SHA256 hash of the leaf data rather than the entire `Bytes`, you may do so as shown:

```sway
fn inclusion_proof_hash(key: MerkleTreeKey, leaf: b256, proof: Proof) {
    assert(proof.is_inclusion());

    // Compute the merkle root of an inclusion proof using the sha256 hash of the leaf
    let root: MerkleRoot = proof.as_inclusion().unwrap().root_from_hash(key, leaf);

    // Verifying an inclusion proof using the sha256 hash of the leaf
    let result: bool = proof.as_inclusion().unwrap().verify_hash(root, key, leaf);
    assert(result);
}
```

### Using the Sparse Merkle Proof Library with Fuels-rs

To generate a Sparse Merkle Tree and corresponding proof for your Sway Smart Contract, use the [Fuel-Merkle](https://github.com/FuelLabs/fuel-vm/tree/master/fuel-merkle) crate.

#### Importing Sparse Tree Into Your Project

To import the Fuel-Merkle crate, the following should be added to the project's `Cargo.toml` file under `[dependencies]`:

```sway
fuel-merkle = { version = "0.56.0" }
```

> **NOTE** Make sure to use the latest version of the [fuel-merkle](https://crates.io/crates/fuel-merkle) crate.

#### Importing Sparse Tree Into Your Rust File

The following should be added to your Rust file to use the Fuel-Merkle crate.

```rust
use fuel_merkle::sparse::in_memory::MerkleTree as SparseTree;
use fuel_merkle::sparse::proof::ExclusionLeaf as FuelExclusionLeaf;
use fuel_merkle::sparse::proof::Proof as FuelProof;
use fuel_merkle::sparse::MerkleTreeKey as SparseTreeKey;
use fuels::types::{Bits256, Bytes};
```

#### Using Fuel-Merkle's Sparse Tree

##### Generating A Sparse Tree

To create a merkle tree using Fuel-Merkle is as simple as pushing your leaves in increasing order.

```rust
    // Create a new Merkle Tree and define leaves
    let mut tree = SparseTree::new();
    let leaves = ["A", "B", "C"].to_vec();
    let leaf_to_prove = "A";
    let key = SparseTreeKey::new(leaf_to_prove);

    // Hash the leaves and then push to the merkle tree
    for datum in &leaves {
        let _ = tree.update(SparseTreeKey::new(datum), datum.as_bytes());
    }
```

##### Generating And Verifying A Sparse Proof

To generate a proof for a specific leaf, you must have the index or key of the leaf. Simply call the prove function:

```rust
    // Get the merkle root and proof set
    let root = tree.root();
    let fuel_proof: FuelProof = tree.generate_proof(&key).unwrap();

    // Convert the proof from a FuelProof to the Sway Proof
    let sway_proof: Proof = fuel_to_sway_sparse_proof(fuel_proof);
```

Once the proof has been generated, you may call the Sway Smart Contract's `verify_proof` function:

```rust
    // Call the Sway contract to verify the generated merkle proof
    let result: bool = contract_instance
        .methods()
        .verify(
            Bits256(root),
            Bits256(*key),
            Some(Bytes(leaves[0].into())),
            sway_proof,
        )
        .call()
        .await
        .unwrap()
        .value;

    assert!(result);
```

##### Converting from a Fuel Proof to a Sway Proof

The Rust SDK does not currently support the `Proof` type in Sway and will conflict with the `Proof` type in fuel-merkle. Therefore, you MUST import the `Proof` type from fuel-merkle as `FuelProof`.

To convert between the two types, you may use the following function:

```rust
pub fn fuel_to_sway_sparse_proof(fuel_proof: FuelProof) -> Proof {
    let mut proof_bits: Vec<Bits256> = Vec::new();
    for iterator in fuel_proof.proof_set().iter() {
        proof_bits.push(Bits256(iterator.clone()));
    }

    match fuel_proof {
        FuelProof::Exclusion(exlcusion_proof) => Proof::Exclusion(ExclusionProof {
            proof_set: proof_bits,
            leaf: match exlcusion_proof.leaf {
                FuelExclusionLeaf::Leaf(leaf_data) => ExclusionLeaf::Leaf(ExclusionLeafData {
                    leaf_key: Bits256(leaf_data.leaf_key),
                    leaf_value: Bits256(leaf_data.leaf_value),
                }),
                FuelExclusionLeaf::Placeholder => ExclusionLeaf::Placeholder,
            },
        }),
        FuelProof::Inclusion(_) => Proof::Inclusion(InclusionProof {
            proof_set: proof_bits,
        }),
    }
}
```


---

### File: docs/sway-libs/docs/book/src/ownership/index.md

# Ownership Library

The **Ownership Library** provides a straightforward way to restrict specific calls in a Sway contract to a single _owner_. Its design follows the [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) standard from [Sway Standards](https://docs.fuel.network/docs/sway-standards/) and offers a set of functions to initialize, verify, revoke, and transfer ownership.

For implementation details, visit the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/ownership/ownership/).

## Importing the Ownership Library

In order to use the Ownership Library, the Ownership Library and the [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Ownership Library and the [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add ownership@0.26.0
forc add src5@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Ownership Library and [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/) Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use ownership::*;
use src5::*;
```

## Integrating the Ownership Library into the SRC-5 Standard

When integrating the Ownership Library with [SRC-5](https://docs.fuel.network/docs/sway-standards/src-5-ownership/), ensure that the `SRC5` trait from **Sway Standards** is implemented in your contract, as shown below. The `_owner()` function from this library is used to fulfill the SRC-5 requirement of exposing the ownership state.

```sway
use ownership::_owner;
use src5::{SRC5, State};

impl SRC5 for Contract {
    #[storage(read)]
    fn owner() -> State {
        _owner()
    }
}
```

## Basic Usage

### Setting a Contract Owner

Establishes the initial ownership state by calling `initialize_ownership(new_owner)`. This can only be done once, typically in your contract's constructor.

```sway
#[storage(read, write)]
fn my_constructor(new_owner: Identity) {
    initialize_ownership(new_owner);
}
```

Please note that the example above does not apply any restrictions on who may call the `initialize()` function. This leaves the opportunity for a bad actor to front-run your contract and claim ownership for themselves. To ensure the intended `Identity` is set as the contract owner upon contract deployment, use a `configurable` where the `INITIAL_OWNER` is the intended owner of the contract.

```sway
configurable {
    INITAL_OWNER: Identity = Identity::Address(Address::zero()),
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn initialize() {
        initialize_ownership(INITAL_OWNER);
    }
}
```

### Applying Restrictions

Protect functions so only the owner can call them by invoking `only_owner()` at the start of those functions.

```sway
#[storage(read)]
fn only_owner_may_call() {
    only_owner();
    // Only the contract's owner may reach this line.
}
```

### Checking the Ownership Status

To retrieve the current ownership state, call `_owner()`.

```sway
#[storage(read)]
fn get_owner_state() {
    let owner: State = _owner();
}
```

### Transferring Ownership

To transfer ownership from the current owner to a new owner, call `transfer_ownership(new_owner)`.

```sway
#[storage(read, write)]
fn transfer_contract_ownership(new_owner: Identity) {
    // The caller must be the current owner.
    transfer_ownership(new_owner);
}
```

### Renouncing Ownership

To revoke ownership entirely and disallow the assignment of a new owner, call `renounce_ownership()`.

```sway
#[storage(read, write)]
fn renounce_contract_owner() {
    // The caller must be the current owner.
    renounce_ownership();
    // Now no one owns the contract.
}
```

## Events

### `OwnershipRenounced`

Emitted when ownership is revoked.

- **Fields:**
  - `previous_owner`: Identity of the owner prior to revocation.

### `OwnershipSet`

Emitted when initial ownership is set.

- **Fields:**
  - `new_owner`: Identity of the newly set owner.

### `OwnershipTransferred`

Emitted when ownership is transferred from one owner to another.

- **Fields:**
  - `new_owner`: Identity of the new owner.
  - `previous_owner`: Identity of the prior owner.

## Errors

### `InitializationError`

- **Variants:**
  - `CannotReinitialized`: Thrown when attempting to initialize ownership if the owner is already set.

### `AccessError`

- **Variants:**
  - `NotOwner`: Thrown when a function restricted to the owner is called by a non-owner.

## Example Integration

Below is a example illustrating how to use this library within a Sway contract:

```sway
contract;

use ownership::{_owner, initialize_ownership, only_owner, renounce_ownership, transfer_ownership};
use src5::{SRC5, State};

configurable {
    INITAL_OWNER: Identity = Identity::Address(Address::zero()),
}

impl SRC5 for Contract {
    #[storage(read)]
    fn owner() -> State {
        _owner()
    }
}

abi MyContract {
    #[storage(read, write)]
    fn initialize();
    #[storage(read)]
    fn restricted_action();
    #[storage(read, write)]
    fn change_owner(new_owner: Identity);
    #[storage(read, write)]
    fn revoke_ownership();
    #[storage(read)]
    fn get_current_owner() -> State;
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn initialize() {
        initialize_ownership(INITAL_OWNER);
    }

    // A function restricted to the owner
    #[storage(read)]
    fn restricted_action() {
        only_owner();
        // Protected action
    }

    // Transfer ownership
    #[storage(read, write)]
    fn change_owner(new_owner: Identity) {
        transfer_ownership(new_owner);
    }

    // Renounce ownership
    #[storage(read, write)]
    fn revoke_ownership() {
        renounce_ownership();
    }

    // Get current owner state
    #[storage(read)]
    fn get_current_owner() -> State {
        _owner()
    }
}
```

1. **Initialization:** Call `constructor(new_owner)` once to set the initial owner.  
2. **Restricted Calls:** Use `only_owner()` to guard any owner-specific functions.  
3. **Ownership Checks:** Retrieve the current owner state via `_owner()`.  
4. **Transfer or Renounce:** Use `transfer_ownership(new_owner)` or `renounce_ownership()` for ownership modifications.


---

### File: docs/sway-libs/docs/book/src/pausable/index.md

# Pausable Library

The Pausable library allows contracts to implement an emergency stop mechanism. This can be useful for scenarios such as having an emergency switch to freeze all transactions in the event of a large bug.

It is highly encouraged to use the [Ownership Library](../ownership/index.md) in combination with the Pausable Library to ensure that only a single administrative user has the ability to pause your contract.

For implementation details on the Pausable Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/pausable/pausable/).

## Importing the Pausable Library

In order to use the Pausable library, the Pausable Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Pausable Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add pausable@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Pausable Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use pausable::*;
```

## Basic Functionality

### Implementing the `Pausable` abi

The Pausable Library has two states:

- `Paused`
- `Unpaused`

By default, your contract will start in the `Unpaused` state. To pause your contract, you may call the `_pause()` function. The example below provides a basic pausable contract using the Pausable Library's `Pausable` abi without any restrictions such as an administrator.

```sway
use pausable::{_is_paused, _pause, _unpause, Pausable};

impl Pausable for Contract {
    #[storage(write)]
    fn pause() {
        _pause();
    }

    #[storage(write)]
    fn unpause() {
        _unpause();
    }

    #[storage(read)]
    fn is_paused() -> bool {
        _is_paused()
    }
}
```

## Applying Paused Restrictions

When developing a contract, you may want to lock functions down to a specific state. To do this, you may call either of the `require_paused()` or `require_not_paused()` functions. The example below shows these functions in use.

```sway
use pausable::require_paused;

#[storage(read)]
fn require_paused_state() {
    require_paused();
    // This comment will only ever be reached if the contract is in the paused state
}
```

```sway
use pausable::require_not_paused;

#[storage(read)]
fn require_not_paused_state() {
    require_not_paused();
    // This comment will only ever be reached if the contract is in the unpaused state
}
```

## Using the Ownership Library with the Pausable Library

It is highly recommended to integrate the [Ownership Library](../ownership/index.md) with the Pausable Library and apply restrictions the `pause()` and `unpause()` functions. This will ensure that only a single user may pause and unpause a contract in cause of emergency. Failure to apply this restriction will allow any user to obstruct a contract's functionality.

The follow example implements the `Pausable` abi and applies restrictions to it's pause/unpause functions. The owner of the contract must be set in a constructor defined by `MyConstructor` in this example.

```sway
use pausable::{_is_paused, _pause, _unpause, Pausable};
use ownership::{initialize_ownership, only_owner};

abi MyConstructor {
    #[storage(read, write)]
    fn my_constructor(new_owner: Identity);
}

impl MyConstructor for Contract {
    #[storage(read, write)]
    fn my_constructor(new_owner: Identity) {
        initialize_ownership(new_owner);
    }
}

impl Pausable for Contract {
    #[storage(write)]
    fn pause() {
        // Add the `only_owner()` check to ensure only the owner may unpause this contract.
        only_owner();
        _pause();
    }

    #[storage(write)]
    fn unpause() {
        // Add the `only_owner()` check to ensure only the owner may unpause this contract.
        only_owner();
        _unpause();
    }

    #[storage(read)]
    fn is_paused() -> bool {
        _is_paused()
    }
}
```


---

### File: docs/sway-libs/docs/book/src/queue/index.md

# Queue Library

A Queue is a linear structure which follows the First-In-First-Out (FIFO) principle. This means that the elements added first are the ones that get removed first.

For implementation details on the Queue Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/queue/queue/).

## Importing the Queue Library

In order to use the Queue Library, the Queue Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Queue Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add queue@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Queue Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use queue::*;
```

## Basic Functionality

### Instantiating a New Queue

Once the `Queue` has been imported, you can create a new queue instance by calling the `new` function.

```sway
    let mut queue = Queue::new();
```

## Enqueuing elements

Adding elements to the `Queue` can be done using the `enqueue` function.

```sway
    // Enqueue an element to the queue
    queue.enqueue(10u8);
```

### Dequeuing Elements

To remove elements from the `Queue`, the `dequeue` function is used. This function follows the FIFO principle.

```sway
    // Dequeue the first element and unwrap the value
    let first_item = queue.dequeue().unwrap();
```

### Fetching the Head Element

To retrieve the element at the head of the `Queue` without removing it, you can use the `peek` function.

```sway
    // Peek at the head of the queue
    let head_item = queue.peek();
```

### Checking the Queue's Length

The `is_empty` and `len` functions can be used to check if the queue is empty and to get the number of elements in the queue respectively.

```sway
    // Checks if queue is empty (returns True or False)
    let is_queue_empty = queue.is_empty();

    // Returns length of queue
    let queue_length = queue.len();
```


---

### File: docs/sway-libs/docs/book/src/reentrancy/index.md

# Reentrancy Guard Library

The Reentrancy Guard Library provides an API to check for and disallow reentrancy on a contract. A reentrancy attack happens when a function is externally invoked during its execution, allowing it to be run multiple times in a single transaction.

The reentrancy check is used to check if a contract ID has been called more than once in the current call stack.

A reentrancy, or "recursive call" attack can cause some functions to behave in unexpected ways. This can be prevented by asserting a contract has not yet been called in the current transaction. An example can be found [here](https://swcregistry.io/docs/SWC-107).

For implementation details on the Reentrancy Guard Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/reentrancy/reentrancy/).

## Importing the Reentrancy Guard Library

In order to use the Reentrancy Guard library, the Reentrancy Guard Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Reentrancy Guard Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add reentrancy@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Reentrancy Guard Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use reentrancy::*;
```

## Basic Functionality

Once imported, using the Reentrancy Library can be done by calling one of the two functions:

- `is_reentrant() -> bool`
- `reentrancy_guard()`

### Using the Reentrancy Guard

Once imported, using the Reentrancy Guard Library can be used by calling the `reentrancy_guard()` in your Sway Smart Contract. The following shows a Sway Smart Contract that applies the Reentrancy Guard Library:

```sway
use reentrancy::reentrancy_guard;

abi MyContract {
    fn my_non_reentrant_function();
}

impl MyContract for Contract {
    fn my_non_reentrant_function() {
        reentrancy_guard();

        // my code here
    }
}
```

### Checking Reentrancy Status

To check if the current caller is a reentrant, you may call the `is_reentrant()` function.

```sway
use reentrancy::is_reentrant;

fn check_if_reentrant() {
    assert(!is_reentrant());
}
```

## Cross Contract Reentrancy

Cross-Contract Reentrancy is not possible on Fuel due to the use of Native Assets. As such, no contract calls are performed when assets are transferred. However standard security practices when relying on other contracts for state should still be applied, especially when making external calls.


---

### File: docs/sway-libs/docs/book/src/signed_integers/index.md

# Signed Integers Library

The Signed Integers library provides a library to use signed numbers in Sway. It has 6 distinct types: `I8`, `I16`, `I32`, `I64`, `I128`, `I256`. These types are stack allocated.

Internally the library uses the `u8`, `u16`, `u32`, `u64`, `U128`, `u256` types to represent the underlying values of the signed integers.

For implementation details on the Signed Integers Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/signed_int/signed_int/).

## Importing the Signed Integer Library

In order to use the Signed Integers Library, the Signed Integers Library must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Signed Integers Library as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add signed_int@0.26.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Signed Integers Library to your Sway Smart Contract, add the following to your Sway file:

```sway
use signed_int::*;
use signed_int::i8::I8;
```

In order to use any of the Signed Integer types, import them into your Sway project like so:

```sway
use signed_int::i8::I8;
```

## Basic Functionality

All the functionality is demonstrated with the `I8` type, but all of the same functionality is available for the other types as well.

### Instantiating a Signed Integer

#### Zero value

Once imported, a `Signed Integer` type can be instantiated defining a new variable and calling the `new` function.

```sway
    let mut i8_value = I8::new();
```

this newly initialized variable represents the value of `0`.

The `new` function is functionally equivalent to the `zero` function.

```sway
    let zero = I8::zero();
    let zero = I8::from_uint(128u8);
```

#### Positive and Negative Values

As the signed variants can only represent half as high a number as the unsigned variants (but with either a positive or negative sign), the `try_from` and `neg_try_from` functions will only work with half of the maximum value of the unsigned variant.

You can use the `try_from` function to create a new positive `Signed Integer` from a its unsigned variant.

```sway
    let one = I8::try_from(1u8).unwrap();
```

You can use the `neg_try_from` function to create a new negative `Signed Integer` from a its unsigned variant.

```sway
    let negative_one = I8::neg_try_from(1u8).unwrap();
```

#### With underlying value

As mentioned previously, the signed integers are internally represented by an unsigned integer, with its values divided into two halves, the bottom half of the values represent the negative values and the top half represent the positive values, and the middle value represents zero.

Therefore, for the lowest value representable by a i8, `-128`, the underlying value would be `0`.

```sway
    let neg_128 = I8::from_uint(0u8);
```

For the zero value, the underlying value would be `128`.

```sway
    let zero = I8::from_uint(128u8);
```

And for the highest value representable by a i8, `127`, the underlying value would be `255`.

```sway
    let pos_127 = I8::from_uint(255u8);
```

#### Minimum and Maximum Values

To get the minimum and maximum values of a signed integer, use the `min` and `max` functions.

```sway
    let min = I8::MIN;
```

```sway
    let max = I8::MAX;
```

### Basic Mathematical Functions

Basic arithmetic operations are working as usual.

```sway
fn add_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 + val2;
}

fn subtract_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 - val2;
}

fn multiply_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 * val2;
}

fn divide_signed_int(val1: I8, val2: I8) {
    let result: I8 = val1 / val2;
}
```

#### Checking if a Signed Integer is Zero

The library also provides a helper function to easily check if a `Signed Integer` is zero.

```sway
fn is_zero() {
    let i8 = I8::zero();
    assert(i8.is_zero());
}
```

## Known Issues

The current implementation of `U128` will compile large bytecode sizes when performing mathematical computations. As a result, `I128` and `I256` inherit the same issue and could cause high transaction costs. This should be resolved with future optimizations of the Sway compiler.


---

### File: docs/sway-libs/docs/book/src/upgradability/index.md

# Upgradability Library

The Upgradability Library provides functions that can be used to implement contract upgrades via simple upgradable proxies. The Upgradability Library implements the required and optional functionality from [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) as well as additional functionality for ownership of the proxy contract.

For implementation details on the Upgradability Library please see the [Sway Libs Docs](https://fuellabs.github.io/sway-libs/master/sway_libs/upgradability/upgradability/).

## Importing the Upgradability Library

In order to use the Upgradability Library, the Upgradability Library and the [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) Standard must be added to your `Forc.toml` file and then imported into your Sway project.

To add the Upgradability Library and the [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) Standard as a dependency to your `Forc.toml` file in your project, use the `forc add` command.

```bash
forc add upgradability@0.26.0
forc add src14@0.8.0
```

> **NOTE:** Be sure to set the version to the latest release.

To import the Upgradability Library and  Standard to your Sway Smart Contract, add the following to your Sway file:

```sway
use upgradability::*;
use src14::*;
use src5::*;
```

## Integrating the Upgradability Library into the SRC-14 Standard

To implement the [SRC-14](https://docs.fuel.network/docs/sway-standards/src-14-simple-upgradeable-proxies/) standard with the Upgradability library, be sure to add the Sway Standards dependency to your contract. The following demonstrates the integration of the Ownership library with the SRC-14 standard.

```sway
use upgradability::{_proxy_owner, _proxy_target, _set_proxy_target};
use src14::{SRC14, SRC14Extension};
use src5::State;

storage {
    SRC14 {
        /// The [ContractId] of the target contract.
        ///
        /// # Additional Information
        ///
        /// `target` is stored at sha256("storage_SRC14_0")
        target in 0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55: Option<ContractId> = None,
        /// The [State] of the proxy owner.
        ///
        /// # Additional Information
        ///
        /// `proxy_owner` is stored at sha256("storage_SRC14_1")
        proxy_owner in 0xbb79927b15d9259ea316f2ecb2297d6cc8851888a98278c0a2e03e1a091ea754: State = State::Uninitialized,
    },
}

impl SRC14 for Contract {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId) {
        _set_proxy_target(new_target);
    }

    #[storage(read)]
    fn proxy_target() -> Option<ContractId> {
        _proxy_target()
    }
}

impl SRC14Extension for Contract {
    #[storage(read)]
    fn proxy_owner() -> State {
        _proxy_owner()
    }
}
```

> **NOTE** An initialization method must be implemented to initialize the proxy target or proxy owner.

## Basic Functionality

### Setting and getting a Proxy Target

Once imported, the Upgradability Library's functions will be available. Use them to change the proxy target for your contract by calling the `set_proxy_target()` function.

```sway
#[storage(read, write)]
fn set_proxy_target(new_target: ContractId) {
    _set_proxy_target(new_target);
}
```

Use the `proxy_target()` method to get the current proxy target.

```sway
#[storage(read)]
fn proxy_target() -> Option<ContractId> {
    _proxy_target()
}
```

### Setting and getting a Proxy Owner

To change the proxy target for your contract use the `set_proxy_owner()` function.

```sway
#[storage(write)]
fn set_proxy_owner(new_proxy_owner: State) {
    _set_proxy_owner(new_proxy_owner);
}
```

Use the `proxy_owner()` method to get the current proxy owner.

```sway
#[storage(read)]
fn proxy_owner() -> State {
    _proxy_owner()
}
```

### Proxy access control

To restrict a function to only be callable by the proxy's owner, call the `only_proxy_owner()` function.

```sway
#[storage(read)]
fn only_proxy_owner_may_call() {
    only_proxy_owner();
    // Only the proxy's owner may reach this line.
}
```


---

### File: docs/sway-standards/docs/src/index.md

# Sway Standards

The purpose of the Sway Standards [repository](https://github.com/FuelLabs/sway-standards) is to contain standards for the Sway Language which users can import and use.

Standards in this repository may be in various stages of development. Use of draft standards and feedback on the proposed standards is encouraged. To use a draft, search for a standard using the appropriate GitHub label and implement the standard ABI into your contract.

If you don't find what you're looking for, feel free to create an issue and propose a new standard!

> **Note**
> All standards currently use `forc v0.69.0`.

## Using a standard

To import any standard, a dependency should be added to the project's `Forc.toml` file under `[dependencies]`.

```sway
[dependencies]
example = "0.0.0"
```

The standard you wish to use may be added as a dependency with the `forc add` command. For example, to import the SRC-20 Standard, use the following `forc` command:

```bash
forc add src20@0.8.0
```

> **NOTE:**
> Be sure to set the tag to the latest release.

You may then import your desired standard in your Sway Smart Contract as so:

```sway
use <standard>::<standard_abi>;
```

For example, to import the SRC-20 Native Asset Standard use the following statement in your Sway Smart Contract file:

```sway
use src20::SRC20;
```

## Standards

### Native Assets

- [SRC-20; Native Asset Standard](./src-20-native-asset.md) defines the implementation of a standard API for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) using the Sway Language.
- [SRC-3; Mint and Burn](./src-3-minting-and-burning.md) is used to enable mint and burn functionality for fungible assets.
- [SRC-6; Vault Standard](./src-6-vault.md) defines the implementation of a standard API for asset vaults developed in Sway.
- [SRC-13; Soulbound Address](./src-13-soulbound-address.md) defines the implementation of a soulbound address.

### Onchain Data

- [SRC-7; Onchain Asset Metadata Standard](./src-7-asset-metadata.md) is used to store metadata for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets).
- [SRC-9; Metadata Keys Standard](./src-9-metadata-keys.md) is used to store standardized metadata keys for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) in combination with the SRC-7 standard.

### Offchain Data

- [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md) is used to associated metadata with [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) offchain.
- [SRC-17; Naming Verification Standard](./src-17-naming-verification.md) defines a naming verification standard for onchain identities using offchain data.

### Security and Access Control

- [SRC-5; Ownership Standard](./src-5-ownership.md) is used to restrict function calls to admin users in contracts.
- [SRC-11; Security Information Standard](./src-11-security-information.md) is used to make communication information readily available in the case white hat hackers find a vulnerability in a contract.

### Contracts

- [SRC-12; Contract Factory](./src-12-contract-factory.md) defines the implementation of a standard API for contract factories.
- [SRC-14; Simple Upgradeable Proxies](./src-14-simple-upgradeable-proxies.md) defines the implementation of an upgradeable proxy contract.

### Bridge

- [SRC-8; Bridged Asset](./src-8-bridged-asset.md) defines the metadata required for an asset bridged to the Fuel Network.
- [SRC-10; Native Bridge Standard](./src-10-native-bridge.md) defines the standard API for the Native Bridge between the Fuel Chain and the canonical base chain.

### Encoding and hashing

- [SRC-16; Typed Structured Data](./src-16-typed-structured-data.md) defines standard encoding and hashing of typed structured data.

### Documentation

- [SRC-2; Inline Documentation](./src-2-inline-documentation.md) defines how to document your Sway files.


---

### File: docs/sway-standards/docs/src/src-10-native-bridge.md

# SRC-10: Native Bridge

The following standard allows for the implementation of a standard API for Native Bridges using the Sway Language. The standardized design has the bridge contract send a message to the origin chain to register which token it accepts to prevent a loss of funds.

## Motivation

A standard interface for bridges intends to provide a safe and efficient bridge between the settlement or canonical chain and the Fuel Network.

## Prior Art

The standard is centered on Fuel’s [Bridge Architecture](https://github.com/FuelLabs/fuel-bridge/blob/main/docs/ARCHITECTURE.md). Fuel's bridge system is built on a message protocol that allows to send (and receive) messages between entities located in two different blockchains.

The following standard takes reference from the [`FungibleBridge`](https://github.com/FuelLabs/fuel-bridge/blob/3971081850e7961d9b649edda4cad8a848ee248e/packages/fungible-token/bridge-fungible-token/src/interface.sw#L22) ABI defined in the fuel-bridge repository.

## Specification

The following functions MUST be implemented to follow the SRC-10; Native Bridge Standard:

### Required Functions

**`fn process_message(message_index: u64)`**

The `process_message()` function accepts incoming deposit messages from the canonical chain and issues the corresponding bridged asset.

- This function MUST parse a message at the given `message_index` index.
- This function SHALL mint an asset that follows the [SRC-8; Bridged Asset Standard](./src-8-bridged-asset.md).
- This function SHALL issue a refund if there is an error in the bridging process.

**`fn withdraw(to_address: b256)`**

The `withdraw()` function accepts and burns a bridged Native Asset on Fuel and sends a message to the bridge contract on the canonical chain to release the originally deposited tokens to the `to_address` address.

- This function SHALL send a message to the bridge contract to release the bridged tokens to the `to_address` address on the canonical chain.
- This function MUST ensure the asset's `AssetId` sent in the transaction matches a bridged asset.
- This function SHALL burn all coins sent in the transaction.

**`fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256)`**

The `claim_refund()` function is called if something goes wrong in the bridging process and an error occurs. It sends a message to the `gateway_contract` contract on the canonical chain to release the `token_address` token with token id `token_id` to the `to_address` address.

- This function SHALL send a message to the `gateway_contract` contract to release the `token_address` token with id `token_id` to the `to_address` address on the canonical chain.
- This function MUST ensure a refund was issued.

### Required Data Types

#### `DepositType`

The `DepositType` enum describes whether the bridged deposit is made to a address, contract, or contract and contains additional metadata. There MUST be the following variants in the `DepositType` enum:

**`Address`: `()`**

The `Address` variant MUST represent when the deposit is made to an address on the Fuel chain.

**`Contract`: `()`**

The `Contract` variant MUST represent when the deposit is made to an contract on the Fuel chain.

**`ContractWithData`: `()`**

The `ContractWithData` variant MUST represent when the deposit is made to an contract and contains additional metadata for the Fuel chain.

##### Example Deposit Type

```sway
pub enum DepositType {
    Address: (),
    Contract: (),
    ContractWithData: (),
}
```

#### `DepositMessage`

The following describes a struct that encapsulates various deposit message metadata to a single type. There MUST be the following fields in the `DepositMessage` struct:

**`amount`: `u256`**

The `amount` field MUST represent the number of tokens.

**`from`: `b256`**

The `from` field MUST represent the bridging user’s address on the canonical chain.

**`to`: `Identity`**

The `to` field MUST represent the bridging target destination `Address` or `ContractId` on the Fuel Chain.

**`token_address`: `b256`**

The `token_address` field MUST represent the bridged token's address on the canonical chain.

**`token_id`: `b256`**

The `token_id` field MUST represent the token's ID on the canonical chain. The `b256::zero()` MUST be used if this is a fungible token and no token ID exists.

**`decimals`: `u8`**

The `decimals` field MUST represent the bridged token's decimals on the canonical chain.

**`deposit_type`: `DepositType`**

The `deposit_type` field MUST represent the type of bridge deposit made on the canonical chain.

##### Example Deposit Message

```sway
pub struct DepositMessage {
    pub amount: b256,
    pub from: b256,
    pub to: Identity,
    pub token_address: b256,
    pub token_id: b256,
    pub decimals: u8,
    pub deposit_type: DepositType,
}
```

#### `MetadataMessage`

The following describes a struct that encapsulates the metadata of token on the canonical chain to a single type. There MUST be the following fields in the `MetadataMessage` struct:

**`token_address`: `b256`**

The `token_address` field MUST represent the bridged token's address on the canonical chain.

**`token_id`: `b256`**

The `token_id` field MUST represent the token's ID on the canonical chain. The `b256::zero()` MUST be used if this is a fungible token and no token ID exists.

**`name`: `String`**

The `name` field MUST represent the bridged token's name field on the canonical chain.

**`symbol`: `String`**

The `symbol` field MUST represent the bridged token's symbol field on the canonical chain.

##### Example Metadata Message

```sway
pub struct MetadataMessage {
    pub token_address: b256,
    pub token_id: b256,
    pub name: String,
    pub symbol: String,
}
```

## Required Standards

Any contract that implements the SRC-10; Native Bridge Standard MUST implement the [SRC-8; Bridged Asset Standard](./src-8-bridged-asset.md) for all bridged assets.

## Rationale

The SRC-10; Native Bridge Standard is designed to standardize the native bridge interface between all Fuel instances.

## Backwards Compatibility

This standard is compatible with the SRC-20 and SRC-8 standards.

## Example ABI

```sway
abi SRC10 {
     fn process_message(message_index: u64);
     fn withdraw(to_address: b256);
     fn claim_refund(to_address: b256, token_address: b256, token_id: b256, gateway_contract: b256);
}
```


---

### File: docs/sway-standards/docs/src/src-11-security-information.md

# SRC-11: Security Information

The following standard allows for contract creators to make communication information readily available to everyone, with the primary purpose of allowing white hat hackers to coordinate a bug-fix or securing of funds.

## Motivation

White hat hackers may find bugs or exploits in contracts that they want to report to the project for safeguarding of funds. It is not immediately obvious from a `ContractId`, who the right person to contact is. This standard aims to make the process of bug reporting as smooth as possible.

## Prior Art

The [`security.txt`](https://github.com/neodyme-labs/solana-security-txt) library for Solana has explored this idea. This standard takes inspiration from the library, with some changes.

## Specification

### Security Information Type

The following describes the `SecurityInformation` type.

- The struct MAY contain `None` for `Option<T>` type fields, if they are deemed unnecessary.
- The struct MUST NOT contain empty `String` or `Vec` fields.
- The struct MAY contain a URL or the information directly for the following fields: `project_url`, `policy`, `encryption`, `source_code`, `auditors`, `acknowledgments`, `additional_information`.
- The struct MUST contain the information directly for the following fields: `name`, `contact_information`, `preferred_languages`, `source_release`, and `source_revision`.
- The struct MUST contain at least one item in the `preferred_languages` field's `Vec`, if it is not `None`. Furthermore, the string should only contain the [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) language code and nothing else.
- The struct MUST contain at least one item in the `contact_information` field's `Vec`. Furthermore, the string should follow the following format `<contact_type>:<contact_information>`. Where `contact_type` describes the method of contact (e.g. `email` or `discord`) and `contact_information` describes the information needed to contact (e.g. `example@example.com` or `@EXAMPLE`).

#### `name: String`

The name of the project that the contract is associated with.

#### `project_url: Option<String>`

The website URL of the project that the contract is associated with.

#### `contact_information: Vec<String>`

A list of contact information to contact developers of the project. Should be in the format `<contact_type>:<contact_information>`. You should include contact types that will not change over time.

#### `policy: String`

Text describing the project's security policy, or a link to it. This should describe what kind of bounties your project offers and the terms under which you offer them.

#### `preferred_languages: Option<Vec<String>>`

A list of preferred languages [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes).
If the field is not `None`, it MUST contain at least one item.

#### `encryption: Option<String>`

A PGP public key block (or similar) or a link to one.

#### `source_code: Option<String>`

A URL to the project's source code.

#### `source_release: Option<String>`

The release identifier of this build, ideally corresponding to a tag on git that can be rebuilt to reproduce the same binary. 3rd party build verification tools will use this tag to identify a matching GitHub release.

#### `source_revision: Option<String>`

The revision identifier of this build, usually a git commit hash that can be rebuilt to reproduce the same binary. 3rd party build verification tools will use this tag to identify a matching GitHub release.

#### `auditors: Option<Vec<String>>`

A list of people or entities that audited this smart contract, or links to pages where audit reports are hosted. Note that this field is self-reported by the author of the program and might not be accurate.

#### `acknowledgments: Option<String>`

Text containing acknowledgments to security researchers who have previously found vulnerabilities in the project, or a link to it.

#### `additional_information: Option<String>`

Text containing any additional information you want to provide, or a link to it.

### Required Functions

The following function MUST be implemented to follow the SRC-11 standard.

#### `fn security_information() -> SecurityInformation;`

This function takes no input parameters and returns a struct containing contact information for the project owners, information regarding the bug bounty program, other information related to security, and any other information that the developers find relevant.

- This function MUST return accurate and up to date information.
- This function's return values MUST follow the specification for the `SecurityInformation` type.
- This function MUST NOT revert under any circumstances.

## Rationale

The return structure discussed covers most information that may want to be conveyed regarding the security of the contract, with an additional field to convey any additional information. This should allow easy communication between the project owners and any white hat hackers if necessary.

## Backwards Compatibility

This standard does not face any issues with backward compatibility.

## Security Considerations

The information is entirely self reported and as such might not be accurate. Accuracy of information cannot be enforced and as such, anyone using this information should be aware of that.

## Example ABI

```sway
abi SRC11 {
    #[storage(read)]
    fn security_information() -> SecurityInformation;
}
```

## Example Implementation

### Hard coded information

A basic implementation of the security information standard demonstrating how to hardcode information to be returned.

```sway
contract;

use src11::{SecurityInformation, SRC11};

use std::{string::String, vec::Vec};

/// The name of the project
const NAME: str[7] = __to_str_array("Example");
/// The URL of the project
const PROJECT_URL: str[19] = __to_str_array("https://example.com");
/// The contact information of the project
const CONTACT1: str[25] = __to_str_array("email:example@example.com");
const CONTACT2: str[41] = __to_str_array("link:https://example.com/security_contact");
const CONTACT3: str[20] = __to_str_array("discord:example#1234");
/// The security policy of the project
const POLICY: str[35] = __to_str_array("https://example.com/security_policy");
/// The preferred languages of the project
const PREFERRED_LANGUAGES1: str[2] = __to_str_array("en");
const PREFERRED_LANGUAGES2: str[2] = __to_str_array("ja");
const PREFERRED_LANGUAGES3: str[2] = __to_str_array("zh");
const PREFERRED_LANGUAGES4: str[2] = __to_str_array("hi");
/// The encryption key of the project
const ENCRYPTION: str[751] = __to_str_array(
    "-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: Alice's OpenPGP certificate
Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html

mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE
ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy
MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO
dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4
OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s
E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb
DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn
0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=
=iIGO
-----END PGP PUBLIC KEY BLOCK-----",
);
/// The URL of the project's source code
const SOURCE_CODE: str[31] = __to_str_array("https://github.com/example/test");
/// The release identifier of this build
const SOURCE_RELEASE: str[6] = __to_str_array("v1.0.0");
/// The revision identifier of this build
const SOURCE_REVISION: str[12] = __to_str_array("a1b2c3d4e5f6");
/// The URL of the project's auditors
const AUDITORS: str[28] = __to_str_array("https://example.com/auditors");
/// The URL of the project's acknowledgements
const ACKNOWLEDGEMENTS: str[36] = __to_str_array("https://example.com/acknowledgements");
/// The URL of the project's additional information
const ADDITIONAL_INFORMATION: str[42] = __to_str_array("https://example.com/additional_information");

impl SRC11 for Contract {
    #[storage(read)]
    fn security_information() -> SecurityInformation {
        let mut contact_information = Vec::new();
        contact_information.push(String::from_ascii_str(from_str_array(CONTACT1)));
        contact_information.push(String::from_ascii_str(from_str_array(CONTACT2)));
        contact_information.push(String::from_ascii_str(from_str_array(CONTACT3)));

        let mut preferred_languages = Vec::new();
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES1))); // English
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES2))); // Japanese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES3))); // Chinese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES4))); // Hindi
        let mut auditors = Vec::new();
        auditors.push(String::from_ascii_str(from_str_array(AUDITORS)));

        SecurityInformation {
            name: String::from_ascii_str(from_str_array(NAME)),
            project_url: Some(String::from_ascii_str(from_str_array(PROJECT_URL))),
            contact_information: contact_information,
            policy: String::from_ascii_str(from_str_array(POLICY)),
            preferred_languages: Some(preferred_languages),
            encryption: Some(String::from_ascii_str(from_str_array(ENCRYPTION))),
            source_code: Some(String::from_ascii_str(from_str_array(SOURCE_CODE))),
            source_release: Some(String::from_ascii_str(from_str_array(SOURCE_RELEASE))),
            source_revision: Some(String::from_ascii_str(from_str_array(SOURCE_REVISION))),
            auditors: Some(auditors),
            acknowledgments: Some(String::from_ascii_str(from_str_array(ACKNOWLEDGEMENTS))),
            additional_information: Some(String::from_ascii_str(from_str_array(ADDITIONAL_INFORMATION))),
        }
    }
}

```

### Variable information

A basic implementation of the security information standard demonstrating how to return variable information that can be edited to keep it up to date. In this example only the contact_information field is variable, but the same method can be applied to any field which you wish to update.

```sway
contract;

use src11::{SecurityInformation, SRC11};

use std::{storage::{storage_string::*, storage_vec::*}, string::String, vec::Vec};

/// The name of the project
const NAME: str[7] = __to_str_array("Example");
/// The URL of the project
const PROJECT_URL: str[19] = __to_str_array("https://example.com");
/// The security policy of the project
const POLICY: str[35] = __to_str_array("https://example.com/security_policy");
/// The preferred languages of the project
const PREFERRED_LANGUAGES1: str[2] = __to_str_array("en");
const PREFERRED_LANGUAGES2: str[2] = __to_str_array("ja");
const PREFERRED_LANGUAGES3: str[2] = __to_str_array("zh");
const PREFERRED_LANGUAGES4: str[2] = __to_str_array("hi");
/// The encryption key of the project
const ENCRYPTION: str[751] = __to_str_array(
    "-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: Alice's OpenPGP certificate
Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html

mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE
ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy
MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO
dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4
OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s
E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb
DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn
0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=
=iIGO
-----END PGP PUBLIC KEY BLOCK-----",
);
/// The URL of the project's source code
const SOURCE_CODE: str[31] = __to_str_array("https://github.com/example/test");
/// The release identifier of this build
const SOURCE_RELEASE: str[6] = __to_str_array("v1.0.0");
/// The revision identifier of this build
const SOURCE_REVISION: str[12] = __to_str_array("a1b2c3d4e5f6");
/// The URL of the project's auditors
const AUDITORS: str[28] = __to_str_array("https://example.com/auditors");
/// The URL of the project's acknowledgements
const ACKNOWLEDGEMENTS: str[36] = __to_str_array("https://example.com/acknowledgements");
/// The URL of the project's additional information
const ADDITIONAL_INFORMATION: str[42] = __to_str_array("https://example.com/additional_information");

storage {
    /// The contact information for the security contact.
    contact_information: StorageVec<StorageString> = StorageVec {},
}

abi StorageInformation {
    #[storage(read, write)]
    fn store_contact_information(input: String);
}

impl StorageInformation for Contract {
    #[storage(read, write)]
    fn store_contact_information(input: String) {
        storage.contact_information.push(StorageString {});
        let storage_string = storage.contact_information.get(storage.contact_information.len() - 1).unwrap();
        storage_string.write_slice(input);
    }
}

#[storage(read)]
fn get_contact_information() -> Vec<String> {
    let mut contact_information = Vec::new();

    let mut i = 0;
    while i < storage.contact_information.len() {
        let storage_string = storage.contact_information.get(i).unwrap();
        contact_information.push(storage_string.read_slice().unwrap());
        i += 1;
    }

    contact_information
}

impl SRC11 for Contract {
    #[storage(read)]
    fn security_information() -> SecurityInformation {
        let mut preferred_languages = Vec::new();
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES1))); // English
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES2))); // Japanese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES3))); // Chinese
        preferred_languages.push(String::from_ascii_str(from_str_array(PREFERRED_LANGUAGES4))); // Hindi
        let mut auditors = Vec::new();
        auditors.push(String::from_ascii_str(from_str_array(AUDITORS)));

        SecurityInformation {
            name: String::from_ascii_str(from_str_array(NAME)),
            project_url: Some(String::from_ascii_str(from_str_array(PROJECT_URL))),
            // Use stored variable contact information instead of hardcoded contact information.
            contact_information: get_contact_information(),
            policy: String::from_ascii_str(from_str_array(POLICY)),
            preferred_languages: Some(preferred_languages),
            encryption: Some(String::from_ascii_str(from_str_array(ENCRYPTION))),
            source_code: Some(String::from_ascii_str(from_str_array(SOURCE_CODE))),
            source_release: Some(String::from_ascii_str(from_str_array(SOURCE_RELEASE))),
            source_revision: Some(String::from_ascii_str(from_str_array(SOURCE_REVISION))),
            auditors: Some(auditors),
            acknowledgments: Some(String::from_ascii_str(from_str_array(ACKNOWLEDGEMENTS))),
            additional_information: Some(String::from_ascii_str(from_str_array(ADDITIONAL_INFORMATION))),
        }
    }
}

```


---

### File: docs/sway-standards/docs/src/src-12-contract-factory.md

# SRC-12: Contract Factory

The following standard allows for the implementation of a standard ABI for Contract Factories using the Sway Language. The standardized design designates how verification of newly deployed child contracts are handled.

## Motivation

A standard interface for Contract Factories provides a safe and effective method of ensuring contracts can verify the validity of another contract as a child of a factory. This is critical on the Fuel Network as contracts cannot deploy other contracts and verification must be done after deployment.

## Prior Art

A Contract Factory is a design where a template contract is used and deployed repeatedly with different configurations. These configurations are often minor changes such as pointing to a different asset. All base functionality remains the same.

On Fuel, contracts cannot deploy other contracts. As a result, a Contract Factory on Fuel must register and verify that the bytecode root of a newly deployed child contract matches the expected bytecode root.

When changing something such as a configurable in Sway, the bytecode root is recalculated. The [Bytecode Library](https://docs.fuel.network/docs/sway-libs/bytecode/) has been developed to calculate the bytecode root of a contract with different configurables.

## Specification

The following functions MUST be implemented to follow the SRC-12; Contract Factory Standard:

### Required Functions

#### `fn register_contract(child_contract: ContractId, configurables: Option<Vec<(u64, Vec<u8>)>>) -> Result<b256, str>`

The `register_contract()` function verifies that a newly deployed contract is the child of a contract factory.

- This function MUST verify that the bytecode root of the `child_contract` contract matches the expected bytecode root.
- This function MUST calculate the bytecode root IF `configurables` is `Some`.
- This function MUST not revert.
- This function MUST return a `Result` containing the `b256` bytecode root of the newly registered contract or an `str` error message.
- This function MAY add arbitrary conditions checking a contract factory child’s validity, such as verifying storage variables or initialized values.

#### `fn is_valid(child_contract: ContractId) -> bool`

The `is_valid()` function returns a boolean representing the state of whether a contract is registered as a valid child of the contract factory.

- This function MUST return `true` if this is a valid and registered child, otherwise `false`.

#### `fn factory_bytecode_root() -> Option<b256>`

The `factory_bytecode_root()` function returns the bytecode root of the default template contract.

- This function MUST return the bytecode root of the template contract.

### Optional Functions

The following are functions that may enhance the use of the SRC-12 standard but ARE NOT required.

#### `fn get_contract_id(configurables: Option<Vec<(u64, Vec<u8>)>>) -> Option<ContractId>`

The `get_contract_id()` function returns a registered contract factory child contract with specific implementation details specified by `configurables`.

This function MUST return `Some(ContractId)` IF a contract that follows the specified `configurables` has been registered with the SRC-12 Contract Factory contract, otherwise `None`.

## Rationale

The SRC-12; Contract Factory Standard is designed to standardize the contract factory design implementation interface between all Fuel instances.

## Backwards Compatibility

There are no other standards that the SRC-12 requires compatibility.

## Security Considerations

This standard takes into consideration child contracts that are deployed with differentiating configurable values, however individual contract behaviours may be dependent on storage variables. As storage variables may change after the contract has been registered with the SRC-12 compliant contract, the standard suggests to check these values upon registration however it is not enforced.

## Example ABI

```sway
abi SRC12 {
    #[storage(read, write)]
    fn register_contract(child_contract: ContractId, configurables: Option<Vec<(u64, Vec<u8>)>>) -> Result<b256, str>;
    #[storage(read)]
    fn is_valid(child_contract: ContractId) -> bool;
    #[storage(read)]
    fn factory_bytecode_root() -> Option<b256>;
}

abi SRC12_Extension {
    #[storage(read)]
    fn get_contract_id(configurables: Option<Vec<(u64, Vec<u8>)>>) -> Option<ContractId>;
}
```

## Example Implementation

### With Configurables

Example of the SRC-12 implementation where contract deployments contain configurable values that differentiate the bytecode root from other contracts with the same bytecode.

```sway
contract;

mod utils;

use utils::{_compute_bytecode_root, _swap_configurables};
use src12::*;
use std::{external::bytecode_root, hash::{Hash, sha256}, storage::storage_vec::*};

configurable {
    TEMPLATE_BYTECODE_ROOT: b256 = b256::zero(),
}

storage {
    /// Contracts that have registered with this contract.
    registered_contracts: StorageMap<ContractId, bool> = StorageMap {},
    /// Maps the hash digest of configurables to the contract id.
    contract_configurables: StorageMap<b256, ContractId> = StorageMap {},
    /// The template contract's bytecode
    bytecode: StorageVec<u8> = StorageVec {},
}

abi MyRegistryContract {
    #[storage(read, write)]
    fn set_bytecode(bytecode: Vec<u8>);
}

impl MyRegistryContract for Contract {
    /// Special helper function to store the template contract's bytecode
    ///
    /// # Additional Information
    ///
    /// Real world implementations should apply restrictions on this function such that it cannot
    /// be changed by anyone or can only be changed once.
    #[storage(read, write)]
    fn set_bytecode(bytecode: Vec<u8>) {
        storage.bytecode.store_vec(bytecode);
    }
}

impl SRC12 for Contract {
    /// Verifies that a newly deployed contract is the child of a contract factory and registers it.
    ///
    /// # Additional Information
    ///
    /// This example does not check whether a contract has already been registered and will overwrite any values.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to verify the bytecode root.
    /// * `configurables`: [Option<ContractConfigurables>] - The configurables value set for the `child_contract`.
    ///
    /// # Returns
    ///
    /// * [Result<BytecodeRoot, str>] - Either the bytecode root of the newly registered contract or a `str` error message.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Writes: `2`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read, write)]
    fn register_contract(
        child_contract: ContractId,
        configurables: Option<ContractConfigurables>,
    ) -> Result<BytecodeRoot, str> {
        let returned_root = bytecode_root(child_contract);

        // If there are no configurables just use the default template
        let computed_root = match configurables {
            Some(config) => {
                let bytecode = storage.bytecode.load_vec();
                compute_bytecode_root(bytecode, config)
            },
            None => {
                TEMPLATE_BYTECODE_ROOT
            }
        };

        // Verify the roots match
        if returned_root != computed_root {
            return Result::Err(
                "The deployed contract's bytecode root and expected contract bytecode root do not match",
            );
        }

        storage.registered_contracts.insert(child_contract, true);
        storage
            .contract_configurables
            .insert(sha256(configurables.unwrap_or(Vec::new())), child_contract);

        return Result::Ok(computed_root)
    }

    /// Returns a boolean representing the state of whether a contract is a valid child of the contract factory.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to check the registry status.
    ///
    /// # Returns
    ///
    /// * [bool] - `true` if the contract has registered and is valid, otherwise `false`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read)]
    fn is_valid(child_contract: ContractId) -> bool {
        storage.registered_contracts.get(child_contract).try_read().unwrap_or(false)
    }

    /// Returns the bytecode root of the default template contract.
    ///
    /// # Returns
    ///
    /// * [Option<BytecodeRoot>] - The bytecode root of the default template contract.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     let root = src_12_contract_abi.factory_bytecode_root();
    ///     assert(root.unwrap() != b256::zero());
    /// }
    /// ```
    #[storage(read)]
    fn factory_bytecode_root() -> Option<BytecodeRoot> {
        Some(TEMPLATE_BYTECODE_ROOT)
    }
}

impl SRC12_Extension for Contract {
    /// Return a registered contract factory child contract with specific implementation details specified by it's configurables.
    ///
    /// # Arguments
    ///
    /// * `configurables`: [Option<ContractConfigurables>] - The configurables value set for the `child_contract`.
    ///
    /// # Returns
    ///
    /// * [Option<ContractId>] - The id of the contract which has registered with the specified configurables.
    ///
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12_Extension;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12_Extension, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     let result_contract_id = src_12_contract_abi.get_contract_id(my_configurables);
    ///     assert(result_contract_id.unwrap() == my_deployed_contract);
    /// }
    /// ```
    #[storage(read)]
    fn get_contract_id(configurables: Option<ContractConfigurables>) -> Option<ContractId> {
        storage.contract_configurables.get(sha256(configurables.unwrap_or(Vec::new()))).try_read()
    }
}

/// This function is copied and can be imported from the Sway Libs Bytecode Library.
/// https://github.com/FuelLabs/sway-libs/tree/master/libs/bytecode
fn compute_bytecode_root(bytecode: Vec<u8>, configurables: Vec<(u64, Vec<u8>)>) -> b256 {
    let mut bytecode_slice = bytecode.as_raw_slice();
    _swap_configurables(bytecode_slice, configurables);
    _compute_bytecode_root(bytecode_slice)
}

```

### Without Configurables

Example of the SRC-12 implementation where all contract deployments are identical and thus have the same bytecode and root.

```sway
contract;

use src12::*;
use std::{external::bytecode_root, hash::Hash};

configurable {
    TEMPLATE_BYTECODE_ROOT: b256 = b256::zero(),
}

storage {
    /// Contracts that have registered with this contract.
    registered_contracts: StorageMap<ContractId, bool> = StorageMap {},
}

impl SRC12 for Contract {
    /// Verifies that a newly deployed contract is the child of a contract factory and registers it.
    ///
    /// # Additional Information
    ///
    /// This example does not check whether a contract has already been registered and will overwrite any values.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to verify the bytecode root.
    /// * `configurables`: [Option<ContractConfigurables>] - The configurables value set for the `child_contract`.
    ///
    /// # Returns
    ///
    /// * [Result<BytecodeRoot, str>] - Either the bytecode root of the newly registered contract or a `str` error message.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Writes: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read, write)]
    fn register_contract(
        child_contract: ContractId,
        configurables: Option<ContractConfigurables>,
    ) -> Result<BytecodeRoot, str> {
        if configurables.is_some() {
            return Result::Err(
                "This SRC-12 implementation only registers contracts without configurable values",
            );
        }

        let returned_root = bytecode_root(child_contract);
        if returned_root != TEMPLATE_BYTECODE_ROOT {
            return Result::Err(
                "The deployed contract's bytecode root and template contract bytecode root do not match",
            );
        }

        storage.registered_contracts.insert(child_contract, true);
        return Result::Ok(returned_root)
    }

    /// Returns a boolean representing the state of whether a contract is a valid child of the contract factory.
    ///
    /// # Arguments
    ///
    /// * `child_contract`: [ContractId] - The deployed factory child contract of which to check the registry status.
    ///
    /// # Returns
    ///
    /// * [bool] - `true` if the contract has registered and is valid, otherwise `false`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId, my_deployed_contract: ContractId, my_configurables: Option<ContractConfigurables>) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     src_12_contract_abi.register_contract(my_deployed_contract, my_configurables);
    ///     assert(src_12_contract_abi.is_valid(my_deployed_contract));
    /// }
    /// ```
    #[storage(read)]
    fn is_valid(child_contract: ContractId) -> bool {
        storage.registered_contracts.get(child_contract).try_read().unwrap_or(false)
    }

    /// Returns the bytecode root of the default template contract.
    ///
    /// # Returns
    ///
    /// * [Option<BytecodeRoot>] - The bytecode root of the default template contract.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src12::SRC12;
    ///
    /// fn foo(my_src_12_contract: ContractId) {
    ///     let src_12_contract_abi = abi(SRC12, my_src_12_contract.bits());
    ///     let root = src_12_contract_abi.factory_bytecode_root();
    ///     assert(root.unwrap() != b256::zero());
    /// }
    /// ```
    #[storage(read)]
    fn factory_bytecode_root() -> Option<BytecodeRoot> {
        Some(TEMPLATE_BYTECODE_ROOT)
    }
}

```


---

### File: docs/sway-standards/docs/src/src-13-soulbound-address.md

# SRC-13: Soulbound Address

The following standard allows for the implementation of Soulbound Address on the Fuel Network. Soulbound Assets are [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) sent to the Soulbound Address and cannot be transferred. As Native Assets on the Fuel Network do not require approvals to be spent, any asset sent to an `Address` may be transferable. The SRC-13 standard provides a predicate interface to lock Native Assets as soulbound.

## Motivation

This standard enables soulbound assets on Fuel and allows external applications to query and provide soulbound assets, whether that be decentralized exchanges, wallets, or other external applications.

## Prior Art

[Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on the Fuel Network do not require the implementation of certain functions such as transfer or approval. This is done directly within the FuelVM and there is no smart contract that requires updating of balances. As such, any assets sent to an `Address` may be spendable and ownership of that asset may be transferred. For any soulbound assets, spending must be restricted.

Predicates are programs that return a Boolean value and which represent ownership of some resource upon execution to true. All predicates evaluate to an `Address` based on their bytecode root. A predicate must evaluate to true such that the assets may be spent.

The SRC-13 Soulbound Asset Standard naming pays homage to the [ERC-5192: Minimal Soulbound NFTs](https://eips.ethereum.org/EIPS/eip-5192) seen on Ethereum. While there is functionality we may use as a reference, it is noted that Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) are fundamentally different than Ethereum's tokens.

## Specification

### Overview

To ensure that some asset shall never be spent, we must apply spending conditions. This can be done with Predicates on Fuel. Any asset sent to a Predicate `Address` shall never be spent if the predicate never evaluates to true.

We must also ensure every `Address` on Fuel has its own Predicate. This can be guaranteed by using a `configurable` where an `Address` is defined.

### Definitions

- **Soulbound Address Predicate** - The resulting predicate which owns assets on behalf of an `Address`.
- **Soulbound Address** - The computed `Address` of the _Soulbound Asset Predicate_.
- **Soulbound Asset** - Any [Native Asset](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) sent to the _Soulbound Address_.

### Soulbound Address Predicate Specification

- The _Soulbound Address Predicate_ SHALL never spend the assets sent to its computed predicate `Address` or _Soulbound Address_.
- The _Soulbound Address Predicate_ SHALL encode an `Address` of which it represents the soulbound address.

Below we define the _Soulbound Address Predicate_ where `ADDRESS` MUST be replaced with the `Address` of which the _Soulbound Address Predicate_ represents.

```sway
predicate;

configurable {
    ADDRESS: Address = Address::from(0x0000000000000000000000000000000000000000000000000000000000000000),
}

fn main() -> bool {
    asm (address: ADDRESS) { address: b256 };
    false
}
```

### Soulbound Address

The _Soulbound Address_ is the _Soulbound Address Predicate_'s predicate address. A predicate's address(the bytecode root) is defined [here](https://github.com/FuelLabs/fuel-specs/blob/master/src/identifiers/predicate-id.md).

The _Soulbound Address_ may be computed from the _Soulbound Address Predicate_'s bytecode both on-chain or off-chain. For off-chain computation, please refer to the fuels-rs [predicate docs](https://docs.fuel.network/docs/fuels-rs/predicates/). For on-chain computation, please refer to Sway-Lib's [Bytecode Library](https://docs.fuel.network/docs/sway-libs/bytecode/).

## Rationale

On the Fuel Network, the process for sending any [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) is the same and does not require any approval. This means that any assets sent to an Address may be spendable and does not require any external spending conditions. In the case of a soulbound asset, we need to ensure the asset cannot be spent.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) and the [SRC-20](./src-20-native-asset.md) standard.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

It should however be noted that any Native Asset on the Fuel Network is not a Soulbound Asset until it is sent to a _Soulbound Address_.

## Example

The following example shows the _Soulbound Address Predicate_ for the `0xe033369a522e3cd2fc19a5a705a7f119938027e8e287c0ec35b784e68dab2be6` `Address`.

The resulting _Soulbound Address_ is `0x7f28a538d06788a3d98bb72f4b41012d86abc4b0369ee5dedf56cfbaf245d609`. Any Native Assets sent to this address will become Soulbound Assets.

```sway
predicate;

configurable {
    ADDRESS: Address = Address::from(0xe033369a522e3cd2fc19a5a705a7f119938027e8e287c0ec35b784e68dab2be6),
}

fn main() -> bool {
    asm (address: ADDRESS) { address: b256 };
    false
}
```


---

### File: docs/sway-standards/docs/src/src-14-simple-upgradeable-proxies.md

# SRC-14: Simple Upgradeable Proxies

The following proposes a standard for simple upgradeable proxies.

## Motivation

We seek to standardize a proxy implementation to improve developer experience and enable tooling to automatically deploy or update proxies as needed.

## Prior Art

[This OpenZeppelin blog post](https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades#proxies-and-implementations) is a good survey of the state of the art at this time.

Proxy designs fall into three essential categories:

1. Immutable proxies which are lightweight clones of other contracts but can't change targets
2. Upgradeable proxies such as [UUPS](https://eips.ethereum.org/EIPS/eip-1822) which store a target in storage and delegate all calls to it
3. [Diamonds](https://eips.ethereum.org/EIPS/eip-2535) which are both upgradeable and can point to multiple targets on a per method basis

This document falls in the second category. We want to standardize the implementation of simple upgradeable pass-through contracts.

The FuelVM provides an `LDC` instruction that is used by Sway's `std::execution::run_external` to provide a similar behavior to EVM's `delegatecall` and execute instructions from another contract while retaining one's own storage context. This is the intended means of implementation of this standard.

## Specification

### Required Behavior

The proxy contract MUST maintain the address of its target in its storage at slot `0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55` (equivalent to `sha256("storage_SRC14_0")`).
It SHOULD base other proxy specific storage fields in the `SRC14` namespace to avoid collisions with target storage.
It MAY have its storage definition overlap with that of its target if necessary.

The proxy contract MUST delegate any method call not part of its interface to the target contract.

This delegation MUST retain the storage context of the proxy contract.

### Required Public Functions

The following functions MUST be implemented by a proxy contract to follow the SRC-14 standard:

#### `fn set_proxy_target(new_target: ContractId);`

If a valid call is made to this function it MUST change the target contract of the proxy to `new_target`.
This method SHOULD implement access controls such that the target can only be changed by a user that possesses the right permissions (typically the proxy owner).

#### `fn proxy_target() -> Option<ContractId>;`

This function MUST return the target contract of the proxy as `Some`. If no proxy is set then `None` MUST be returned.

### Optional Public Functions

The following functions are RECOMMENDED to be implemented by a proxy contract to follow the SRC-14 standard:

#### `fn proxy_owner() -> State;`

This function SHALL return the current state of ownership for the proxy contract where the `State` is either `Uninitialized`, `Initialized`, or `Revoked`. `State` is defined in the [SRC-5; Ownership Standard](./src-5-ownership.md).

## Rationale

This standard is meant to provide simple upgradeability, it is deliberately minimalistic and does not provide the level of functionality of diamonds.

Unlike in [UUPS](https://eips.ethereum.org/EIPS/eip-1822), this standard requires that the upgrade function is part of the proxy and not its target.
This prevents irrecoverable updates if a proxy is made to point to another proxy and no longer has access to upgrade logic.

## Backwards Compatibility

SRC-14 is intended to be compatible with SRC-5 and other standards of contract functionality.

As it is the first attempt to standardize proxy implementation, we do not consider interoperability with other proxy standards.

## Security Considerations

Permissioning proxy target changes is the primary consideration here.
Use of the [SRC-5; Ownership Standard](./src-5-ownership.md) is discouraged. If both the target and proxy contracts implement the [SRC-5](./src-5-ownership.md) standard, the `owner()` function in the target contract is unreachable through the proxy contract. Use of the `proxy_owner()` function in the proxy contract should be used instead.

## Example ABI

```sway
abi SRC14 {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId);
    #[storage(read)]
    fn proxy_target() -> Option<ContractId>;
}

abi SRC14Extension {
    #[storage(read)]
    fn proxy_owner() -> State;
}
```

## Example Implementation

### Minimal Proxy

Example of a minimal SRC-14 implementation with no access control.

```sway
contract;

use std::execution::run_external;
use src14::{SRC14, SRC14_TARGET_STORAGE};

storage {
    SRC14 {
        /// The [ContractId] of the target contract.
        ///
        /// # Additional Information
        ///
        /// `target` is stored at sha256("storage_SRC14_0")
        target in 0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55: ContractId = ContractId::zero(),
    },
}

impl SRC14 for Contract {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId) {
        storage::SRC14.target.write(new_target);
    }

    #[storage(read)]
    fn proxy_target() -> Option<ContractId> {
        storage::SRC14.target.try_read()
    }
}

#[fallback]
#[storage(read)]
fn fallback() {
    // pass through any other method call to the target
    run_external(storage::SRC14.target.read())
}

```

### Owned Proxy

Example of a SRC-14 implementation that also implements `proxy_owner()`.

```sway
contract;

use std::execution::run_external;
use src5::{AccessError, State};
use src14::{SRC14, SRC14_TARGET_STORAGE, SRC14Extension};

/// The owner of this contract at deployment.
#[allow(dead_code)]
const INITIAL_OWNER: Identity = Identity::Address(Address::zero());

storage {
    SRC14 {
        /// The [ContractId] of the target contract.
        ///
        /// # Additional Information
        ///
        /// `target` is stored at sha256("storage_SRC14_0")
        target in 0x7bb458adc1d118713319a5baa00a2d049dd64d2916477d2688d76970c898cd55: ContractId = ContractId::zero(),
        /// The [State] of the proxy owner.
        owner: State = State::Initialized(INITIAL_OWNER),
    },
}

impl SRC14 for Contract {
    #[storage(read, write)]
    fn set_proxy_target(new_target: ContractId) {
        only_owner();
        storage::SRC14.target.write(new_target);
    }

    #[storage(read)]
    fn proxy_target() -> Option<ContractId> {
        storage::SRC14.target.try_read()
    }
}

impl SRC14Extension for Contract {
    #[storage(read)]
    fn proxy_owner() -> State {
        storage::SRC14.owner.read()
    }
}

#[fallback]
#[storage(read)]
fn fallback() {
    // pass through any other method call to the target
    run_external(storage::SRC14.target.read())
}

#[storage(read)]
fn only_owner() {
    require(
        storage::SRC14
            .owner
            .read() == State::Initialized(msg_sender().unwrap()),
        AccessError::NotOwner,
    );
}

```


---

### File: docs/sway-standards/docs/src/src-15-offchain-asset-metadata.md

# SRC-15: Off-Chain Native Asset Metadata

The following standard attempts to define arbitrary offchain metadata for any [Native Asset](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) that is not required by other contracts onchain, in a stateless manner. Any contract that implements the SRC-15 standard MUST implement the [SRC-20](./src-20-native-asset.md) standard.

> **NOTE** If data is  needed onchain, use the [SRC-7; Onchain Asset Metadata Standard](./src-7-asset-metadata.md).

## Motivation

The SRC-15 standard seeks to enable data-rich assets on the Fuel Network while maintaining a stateless solution. All metadata queries are done off-chain using the indexer.

## Prior Art

The SRC-7 standard exists prior to the SRC-15 standard and is a stateful solution. The SRC-15 builds off the SRC-7 standard by using the `Metadata` enum however provides a stateless solution.

The use of generic metadata was originally found in the Sway-Lib's [NFT Library](https://github.com/FuelLabs/sway-libs/tree/v0.12.0/libs/nft) which did not use Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). This library has since been deprecated.

A previous definition for a metadata standard was written in the original edit of the now defunct [SRC-721](https://github.com/FuelLabs/sway-standards/issues/2). This has since been replaced with the [SRC-20](./src-20-native-asset.md) standard as `SubId` was introduced to enable multiple assets to be minted from a single contract.

## Specification

### Metadata Type

The `Metadata` enum from the SRC-7 standard is also used to represent the metadata in the SRC-15 standard.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-15 standard. Logging MUST be emitted from the contract which minted the asset.

#### SRC15MetadataEvent

The `SRC15MetadataEvent` MUST be emitted at least once for each distinct piece of metadata and each distinct asset. The latest emitted `SRC15MetadataEvent` is determined to be the current metadata.

There SHALL be the following fields in the `SRC15MetadataEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` for the metadata.
* `metadata`: The `metadata` field SHALL be used for the corresponding `Metadata` which represents the metadata of the asset.

Example:

```sway
pub struct SRC15MetadataEvent {
    pub asset: AssetId,
    pub metadata: Metadata,
}
```

#### SRC15GlobalMetadataEvent

The `SRC15GlobalMetadataEvent` MUST be emitted at least once for each distinct piece of metadata for *all* assets minted by a contract. The latest emitted `SRC15GlobalMetadataEvent` is determined to be the current metadata.

There SHALL be the following fields in the `SRC15GlobalMetadataEvent` struct:

* `metadata`: The `metadata` field SHALL be used for the corresponding `Metadata` which represents the metadata associated with all assets minted by the contract.

Example:

```sway
pub struct SRC15GlobalMetadataEvent {
    pub metadata: Metadata,
}
```

## Rationale

The SRC-15 standard allows for data-rich assets in a stateless manner by associating an asset with some metadata that may later be fetched by the indexer.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) and the [SRC-20](./src-20-native-asset.md) standard. This standard is also compatible with the SRC-7 standard which defines a stateful solution. It also maintains compatibility with existing standards in other ecosystems.

## Security Considerations

When indexing for SRC-15 metadata, developers should confirm that the contract that emitted the `SRC15MetadataEvent` is also the contract that minted the asset that the metadata associates with. Additionally, restrictions via access control on who may emit the Metadata should be considered.

## Example Implementation

### Single Native Asset

Example of the SRC-15 implementation where metadata exists for only a single asset with one `SubId`.

```sway
contract;

use src15::SRC15MetadataEvent;
use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src7::Metadata;
use std::string::String;
configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
    /// The metadata for the "attr:health" key.
    ATTR_HEALTH: u64 = 100,
}
abi EmitSRC15Events {
    fn emit_src15_events();
}
impl EmitSRC15Events for Contract {
    fn emit_src15_events() {
        // NOTE: There are no checks for if the caller has permissions to emit the metadata.
        // NOTE: Nothing is stored in storage and there is no method to retrieve the configurables.
        let asset = AssetId::default();
        let metadata_1 = Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X)));
        let metadata_2 = Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM)));
        let metadata_3 = Metadata::Int(ATTR_HEALTH);
        SRC15MetadataEvent::new(asset, metadata_1).log();
        SRC15MetadataEvent::new(asset, metadata_2).log();
        SRC15MetadataEvent::new(asset, metadata_3).log();
    }
}
// SRC15 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}
abi EmitSRC20Events {
    fn emit_src20_events();
}
impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable must be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));
        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, TOTAL_SUPPLY, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-15 implementation where metadata exists for multiple assets with differing `SubId` values.

```sway
contract;

use src15::SRC15MetadataEvent;
use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src7::Metadata;
use std::{hash::Hash, storage::storage_string::*, string::String};
// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
    /// The decimals of every asset minted by this contract.
    DECIMALS: u8 = 0u8,
    /// The name of every asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of every asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYAST"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
}
storage {
    /// The total number of distinguishable assets this contract has minted.
    total_assets: u64 = 0,
    /// The total supply of a particular asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}
abi EmitSRC15Events {
    #[storage(read)]
    fn emit_src15_events(asset: AssetId, svg_image: String, health_attribute: u64);
}
impl EmitSRC15Events for Contract {
    #[storage(read)]
    fn emit_src15_events(asset: AssetId, svg_image: String, health_attribute: u64) {
        // NOTE: There are no checks for if the caller has permissions to emit the metadata
        // NOTE: Nothing is stored in storage and there is no method to retrieve the configurables.

        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let metadata_1 = Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X)));
        let metadata_2 = Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM)));
        let metadata_3 = Metadata::String(svg_image);
        let metadata_4 = Metadata::Int(health_attribute);
        SRC15MetadataEvent::new(asset, metadata_1).log();
        SRC15MetadataEvent::new(asset, metadata_2).log();
        SRC15MetadataEvent::new(asset, metadata_3).log();
        SRC15MetadataEvent::new(asset, metadata_4).log();
    }
}
// SRC15 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(NAME))),
            None => None,
        }
    }
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(SYMBOL))),
            None => None,
        }
    }
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(DECIMALS),
            None => None,
        }
    }
}
abi EmitSRC20Data {
    fn emit_src20_data(asset: AssetId, total_supply: u64);
}
impl EmitSRC20Data for Contract {
    fn emit_src20_data(asset: AssetId, supply: u64) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));
        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, supply, sender).log();
    }
}

```

### Global

Example of the SRC-15 implementation where global metadata exists for all assets.

```sway
contract;

use src15::SRC15GlobalMetadataEvent;
use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src7::Metadata;
use std::{hash::Hash, storage::storage_string::*, string::String};
// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
    /// The decimals of every asset minted by this contract.
    DECIMALS: u8 = 0u8,
    /// The name of every asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of every asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYAST"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
}
storage {
    /// The total number of distinguishable assets this contract has minted.
    total_assets: u64 = 0,
    /// The total supply of a particular asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}
abi EmitSRC15Events {
    #[storage(read)]
    fn emit_src15_events(svg_image: String, health_attribute: u64);
}
impl EmitSRC15Events for Contract {
    #[storage(read)]
    fn emit_src15_events(svg_image: String, health_attribute: u64) {
        // NOTE: There are no checks for if the caller has permissions to emit the metadata
        // NOTE: Nothing is stored in storage and there is no method to retrieve the configurables.
        let metadata_1 = Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X)));
        let metadata_2 = Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM)));
        let metadata_3 = Metadata::String(svg_image);
        let metadata_4 = Metadata::Int(health_attribute);
        SRC15GlobalMetadataEvent::new(metadata_1).log();
        SRC15GlobalMetadataEvent::new(metadata_2).log();
        SRC15GlobalMetadataEvent::new(metadata_3).log();
        SRC15GlobalMetadataEvent::new(metadata_4).log();
    }
}
// SRC15 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(NAME))),
            None => None,
        }
    }
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(SYMBOL))),
            None => None,
        }
    }
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(DECIMALS),
            None => None,
        }
    }
}
abi EmitSRC20Data {
    fn emit_src20_data(asset: AssetId, total_supply: u64);
}
impl EmitSRC20Data for Contract {
    fn emit_src20_data(asset: AssetId, supply: u64) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));
        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, supply, sender).log();
    }
}

```


---

### File: docs/sway-standards/docs/src/src-16-typed-structured-data.md

# SRC-16: Typed Structured Data

The following standard sets out to standardize encoding and hashing of typed structured data. This enables secure off-chain message signing with human-readable data structures.

## Motivation

As the Fuel ecosystem expands, there's an increasing need for applications to handle complex, human-readable data structures rather than raw bytes. When users sign messages or transactions, they should be able to clearly understand what they're signing, whether it's a simple asset transfer, or a complex DeFi interaction. Without a standard method for hashing structured data, developers risk implementing their own solutions, which could lead to confusion or compromise security. This standard provides a secure and consistent way to handle encoding and hashing of structured data, ensuring both safety and usability within ecosystem.

This standard aims to:

* Provide a secure, standardized method for hashing structured data
* Enable clear presentation of structured data for user verification during signing
* Support complex data types that mirror Sway structs
* Enable domain separation to prevent cross-protocol replay attacks
* Define a consistent encoding scheme for structured data types
* Remain stateless, not requiring any storage attributes to enable use across all Fuel program types.

## Prior Art

This standard uses ideas from [Ethereum's EIP-712 standard](https://eips.ethereum.org/EIPS/eip-712), adapting its concepts for the Fuel ecosystem. EIP-712 has proven successful in enabling secure structured data signing for applications like the various browser based wallets and signers that are utilized throughout various DeFi protocols.

## Specification

### Definition of Typed Structured Data 𝕊

The set of structured data 𝕊 consists of all instances of struct types that can be composed from the following types:

Atomic Types:

```sway
u8 to u256
bool
b256 (hash)
```

Dynamic Types:

```sway
Bytes   // Variable-length byte sequences
String  // Variable-length strings
```

Reference Types:

Arrays (both fixed size and dynamic)
Structs (reference to other struct types)

Example struct definition:

```sway
struct Mail {
    from: Address,
    to: Address,
    contents: String,
}
```

### Domain Separator Encoding

The domain separator provides context for the signing operation, preventing cross-protocol replay attacks. It is computed as hash_struct(domain) where domain is defined as:

```sway
pub struct SRC16Domain {
    name: String,                   // The protocol name (e.g., "MyProtocol")
    version: String,                // The protocol version (e.g., "1")
    chain_id: u64,                  // The Fuel chain ID
    verifying_contract: ContractId, // The contract id that will verify the signature
}
```

The `chain_id` field is a u64 that must be encoded by left-padding with zeros and packed in big-endian order to fill a 32-byte value.

The domain separator encoding follows this scheme:

* Add SRC16_DOMAIN_TYPE_HASH
* Add Keccak256 hash of name string
* Add Keccak256 hash of version string
* Add chain ID as 32-byte big-endian
* Add verifying contract id as 32 bytes

## Type Encoding

Each struct type is encoded as name ‖ "(" ‖ member₁ ‖ "," ‖ member₂ ‖ "," ‖ … ‖ memberₙ ")" where each member is written as type ‖ " " ‖ name.

Example:

```sway
Mail(address from,address to,string contents)
```

## Data Encoding

### Definition of hash_struct

The hash_struct function is defined as:

hash_struct(s : 𝕊) = keccak256(type_hash ‖ encode_data(s))
where:

* type_hash = keccak256(encode_type(type of s))
* ‖ represents byte concatenation
* encode_type and encode_data are defined below

### Definition of encode_data

The encoding of a struct instance is enc(value₁) ‖ enc(value₂) ‖ … ‖ enc(valueₙ), the concatenation of the encoded member values in the order they appear in the type. Each encoded member value is exactly 32 bytes long.

The values are encoded as follows:

Atomic Values:

* Boolean false and true are encoded as u64 values 0 and 1, padded to 32 bytes
* `Address`, `ContractId`, `Identity`, and `b256` are encoded directly as 32 bytes
* Unsigned Integer values (u8 to u256) are encoded as big-endian bytes, padded to 32 bytes

Dynamic Types:

* `Bytes` and `String` are encoded as their Keccak256 hash

Reference Types:

* Arrays (both fixed and dynamic) are encoded as the Keccak256 hash of their concatenated encodings
* Struct values are encoded recursively as hash_struct(value)

The implementation of `TypedDataHash` for `𝕊` SHALL utilize the `DataEncoder` for encoding each element of the struct based on its type.

## Final Message Encoding

The encoding of structured data follows this pattern:

encode(domain_separator : 𝔹²⁵⁶, message : 𝕊) = "\x19\x01" ‖ `domain_separator` ‖ `hash_struct`(message)

where:

* \x19\x01 is a constant prefix
* ‖ represents byte concatenation
* `domain_separator` is the 32-byte hash of the domain parameters
* `hash_struct`(message) is the 32-byte hash of the structured data

## Example implementation

```sway
const MAIL_TYPE_HASH: b256 = 0x536e54c54e6699204b424f41f6dea846ee38ac369afec3e7c141d2c92c65e67f;

impl TypedDataHash for Mail {

    fn type_hash() -> b256 {
        MAIL_TYPE_HASH
    }

    fn struct_hash(self) -> b256 {
        let mut encoded = Bytes::new();
        encoded.append(
            MAIL_TYPE_HASH.to_be_bytes()
        );
        encoded.append(
            DataEncoder::encode_address(self.from).to_be_bytes()
        );
        encoded.append(
            DataEncoder::encode_address(self.to).to_be_bytes()
        );
        encoded.append(
            DataEncoder::encode_string(self.contents).to_be_bytes()
        );

        keccak256(encoded)
    }
}
```

## Rationale

* Domain separators provides protocol-specific context to prevent signature replay across different protocols and chains.
* Type hashes ensure type safety and prevent collisions between different data structures
* The encoding scheme is designed to be deterministic and injective
* The standard maintains compatibility with existing Sway types and practices

## Backwards Compatibility

This standard is compatible with existing Sway data structures and can be implemented alongside other Fuel standards. It does not conflict with existing signature verification methods.

### Type System Compatibility Notes

When implementing SRC16 in relation to EIP712, the following type mappings and considerations apply:

#### String Encoding

* Both standards use the same String type and encoding
* SRC16 specifically uses String type only (not Sway's `str` or `str[]`)
* String values are encoded identically in both standards using keccak256 hash

#### Fixed Bytes

* EIP712's `bytes32` maps directly to Sway's `b256`
* Encoded using `encode_b256` in the `DataEncoder`
* Both standards handle 32-byte values identically
* Smaller fixed byte arrays (`bytes1` to `bytes31`) are not supported in SRC16

#### Address Types

* EIP712 uses 20-byte Ethereum addresses
* When encoding an EIP712 address, SRC16:
  * Takes only rightmost 20 bytes from a 32-byte Fuel Address
  * Pads with zeros on the left for EIP712 compatibility
  * Example: Fuel `Address` of 32 bytes becomes rightmost 20 bytes in EIP712 encoding

#### ContractId Handling

* `ContractId` is unique to Fuel/SRC16 (no equivalent in EIP712)
* When encoding for EIP712 compatibility:
  * Uses rightmost 20 bytes of `ContractId`
  * Particularly important in domain separators where EIP712 expects a 20-byte address

#### Domain Separator Compatibility

```sway
// SRC16 Domain (Fuel native)
pub struct SRC16Domain {
    name: String,                   // Same as EIP712
    version: String,                // Same as EIP712
    chain_id: u64,                  // Fuel chain ID
    verifying_contract: ContractId, // Full 32-byte ContractId
}

// EIP712 Domain (Ethereum compatible)
pub struct EIP712Domain {
    name: String,
    version: String,
    chain_id: u256,
    verifying_contract: b256,      // Only rightmost 20 bytes used
}
```

Note on `verifying_contract` field; When implementing EIP712 compatibility within SRC16, the `verifying_contract` address in the `EIP712Domain` must be constructed by taking only the rightmost 20 bytes from either a Fuel `ContractId`. This ensures proper compatibility with Ethereum's 20-byte addressing scheme in the domain separator.

```sway
// Example ContractId conversion:
// Fuel ContractId (32 bytes):
//   0x000000000000000000000000a2233d3bf2aa3f0cbbe824eb04afc1acc84c364c
//                            └─────────────── 20 bytes ───────────────┘
//
// EIP712 Address (20 bytes):
//   0xa2233d3bf2aa3f0cbbe824eb04afc1acc84c364c
//    └─────────────── 20 bytes ───────────────┘
```

Note on EIP712 Domain Separator `salt`; Within EIP712 the field `salt` is an optional field to be used at the discretion of the protocol designer. Within SRC16 the `EIP712Domain` does not use the `salt` field. The other fields in `EIP712Domain` are mandatory within SRC16.

## Security Considerations

### Replay Attacks

Implementations must ensure signatures cannot be replayed across:

Different chains (prevented by chain_id)
Different protocols (prevented by domain separator)
Different contracts (prevented by verifying_contract)

### Type Safety

Implementations must validate all type information and enforce strict encoding rules to prevent type confusion attacks.

## Example Implementation

Example of the SRC16 implementation where a contract utilizes the encoding scheme to produce a typed structured data hash of the Mail type.

```sway
contract;

use src16::{
    DataEncoder,
    DomainHash,
    SRC16,
    SRC16Base,
    SRC16Domain,
    SRC16Encode,
    SRC16Payload,
    TypedDataHash,
};
use std::{bytes::Bytes, contract_id::*, hash::*, string::String};

configurable {
    /// The name of the signing domain.
    DOMAIN: str[8] = __to_str_array("MyDomain"),
    /// The current major version for the signing domain.
    VERSION: str[1] = __to_str_array("1"),
    /// The active chain ID where the signing is intended to be used. Cast to u256 in domain_hash
    CHAIN_ID: u64 = 9889u64,
}

/// A demo struct representing a mail message
pub struct Mail {
    /// The sender's address
    pub from: Address,
    /// The recipient's address
    pub to: Address,
    /// The message contents
    pub contents: String,
}

/// The Keccak256 hash of the type Mail as UTF8 encoded bytes.
///
/// "Mail(address from,address to,string contents)"
///
/// 536e54c54e6699204b424f41f6dea846ee38ac369afec3e7c141d2c92c65e67f
///
const MAIL_TYPE_HASH: b256 = 0x536e54c54e6699204b424f41f6dea846ee38ac369afec3e7c141d2c92c65e67f;

impl TypedDataHash for Mail {
    fn type_hash() -> b256 {
        MAIL_TYPE_HASH
    }

    fn struct_hash(self) -> b256 {
        let mut encoded = Bytes::new();
        // Add the Mail type hash.
        encoded.append(MAIL_TYPE_HASH.to_be_bytes());
        // Use the DataEncoder to encode each field for known types
        encoded.append(DataEncoder::encode_address(self.from).to_be_bytes());
        encoded.append(DataEncoder::encode_address(self.to).to_be_bytes());
        encoded.append(DataEncoder::encode_string(self.contents).to_be_bytes());

        keccak256(encoded)
    }
}

/// Implement the encode function for Mail using SRC16Payload
///
/// # Additional Information
///
/// 1. Get the encodeData hash of the Mail typed data using
///    <Mail>..struct_hash();
/// 2. Obtain the payload to by populating the SRC16Payload struct
///    with the domain separator and data_hash from the previous step.
/// 3. Obtain the final_hash [Some(b256)] or None using the function
///    SRC16Payload::encode_hash()
///
impl SRC16Encode<Mail> for Mail {
    fn encode(s: Mail) -> b256 {
        // encodeData hash
        let data_hash = s.struct_hash();
        // setup payload
        let payload = SRC16Payload {
            domain: _get_domain_separator(),
            data_hash: data_hash,
        };

        // Get the final encoded hash
        match payload.encode_hash() {
            Some(hash) => hash,
            None => revert(0),
        }
    }
}

impl SRC16Base for Contract {
    fn domain_separator_hash() -> b256 {
        _get_domain_separator().domain_hash()
    }

    fn data_type_hash() -> b256 {
        MAIL_TYPE_HASH
    }
}

impl SRC16 for Contract {
    fn domain_separator() -> SRC16Domain {
        _get_domain_separator()
    }
}

abi MailMe {
    fn send_mail_get_hash(from_addr: Address, to_addr: Address, contents: String) -> b256;
}

impl MailMe for Contract {
    /// Sends a some mail and returns its encoded hash
    ///
    /// # Arguments
    ///
    /// * `from_addr`: [Address] - The sender's address
    /// * `to_addr`: [Address] - The recipient's address
    /// * `contents`: [String] - The message contents
    ///
    /// # Returns
    ///
    /// * [b256] - The encoded hash of the mail data
    ///
    fn send_mail_get_hash(from_addr: Address, to_addr: Address, contents: String) -> b256 {
        // Create the mail struct from data passed in call
        let some_mail = Mail {
            from: from_addr,
            to: to_addr,
            contents: contents,
        };

        Mail::encode(some_mail)
    }
}

/// A program specific implementation to get the Fuel SRC16Domain
///
/// In a Contract the ContractID can be obtain with ContractId::this()
///
/// In a Predicate or Script it is at the implementors discretion to
/// use the code root if they wish to contrain the validation to a
/// specifc program.
///
fn _get_domain_separator() -> SRC16Domain {
    SRC16Domain::new(
        String::from_ascii_str(from_str_array(DOMAIN)),
        String::from_ascii_str(from_str_array(VERSION)),
        CHAIN_ID,
        ContractId::this(),
    )
}

```

```sway
contract;

use src16::{
    DataEncoder,
    DomainHash,
    EIP712,
    EIP712Domain,
    SRC16Base,
    SRC16Encode,
    SRC16Payload,
    TypedDataHash,
};
use std::{bytes::Bytes, contract_id::*, hash::*, string::String};

configurable {
    /// The name of the signing domain.
    DOMAIN: str[8] = __to_str_array("MyDomain"),
    /// The current major version for the signing domain.
    VERSION: str[1] = __to_str_array("1"),
    /// The active chain ID where the signing is intended to be used. Cast to u256 in domain_hash
    CHAIN_ID: u64 = 9889u64,
}

/// A demo struct representing a mail message
pub struct Mail {
    /// The sender's address
    pub from: b256,
    /// The recipient's address
    pub to: b256,
    /// The message contents
    pub contents: String,
}

/// The Keccak256 hash of the type Mail as UTF8 encoded bytes.
///
/// "Mail(bytes32 from,bytes32 to,string contents)"
///
/// cfc972d321844e0304c5a752957425d5df13c3b09c563624a806b517155d7056
///
const MAIL_TYPE_HASH: b256 = 0xcfc972d321844e0304c5a752957425d5df13c3b09c563624a806b517155d7056;

impl TypedDataHash for Mail {
    fn type_hash() -> b256 {
        MAIL_TYPE_HASH
    }

    fn struct_hash(self) -> b256 {
        let mut encoded = Bytes::new();

        // Add the Mail type hash.
        encoded.append(MAIL_TYPE_HASH.to_be_bytes());
        // Use the DataEncoder to encode each field for known types
        encoded.append(DataEncoder::encode_b256(self.from).to_be_bytes());
        encoded.append(DataEncoder::encode_b256(self.to).to_be_bytes());
        encoded.append(DataEncoder::encode_string(self.contents).to_be_bytes());

        keccak256(encoded)
    }
}

/// Implement the encode function for Mail using SRC16Payload
///
/// # Additional Information
///
/// 1. Get the encodeData hash of the Mail typed data using
///    <Mail>..struct_hash();
/// 2. Obtain the payload to by populating the SRC16Payload struct
///    with the domain separator and data_hash from the previous step.
/// 3. Obtain the final_hash [Some(b256)] or None using the function
///    SRC16Payload::encode_hash()
///
impl SRC16Encode<Mail> for Mail {
    fn encode(s: Mail) -> b256 {
        // encodeData hash
        let data_hash = s.struct_hash();
        // setup payload
        let payload = SRC16Payload {
            domain: _get_domain_separator(),
            data_hash: data_hash,
        };

        // Get the final encoded hash
        match payload.encode_hash() {
            Some(hash) => hash,
            None => revert(0),
        }
    }
}

impl SRC16Base for Contract {
    fn domain_separator_hash() -> b256 {
        _get_domain_separator().domain_hash()
    }

    fn data_type_hash() -> b256 {
        MAIL_TYPE_HASH
    }
}

impl EIP712 for Contract {
    fn domain_separator() -> EIP712Domain {
        _get_domain_separator()
    }
}

abi MailMe {
    fn send_mail_get_hash(from_addr: b256, to_addr: b256, contents: String) -> b256;
}

impl MailMe for Contract {
    /// Sends a some mail and returns its encoded hash
    ///
    /// # Arguments
    ///
    /// * `from_addr`: [b256] - The sender's address
    /// * `to_addr`: [b256] - The recipient's address
    /// * `contents`: [String] - The message contents
    ///
    /// # Returns
    ///
    /// * [b256] - The encoded hash of the mail data
    ///
    fn send_mail_get_hash(from_addr: b256, to_addr: b256, contents: String) -> b256 {
        // Create the mail struct from data passed in call
        let some_mail = Mail {
            from: from_addr,
            to: to_addr,
            contents: contents,
        };

        Mail::encode(some_mail)
    }
}

/// A program specific implementation to get the Ethereum EIP712Domain
///
/// In a Contract the ContractID can be obtain with ContractId::this()
///
/// In a Predicate or Script it is at the implementors discretion to
/// use the code root if they wish to contrain the validation to a
/// specifc program.
///
fn _get_domain_separator() -> EIP712Domain {
    EIP712Domain::new(
        String::from_ascii_str(from_str_array(DOMAIN)),
        String::from_ascii_str(from_str_array(VERSION)),
        (asm(r1: (0, 0, 0, CHAIN_ID)) {
                r1: u256
            }),
        ContractId::this(),
    )
}

```


---

### File: docs/sway-standards/docs/src/src-17-naming-verification.md

# SRC-17: Naming Verification Standard

The following standard defines a naming verification standard for onchain identities using offchain data.

## Motivation

A standard interface for names on Fuel allows external applications to verify and determine the resolver of a name, whether that be decentralized exchanges frontends, wallets, explorers, or other infrastructure providers.

## Prior Art

A number of existing name service platforms already existed prior to the development of this standard. Notably the most well-known on the Ethereum Blockchain is the [Ethereum Name Service(ENS)](https://ens.domains/). This domain service has a major influence on other name services across multiple platforms. ENS pioneered name service platforms and this standard takes some inspiration from their resolver design.

On Fuel, we have 2 existing name service platforms. These are [Bako ID](https://www.bako.id/) and [Fuel Name Service(FNS)](https://fuelname.com/). This standard was developed in close collaboration with these two platforms to ensure compatibility and ease of upgrade.

## Specification

### Type Aliases

#### `AltBn128Proof` Type Alias

The following describes a type alias for AltBn128 proofs. The `AltBn128Proof` SHALL be defined as the fixed length array `[u8; 288]`.

```sway
pub type AltBn128Proof = [u8; 288];
```

#### `SparseMerkleProof` Type Alias

The following describes a type alias for Sparse Merkle Tree proofs. The `SparseMerkleProof` SHALL be defined as the `Proof` type from the Sway-Libs Sparse Merkle Tree Library.

```sway
pub type SparseMerkleProof = Proof;
```

### Enums

#### `SRC17VerificationError` Enum

The following describes an enum that is used when verification of a name fails. There SHALL be the following variants in the `SRC17VerificationError` type:

##### `VerificationFailed`

The `VerificationFailed` variant SHALL be used when verification of a name fails for ANY reason.

```sway
pub enum SRC17VerificationError {
    VerificationFailed: (),
}
```

#### `SRC17Proof` Enum

The following describes an enum that wraps various proof types into a single input type. There SHALL be the following variants in the `SRC17Proof` type:

##### `AltBn128Proof`

The `AltBn128Proof` variant SHALL be used for AltBn128 proofs.

##### `SparseMerkleProof`

The `SparseMerkleProof` variant SHALL be used for Sparse Merkle Tree proofs.

```sway
pub enum SRC17Proof {
    AltBn128Proof: AltBn128Proof,
    SparseMerkleProof: SparseMerkleProof,
}
```

### Required Public Functions

The following functions MUST be implemented to follow the SRC-17 standard:

#### `fn verify(proof: SRC17Proof, name: String, resolver: Identity, asset: AssetId, metadata: Option<Bytes>) -> Result<(), SRC17VerificationError>`

- This function MUST return `Ok(())` if the proof verification was successful. Otherwise, it MUST return `Err(SRC17VerificationError::VerificationFailed)`.
- The `proof` argument MUST be an `SRC17Proof` which proves the `name`, `asset`, `resolver`, and `metadata` are valid and included in the data.
- The `name` argument MUST the corresponding `String` for the onchain human-readable identity.
- The `resolver` argument MUST be the identity which the name is pointing to.
- The `asset` argument MUST be the asset that represents ownership of a name.
- The `metadata` argument MUST contain `Some` bytes associated with the name or MUST be `None`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-17 standard. Logs MUST be emitted if there are changes that update ANY proof.

#### SRC17NameEvent

The `SRC17NameEvent` MUST be emitted when ANY data changes occur.

There SHALL be the following fields in the `SRC17UpdateEvent` struct:

- `name`: The `name` field SHALL be used for the corresponding `String` which represents the name.
- `resolver`: The `resolver` field SHALL be used for the corresponding `Identity` to which the name points.
- `asset`: The `asset` field SHALL be used for the corresponding `AssetId` that represents ownership of a name.
- `metadata`: The `metadata` field MUST contain `Some` bytes associated with the name or MUST be `None`.

Example:

```sway
pub struct SRC17NameEvent {
    pub name: String,
    pub resolver: Identity,
    pub asset: AssetId,
    pub metadata: Option<Bytes>
}
```

## Rationale

The development and implementation of this standard should enable the verification of names for infrastructure providers such as explorers, wallets, and more. Standardizing the verification method and leaving the implementation up to interpretation shall leave room for experimentation and differentiating designs between projects.

Additionally, the use of proofs should reduce the onchain footprint and minimize state. This standard notably has no expiry, a feature of most name service platforms. Should a project wish to implement an expiry, it should be included as part of the metadata.

## Backwards Compatibility

This standard is compatible with the existing name standards in the Fuel ecosystem, namely Bako ID and Fuel Name Service(FNS). There are no other standards that require compatibility.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

## Example ABI

```sway
pub type AltBn128Proof = [u8; 288];
pub type SparseMerkleProof = Proof;

pub enum SRC17Proof {
    AltBn128Proof: AltBn128Proof,
    SparseMerkleProof: SparseMerkleProof,
}

pub enum SRC17VerificationError {
    VerificationFailed: (),
}

abi SRC17 {
    #[storage(read)]
    fn verify(proof: SRC17Proof, name: String, resolver: Identity, asset: AssetId, metadata: Option<Bytes>) -> Result<(), SRC17VerificationError>;
}
```

## Example Implementation

### Sparse Merkle Verification Example

An example of the SRC-17 implementation where a Sparse Merkle Tree is used to verify the validity of names. In the example, the `name` is the key in the Sparse Merkle Tree and the `asset`, `resolver`, and `metadata` are the data which make up the leaf. The example supports both inclusion and exclusion proofs. If an AltBn128 proof is provided instead, the verification fails.

```sway
contract;

use std::{bytes::Bytes, hash::{Hash, sha256}, string::String};
use src17::{
    AltBn128Proof,
    SparseMerkleProof,
    SRC17,
    SRC17NameEvent,
    SRC17Proof,
    SRC17VerificationError,
};
use merkle::{common::MerkleRoot, sparse::MerkleTreeKey};

storage {
    merkle_root: MerkleRoot = MerkleRoot::zero(),
}

impl SRC17 for Contract {
    #[storage(read)]
    fn verify(
        proof: SRC17Proof,
        name: String,
        resolver: Identity,
        asset: AssetId,
        metadata: Option<Bytes>,
    ) -> Result<(), SRC17VerificationError> {
        match proof {
            SRC17Proof::AltBn128Proof(_) => Err(SRC17VerificationError::VerificationFailed),
            SRC17Proof::SparseMerkleProof(proof) => {
                let key: MerkleTreeKey = sha256(name);

                match proof {
                    SparseMerkleProof::Inclusion => {
                        // Combine the resolver, asset, and metadata into to a single Byte array.
                        let mut leaf_bytes = Bytes::new();
                        leaf_bytes.append(resolver.bits().into());
                        leaf_bytes.append(asset.bits().into());
                        match metadata {
                            Some(metadata_bytes) => {
                                leaf_bytes.append(metadata_bytes);
                            },
                            None => (),
                        }

                        if proof.verify(storage.merkle_root.read(), key, Some(leaf_bytes))
                        {
                            Ok(())
                        } else {
                            Err(SRC17VerificationError::VerificationFailed)
                        }
                    },
                    SparseMerkleProof::Exclusion => {
                        if proof.verify(storage.merkle_root.read(), key, None) {
                            Ok(())
                        } else {
                            Err(SRC17VerificationError::VerificationFailed)
                        }
                    }
                }
            }
        }
    }
}

abi UpdateData {
    fn data_updated(
        name: String,
        resolver: Identity,
        asset: AssetId,
        metadata: Option<Bytes>,
    );
}

impl UpdateData for Contract {
    fn data_updated(
        name: String,
        resolver: Identity,
        asset: AssetId,
        metadata: Option<Bytes>,
    ) {
        // NOTE: There are no checks for whether someone has the permission to do this. 
        // It is suggested to add some administrative controls such as the Sway-Libs Ownership Library.
        let event = SRC17NameEvent::new(name, resolver, asset, metadata);
        event.log();
    }
}

abi SetupExample {
    #[storage(write)]
    fn initialize(root: MerkleRoot);
}

impl SetupExample for Contract {
    #[storage(write)]
    fn initialize(root: MerkleRoot) {
        // NOTE: There are no checks for whether someone has the permission to do this. 
        // It is suggested to add some administrative controls such as the Sway-Libs Ownership Library.
        storage.merkle_root.write(root);
    }
}

```


---

### File: docs/sway-standards/docs/src/src-2-inline-documentation.md

# SRC-2: Inline Documentation

The following standard intends to define the structure and organization of inline documentation for functions, structs, enums, storage, configurables, and more within the Sway Language. This is a living standard.

## Motivation

The standard seeks to provide a better developer experience using Fuel's tooling and the Language Server. This will allow for better interoperability between applications and enable developers to quickly understand any external code they are using or implementing.

## Prior Art

A number of pre-existing functions in the [sway standard library](https://fuellabs.github.io/sway/master/std/), [sway-applications](https://github.com/FuelLabs/sway-applications), and [sway-libs](https://docs.fuel.network/docs/sway-libs/) repositories have inline documentation. The inline documentation for these is already compatible with Fuel's VS Code extension. These however do not all follow the same structure and outline.

## Specification

### Functions

The following describes the structure and order of inline documentation for functions. Some sections MAY NOT apply to each function. When a section is not relevant it SHALL be omitted.

#### Functions: Description

This section has no header.
A simple explanation of the function's intent or functionality.
Example:

```sway
/// This function computes the hash of two numbers.
```

#### Functions: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the function's intent or functionality.
Example:

```sway
/// # Additional Information
///
/// This function also has some complex behaviors.
```

#### Functions: Arguments

This section has a `h1` header.
Lists the arguments of the function's definition with the `*` symbol and describes each one. The list SHALL provide the name, type, and description. The argument SHALL be encapsulated between two backticks: `argument`. The type SHALL be encapsulated between two square brackets: [type].
Example:

```sway
/// # Arguments
///
/// * `argument_1`: [Identity] - This argument is a user to be hashed.
```

#### Functions: Returns

This section has a `h1` header.
Lists the return values of the function with the `*` symbol and describes each one. This list SHALL be in the order of the return index and provide the type and description. The type SHALL be encapsulated between two square brackets: [type].
Example:

```sway
/// # Returns
///
/// * [u64] - The number of hashes performed.
```

#### Functions: Reverts

This section has a `h1` header.
Lists the cases in which the function will revert starting with the `*` symbol. The list SHALL be in the order of occurrence within the function.
Example:

```sway
/// # Reverts
///
/// * When `argument_1` or `argument_2` are a zero [b256].
```

#### Functions: Number of Storage Accesses

This section has a `h1` header.
Provides information on how many storage reads, writes, and clears occur within the function.
Example:

```sway
/// # Number of Storage Accesses
///
/// * Reads: `1`
/// * Clears: `2`
```

#### Functions: Examples

This section has a `h1` header.
This section provides an example of the use of the function. This section is not required to follow the SRC-2 standard however encouraged for auxiliary and library functions.
Example:

```sway
/// # Examples
///
/// ```sway
/// fn foo(argument_1: b256, argument_2: b256) {
///     let result = my_function(argument_1, argument_2);
/// }
```

### Structs

The following describes the structure and order of inline documentation for structs. Some sections MAY NOT apply to each struct. When a section is not relevant it SHALL be omitted.

#### Structs: Description

This section has no header.
A simple explanation of the struct's purpose or functionality.
Example:

```sway
/// This struct contains information on an NFT.
```

#### Structs: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the struct's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This struct also has some complex behaviors.
```

### Fields

The following describes the structure and order of inline documentation for fields within structs. Some sections MAY NOT apply to each field. When a section is not relevant it SHALL be omitted.

#### Fields: Description

This section has no header.
Each field SHALL have its own description with a simple explanation of the field's purpose or functionality.
Example:

```sway
/// This field represents an owner.
field_1: Identity,
```

#### Fields: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the field's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This field also has some complex behaviors.
```

### Enums

The following describes the structure and order of inline documentation for enums. Some sections MAY NOT apply to each enum. When a section is not relevant it SHALL be omitted.

#### Enums: Description

This section has no header.
A simple explanation of the enum's purpose or functionality.
Example:

```sway
/// This enum holds the state of a contract.
```

#### Enums: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the enum's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This enum also has some complex behaviors.
```

### Variant

The following describes the structure and order of inline documentation for fields within enums. Some sections MAY NOT apply to each field. When a section is not relevant it SHALL be omitted.

#### Variant: Description

This section has no header.
Each variant SHALL have its own description with a simple explanation of the variant's purpose or functionality.
Example:

```sway
/// This variant represents the uninitialized state of a contract.
variant_1: (),
/// This variant represents the initialized state of a contract.
variant_2: Identity,
```

#### Variant: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the variant's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This variant also has some complex behaviors.
```

### Errors

In Sway, errors are recommended to be enums. They SHALL follow the same structure and order for inline documentation as described above for enums. Some sections MAY NOT apply to each error. When a section is not relevant it SHALL be omitted.

### Logs

In Sway, logs are recommended to be structs. They SHALL follow the same structure and order for inline documentation as described above for structs. Some sections MAY NOT apply to each log. When a section is not relevant it SHALL be omitted.

### Storage

The following describes the structure and order of inline documentation for variables within the storage block. Some sections MAY NOT apply to each storage variable. When a section is not relevant it SHALL be omitted.

#### Storage: Description

This section has no header.
A simple explanation of the storage variable's purpose or functionality.
Example:

```sway
/// This storage variable is used for state.
```

#### Storage: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the storage variable's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This storage variable maps a user to a state.
```

### Configurable

The following describes the structure and order of inline documentation for variables in the configurable block. Some sections MAY NOT apply to each storage variable. When a section is not relevant it SHALL be omitted.

#### Configurable: Description

This section has no header.
A simple explanation of the configurable variable's purpose or functionality.
Example:

```sway
/// This configurable variable is used for an address.
```

#### Configurable: Additional Information

This section has a `h1` header.
This section is directly below the description and can provide additional information beyond the configurable variable's purpose or functionality.
Example:

```sway
/// # Additional Information
///
/// This configurable variable makes security assumptions.
```

### Other Sections

If the above described sections are not relevant for the information that needs to documented, a custom section with a arbitrary `h1` header may be utilized.

Example:

```sway
/// # Recommended Message Style
///
/// We recommend that `expect` messages are used to describe the reason you *expect* the `Option` should be `Some`.
```

## Rationale

The SRC-2 standard should help provide developers with an easy way to both quickly write inline documentation and get up to speed on other developers' code. This standard in combination with Fuel's VS Code extension provides readily accessible information on functions, structs, and enums

![Screenshot 2023-05-10 125656](https://github.com/FuelLabs/sway-standards/assets/54727135/f03073b9-2a28-44d1-b12a-5603a0738fee)

## Backwards Compatibility

There are no standards that the SRC-2 standard requires to be backward compatible with.

## Security Considerations

This standard will improve security by providing developers with relevant information such as revert cases.

## Examples

### Function Example

```sway
/// Ensures that the sender is the owner.
///
/// # Arguments
///
/// * `number`: [u64] - A value that is checked to be 5.
///
/// # Returns
///
/// * [bool] - Determines whether `number` is or is not 5.
///
/// # Reverts
///
/// * When the sender is not the owner.
///
/// # Number of Storage Accesses
///
/// * Reads: `1`
///
/// # Examples
///
/// ```sway
/// use ownable::Ownership;
///
/// storage {
///     owner: Ownership = Ownership::initialized(Identity::Address(Address::zero())),
/// }
///
/// fn foo() {
///     storage.owner.only_owner();
///     // Do stuff here
/// }
#[storage(read)]
pub fn only_owner(self, number: u64) -> bool {
    require(self.owner() == State::Initialized(msg_sender().unwrap()), AccessError::NotOwner);
    number == 5
}
```

### Struct Examples

```sway
/// Metadata that is tied to an asset.
pub struct NFTMetadata {
    /// Represents the ID of this NFT.
    value: u64,
}
```

```sway
/// Log of a bid.
pub struct Bid {
    /// The number of coins that were bid.
    amount: u64,
    /// The user which placed this bid.
    bidder: Identity,
}
```

### Enum Examples

```sway
/// Determines the state of ownership.
pub enum State {
    /// The ownership has not been set.
    Uninitialized: (),
    /// The user who has been given ownership.
    Initialized: Identity,
    /// The ownership has been given up and can never be set again.
    Revoked: (),
}
```

```sway
/// Error log for when access is denied.
pub enum AccessError {
    /// Emitted when the caller is not the owner of the contract.
    NotOwner: (),
}
```

### Storage Examples

```sway
storage {
    /// An asset which is to be distributed.
    asset: Option<AssetId> = Option::None,
    /// Stores the ClaimState of users that have interacted with the Airdrop Distributor contract.
    ///
    /// # Additional Information
    ///
    /// Maps (user => claim)
    claims: StorageMap<Identity, ClaimState> = StorageMap {},
}
```

### Configurable Example

```sway
configurable {
    /// The threshold required for activation.
    THRESHOLD: u64 = 5,
}
```


---

### File: docs/sway-standards/docs/src/src-20-native-asset.md

# SRC-20: Native Asset

The following standard allows for the implementation of a standard API for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) using the Sway Language. This standard provides basic functionality as well as on-chain metadata for other applications to use.

## Motivation

A standard interface for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) on Fuel allows external applications to interact with the native asset, whether that be decentralized exchanges, wallets, or Fuel's [Scripts](https://docs.fuel.network/docs/sway/sway-program-types/scripts/) and [Predicates](https://docs.fuel.network/docs/sway/sway-program-types/predicates/).

## Prior Art

The SRC-20 Native Asset Standard naming pays homage to the [ERC-20 Token Standard](https://eips.ethereum.org/EIPS/eip-20) seen on Ethereum. While there is functionality we may use as a reference, it is noted that Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) are fundamentally different than Ethereum's tokens.

There has been a discussion of the Fungible Token Standard on the [Fuel Forum](https://forum.fuel.network/). This discussion can be found [here](https://forum.fuel.network/t/src-20-fungible-token-standard/186).

There has also been a Fungible Token Standard and Non-Fungible Token Standard implementations added to the [Sway-Libs](https://github.com/FuelLabs/sway-libs) repository before the creation of the [Sway-Standards](https://github.com/FuelLabs/sway-standards) repository. The introduction of this standard in the [Sway-Standards](https://github.com/FuelLabs/sway-standards) repository will deprecate the Sway-Libs Fungible Token Standard.

## Specification

### Required Public Functions

The following functions MUST be implemented to follow the SRC-20 standard:

#### `fn total_assets() -> u64`

This function MUST return the total number of individual assets for a contract.

#### `fn total_supply(asset: AssetId) -> Option<u64>`

This function MUST return the total supply of coins for an asset. This function MUST return `Some` for any assets minted by the contract.

#### `fn name(asset: AssetId) -> Option<String>`

This function MUST return the name of the asset, such as “Ether”. This function MUST return `Some` for any assets minted by the contract.

#### `fn symbol(asset: AssetId) -> Option<String>`

This function must return the symbol of the asset, such as “ETH”. This function MUST return `Some` for any assets minted by the contract.

#### `fn decimals(asset: AssetId) -> Option<u8>`

This function must return the number of decimals the asset uses - e.g. 8, which means to divide the coin amount by 100000000 to get its user representation. This function MUST return `Some` for any assets minted by the contract.

### Non-Fungible Asset Restrictions

Non-Fungible Tokens (NFT) or Non-Fungible Assets on Fuel are Native Assets and thus follow the same standard as Fungible Native Assets with some restrictions. For a Native Asset on Fuel to be deemed an NFT, the following must be applied:

* Non-Fungible Assets SHALL have a total supply of one per asset.
* Non-Fungible Assets SHALL have a decimal of `0u8`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-20 standard.

* IF a value is updated via a function call, a log MUST be emitted.
* IF a value is embedded in a contract as a constant, configurable, or other manner, an event MUST be emitted at least once.

#### SetNameEvent

The `SetNameEvent` MUST be emitted when the name of an asset has updated.

There SHALL be the following fields in the `SetNameEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `name`: The `name` field SHALL be used for the corresponding `Option<String>` which represents the name of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the name of the asset.

Example:

```sway
pub struct SetNameEvent {
    pub asset: AssetId,
    pub name: Option<String>,
    pub sender: Identity,
}
```

#### SetSymbolEvent

The `SetSymbolEvent` MUST be emitted when the symbol of an asset has updated.

There SHALL be the following fields in the `SetSymbolEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `symbol`: The `symbol` field SHALL be used for the corresponding `Option<String>` which represents the symbol of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the symbol of the asset.

Example:

```sway
pub struct SetSymbolEvent {
    pub asset: AssetId,
    pub symbol: Option<String>,
    pub sender: Identity,
}
```

#### SetDecimalsEvent

The `SetDecimalsEvent` MUST be emitted when the decimals of an asset has updated.

There SHALL be the following fields in the `SetDecimalsEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `decimals`: The `decimals` field SHALL be used for the corresponding `u8` which represents the decimals of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the decimals of the asset.

Example:

```sway
pub struct SetDecimalsEvent {
    pub asset: AssetId,
    pub decimals: u8,
    pub sender: Identity,
}
```

#### UpdateTotalSupplyEvent

The `UpdateTotalSupplyEvent` MUST be emitted when the total supply of an asset has updated.

There SHALL be the following fields in the `UpdateTotalSupplyEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `supply`: The `supply` field SHALL be used for the corresponding `u64` which represents the total supply of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the total supply of the asset.

Example:

```sway
pub struct UpdateTotalSupplyEvent {
    pub asset: AssetId,
    pub supply: u64,
    pub sender: Identity,
}
```

## Rationale

As the SRC-20 Native Asset Standard leverages Native Assets on Fuel, we do not require the implementation of certain functions such as transfer or approval. This is done directly within the FuelVM and there is no smart contract that requires updating of balances. As Fuel is UTXO based, any transfer events may be indexed on transaction receipts.

Following this, we have omitted the inclusion of any transfer functions or events. The provided specification outlines only the functions necessary to implement fully functional native assets on the Fuel Network. Additional functionality and properties may be added as needed.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). There are no other standards that require compatibility.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

## Example ABI

```sway
abi SRC20 {
    #[storage(read)]
    fn total_assets() -> u64;
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64>;
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String>;
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8>;
}
```

## Example Implementation

### Single Native Asset

Example of the SRC-20 implementation where a contract contains a single asset with one `SubId`. This implementation is recommended for users that intend to deploy a single asset with their contract.

```sway
contract;

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use std::{auth::msg_sender, string::String};

configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

impl SRC20 for Contract {
    /// Returns the total number of individual assets minted by a contract.
    ///
    /// # Additional Information
    ///
    /// For this single asset contract, this is always one.
    ///
    /// # Returns
    ///
    /// * [u64] - The number of assets that this contract has minted.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let assets = src_20_abi.total_assets();
    ///     assert(assets == 1);
    /// }
    /// ```
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    /// Returns the total supply of coins for the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the total supply, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u64>] - The total supply of an `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let supply = src_20_abi.total_supply(DEFAULT_SUB_ID);
    ///     assert(supply.unwrap() != 0);
    /// }
    /// ```
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }

    /// Returns the name of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the name, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The name of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let name = src_20_abi.name(DEFAULT_SUB_ID);
    ///     assert(name.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    /// Returns the symbol of the asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the symbol, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The symbol of `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let symbol = src_20_abi.symbol(DEFAULT_SUB_ID);
    ///     assert(symbol.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    /// Returns the number of decimals the asset uses.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the decimals, this should be the default `SubId`.
    ///
    /// # Returns
    ///
    /// * [Option<u8>] - The decimal precision used by `asset`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let decimals = src_20_abi.decimals(DEFAULT_SUB_ID);
    ///     assert(decimals.unwrap() == 9u8);
    /// }
    /// ```
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, TOTAL_SUPPLY, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-20 implementation where a contract contains multiple assets with differing `SubId`s. This implementation is recommended for users that intend to deploy multiple assets with their contract.

```sway
contract;

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use std::{hash::Hash, storage::storage_string::*, string::String};

storage {
    /// The total number of distinguishable assets minted by this contract.
    total_assets: u64 = 0,
    /// The total supply of coins for a specific asset minted by this contract.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// The name of a specific asset minted by this contract.
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    /// The symbol of a specific asset minted by this contract.
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    /// The decimals of a specific asset minted by this contract.
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC20 for Contract {
    /// Returns the total number of individual assets minted  by this contract.
    ///
    /// # Additional Information
    ///
    /// For this single asset contract, this is always one.
    ///
    /// # Returns
    ///
    /// * [u64] - The number of assets that this contract has minted.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let assets = src_20_abi.total_assets();
    ///     assert(assets == 1);
    /// }
    /// ```
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    /// Returns the total supply of coins for an asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the total supply.
    ///
    /// # Returns
    ///
    /// * [Option<u64>] - The total supply of an `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let supply = src_20_abi.total_supply(DEFAULT_SUB_ID);
    ///     assert(supply.unwrap() != 0);
    /// }
    /// ```
    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    /// Returns the name of an asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the name.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The name of `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let name = src_20_abi.name(DEFAULT_SUB_ID);
    ///     assert(name.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }

    /// Returns the symbol of am asset.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the symbol.
    ///
    /// # Returns
    ///
    /// * [Option<String>] - The symbol of `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let symbol = src_20_abi.symbol(DEFAULT_SUB_ID);
    ///     assert(symbol.is_some());
    /// }
    /// ```
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    /// Returns the number of decimals an asset uses.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the decimals.
    ///
    /// # Returns
    ///
    /// * [Option<u8>] - The decimal precision used by `asset`.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src20::SRC20;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let src_20_abi = abi(SRC20, contract_id);
    ///     let decimals = src_20_abi.decimals(DEFAULT_SUB_ID);
    ///     assert(decimals.unwrap() == 9u8);
    /// }
    /// ```
    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        total_supply: u64,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        supply: u64,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.get(asset).write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.get(asset).clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.get(asset).write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.get(asset).clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.get(asset).write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();

        storage.total_supply.get(asset).write(supply);
        TotalSupplyEvent::new(asset, supply, sender).log();
    }
}

```


---

### File: docs/sway-standards/docs/src/src-3-minting-and-burning.md

# SRC-3: Minting and Burning Native Assets

The following standard enables the minting and burning of native assets for any fungible assets within the Sway Language. It seeks to define mint and burn functions defined separately from the [SRC-20](./src-20-native-asset.md) standard.

## Motivation

The intent of this standard is to separate the extensions of minting and burning from the [SRC-20](./src-20-native-asset.md) standard.

## Prior Art

Minting and burning were initially added to the [SRC-20](./src-20-native-asset.md) standard.

## Specification

### Required Public Functions

The following functions MUST be implemented to follow the SRC-3 standard:

#### `fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64)`

This function MUST mint `amount` coins with a sub-identifier and transfer them to the `recipient`.
This function MUST use the `sub_id` as the sub-identifier IF `sub_id` is `Some`, otherwise this function MUST assign a `SubId` if the `sub_id` argument is `None`.
This function MAY contain arbitrary conditions for minting, and revert if those conditions are not met.

##### Mint Arguments

* `recipient` - The `Identity` to which the newly minted asset is transferred to.
* `sub_id` - The sub-identifier of the asset to mint. If this is `None`, a `SubId` MUST be assigned.
* `amount` - The quantity of coins to mint.

#### `fn burn(sub_id: SubId, amount: u64)`

This function MUST burn `amount` coins with the sub-identifier `sub_id` and MUST ensure the `AssetId` of the asset is the sha-256 hash of `(ContractId, SubId)` for the implementing contract.
This function MUST ensure at least `amount` coins have been transferred to the implementing contract.
This function MUST update the total supply defined in the [SRC-20](./src-20-native-asset.md) standard.
This function MAY contain arbitrary conditions for burning, and revert if those conditions are not met.

##### Burn Arguments

* `sub_id` - The sub-identifier of the asset to burn.
* `amount` - The quantity of coins to burn.

## Rationale

This standard has been added to enable compatibility between applications and allow minting and burning native assets per use case. This standard has been separated from the [SRC-20](./src-20-native-asset.md) standard to allow for the minting and burning for all fungible assets, irrelevant of whether they are [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) or not.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) ensuring its compatibility with the [SRC-20](./src-20-native-asset.md) standard.

## Security Considerations

This standard may introduce security considerations if no checks are implemented to ensure the calling of the `mint()` function is deemed valid or permitted. Checks are highly encouraged.
The burn function may also introduce a security consideration if the total supply within the [SRC-20](./src-20-native-asset.md) standard is not modified.

## Example ABI

```sway
abi SRC3 {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64);
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64);
}
```

## Example Implementation

### Single Native Asset

Example of the SRC-3 implementation where a contract only mints a single asset with one `SubId`.

```sway
contract;

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src3::SRC3;
use std::{
    asset::{
        burn,
        mint_to,
    },
    auth::msg_sender,
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    string::String,
};

configurable {
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

storage {
    /// The total supply of the asset minted by this contract.
    total_supply: u64 = 0,
}

impl SRC3 for Contract {
    /// Unconditionally mints new assets using the default SubId.
    ///
    /// # Arguments
    ///
    /// * `recipient`: [Identity] - The user to which the newly minted asset is transferred to.
    /// * `sub_id`: [SubId] - The default SubId.
    /// * `amount`: [u64] - The quantity of coins to mint.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    ///
    /// # Reverts
    ///
    /// * When the `sub_id` is not the default SubId.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let contract_abi = abi(SRC3, contract);
    ///     contract_abi.mint(Identity::ContractId(contract_id), Some(DEFAULT_SUB_ID), 100);
    /// }
    /// ```
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        require(
            sub_id
                .is_some() && sub_id
                .unwrap() == DEFAULT_SUB_ID,
            "Incorrect Sub Id",
        );

        // Increment total supply of the asset and mint to the recipient.
        let new_supply = amount + storage.total_supply.read();
        storage.total_supply.write(new_supply);

        mint_to(recipient, DEFAULT_SUB_ID, amount);

        TotalSupplyEvent::new(AssetId::default(), new_supply, msg_sender().unwrap())
            .log();
    }

    /// Unconditionally burns assets sent with the default SubId.
    ///
    /// # Arguments
    ///
    /// * `sub_id`: [SubId] - The default SubId.
    /// * `amount`: [u64] - The quantity of coins to burn.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    ///
    /// # Reverts
    ///
    /// * When the `sub_id` is not the default SubId.
    /// * When the transaction did not include at least `amount` coins.
    /// * When the transaction did not include the asset minted by this contract.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId, asset_id: AssetId) {
    ///     let contract_abi = abi(SRC3, contract_id);
    ///     contract_abi {
    ///         gas: 10000,
    ///         coins: 100,
    ///         asset_id: asset_id,
    ///     }.burn(DEFAULT_SUB_ID, 100);
    /// }
    /// ```
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        require(sub_id == DEFAULT_SUB_ID, "Incorrect Sub Id");
        require(msg_amount() >= amount, "Incorrect amount provided");
        require(
            msg_asset_id() == AssetId::default(),
            "Incorrect asset provided",
        );

        // Decrement total supply of the asset and burn.
        let new_supply = storage.total_supply.read() - amount;
        storage.total_supply.write(new_supply);

        burn(DEFAULT_SUB_ID, amount);

        TotalSupplyEvent::new(AssetId::default(), new_supply, msg_sender().unwrap())
            .log();
    }
}

// SRC3 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(storage.total_supply.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-3 implementation where a contract mints multiple assets with differing `SubId` values.

```sway
contract;

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src3::SRC3;
use std::{
    asset::{
        burn,
        mint_to,
    },
    auth::msg_sender,
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    hash::Hash,
    storage::storage_string::*,
    string::String,
};

// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
    /// The decimals of every asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of every asset minted by this contract.
    NAME: str[12] = __to_str_array("ExampleAsset"),
    /// The symbol of every asset minted by this contract.
    SYMBOL: str[2] = __to_str_array("EA"),
}

storage {
    /// The total number of distinguishable assets this contract has minted.
    total_assets: u64 = 0,
    /// The total supply of a particular asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
}

impl SRC3 for Contract {
    /// Unconditionally mints new assets using the `sub_id` sub-identifier.
    ///
    /// # Arguments
    ///
    /// * `recipient`: [Identity] - The user to which the newly minted asset is transferred to.
    /// * `sub_id`: [Option<SubId>] - The sub-identifier of the newly minted asset.
    /// * `amount`: [u64] - The quantity of coins to mint.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `2`
    /// * Writes: `2`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let contract_abi = abi(SRC3, contract_id);
    ///     contract_abi.mint(Identity::ContractId(contract_id), Some(DEFAULT_SUB_ID), 100);
    /// }
    /// ```
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        let sub_id = match sub_id {
            Some(s) => s,
            None => DEFAULT_SUB_ID,
        };
        let asset_id = AssetId::new(ContractId::this(), sub_id);

        // If this SubId is new, increment the total number of distinguishable assets this contract has minted.
        let asset_supply = storage.total_supply.get(asset_id).try_read();
        match asset_supply {
            None => {
                storage.total_assets.write(storage.total_assets.read() + 1)
            },
            _ => {},
        }

        // Increment total supply of the asset and mint to the recipient.
        let new_supply = amount + asset_supply.unwrap_or(0);
        storage.total_supply.insert(asset_id, new_supply);

        mint_to(recipient, sub_id, amount);

        TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
            .log();
    }

    /// Unconditionally burns assets sent with the `sub_id` sub-identifier.
    ///
    /// # Arguments
    ///
    /// * `sub_id`: [SubId] - The sub-identifier of the asset to burn.
    /// * `amount`: [u64] - The quantity of coins to burn.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    /// * Writes: `1`
    ///
    /// # Reverts
    ///
    /// * When the transaction did not include at least `amount` coins.
    /// * When the asset included in the transaction does not have the SubId `sub_id`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src3::SRC3;
    /// use std::constants::DEFAULT_SUB_ID;
    ///
    /// fn foo(contract_id: ContractId, asset_id: AssetId) {
    ///     let contract_abi = abi(SRC3, contract_id);
    ///     contract_abi {
    ///         gas: 10000,
    ///         coins: 100,
    ///         asset_id: asset_id,
    ///     }.burn(DEFAULT_SUB_ID, 100);
    /// }
    /// ```
    #[payable]
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        let asset_id = AssetId::new(ContractId::this(), sub_id);
        require(msg_amount() == amount, "Incorrect amount provided");
        require(msg_asset_id() == asset_id, "Incorrect asset provided");

        // Decrement total supply of the asset and burn.
        let new_supply = storage.total_supply.get(asset_id).read() - amount;
        storage.total_supply.insert(asset_id, new_supply);

        burn(sub_id, amount);

        TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
            .log();
    }
}

// SRC3 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(NAME))),
            None => None,
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(SYMBOL))),
            None => None,
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(DECIMALS),
            None => None,
        }
    }
}

abi SetSRC20Data {
    #[storage(read)]
    fn set_src20_data(asset: AssetId);
}

impl SetSRC20Data for Contract {
    #[storage(read)]
    fn set_src20_data(asset: AssetId) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
    }
}

```


---

### File: docs/sway-standards/docs/src/src-5-ownership.md

# SRC-5: Ownership

The following standard intends to enable the use of administrators or owners in Sway contracts.

## Motivation

The standard seeks to provide a method for restricting access to particular users within a Sway contract.

## Prior Art

The [sway-libs](https://docs.fuel.network/docs/sway-libs/ownership/) repository contains a pre-existing Ownership library.

Ownership libraries exist for other ecosystems such as OpenZeppelin's [Ownership library](https://docs.openzeppelin.com/contracts/2.x/api/ownership).

## Specification

### State

There SHALL be 3 states for any library implementing an ownership module in the following order:

#### `Uninitialized`

The `Uninitialized` state SHALL be set as the initial state if no owner or admin is set. The `Uninitialized` state MUST be used when an owner or admin MAY be set in the future.

#### `Initialized`

The `Initialized` state SHALL be set as the state if an owner or admin is set with an associated `Identity` type.

#### `Revoked`

The `Revoked` state SHALL be set when there is no owner or admin and there SHALL NOT be one set in the future.

Example:

```sway
pub enum State {
    Uninitialized: (),
    Initialized: Identity,
    Revoked: (),
}
```

### Functions

The following functions MUST be implemented to follow the SRC-5 standard:

#### `fn owner() -> State`

This function SHALL return the current state of ownership for the contract where `State` is either `Uninitialized`, `Initialized`, or `Revoked`.

### Errors

There SHALL be error handling.

#### `NotOwner`

This error MUST be emitted when `only_owner()` reverts.

## Rationale

In order to provide a universal method of administrative capabilities, SRC-5 will further enable interoperability between applications and provide safeguards for smart contract security.

## Backwards Compatibility

The SRC-5 standard is compatible with the [sway-libs](https://github.com/FuelLabs/sway-libs) repository pre-existing Ownership library. Considerations should be made to best handle multiple owners or admins.

There are no standards that SRC-5 requires to be compatible with.

## Security Considerations

The SRC-5 standard should help improve the security of Sway contracts and their interoperability.

## Example ABI

```sway
abi SRC5 {
    #[storage(read)]
    fn owner() -> State;
}
```

## Example Implementation

### Uninitialized

Example of the SRC-5 implementation where a contract does not have an owner set at compile time with the intent to set it during runtime.

```sway
contract;

use src5::{SRC5, State};

storage {
    /// The owner in storage.
    owner: State = State::Uninitialized,
}

impl SRC5 for Contract {
    /// Returns the owner.
    ///
    /// # Return Values
    ///
    /// * [State] - Represents the state of ownership for this contract.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src5::SRC5;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let ownership_abi = abi(contract_id, SRC_5);
    ///
    ///     match ownership_abi.owner() {
    ///         State::Uninitialized => log("The ownership is uninitialized"),
    ///         _ => log("This example will never reach this statement"),
    ///     }
    /// }
    /// ```
    #[storage(read)]
    fn owner() -> State {
        storage.owner.read()
    }
}

```

### Initialized

Example of the SRC-5 implementation where a contract has an owner set at compile time.

```sway
contract;

use src5::{SRC5, State};

/// The owner of this contract at deployment.
#[allow(dead_code)]
const INITIAL_OWNER: Identity = Identity::Address(Address::zero());

storage {
    /// The owner in storage.
    owner: State = State::Initialized(INITIAL_OWNER),
}

impl SRC5 for Contract {
    /// Returns the owner.
    ///
    /// # Return Values
    ///
    /// * [State] - Represents the state of ownership for this contract.
    ///
    /// # Number of Storage Accesses
    ///
    /// * Reads: `1`
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src5::SRC5;
    ///
    /// fn foo(contract_id: ContractId) {
    ///     let ownership_abi = abi(contract_id, SRC_5);
    ///
    ///     match ownership_abi.owner() {
    ///         State::Initialized(owner) => log("The ownership is initialized"),
    ///         _ => log("This example will never reach this statement"),
    ///     }
    /// }
    /// ```
    #[storage(read)]
    fn owner() -> State {
        storage.owner.read()
    }
}

```


---

### File: docs/sway-standards/docs/src/src-6-vault.md

# SRC-6: Vault

The following standard allows for the implementation of a standard API for asset vaults such as yield-bearing asset vaults or asset wrappers. This standard is an optional add-on to the [SRC-20](./src-20-native-asset.md) standard.

## Motivation

Asset vaults allow users to own shares of variable amounts of assets, such as lending protocols which may have growing assets due to profits from interest. This pattern is highly useful and would greatly benefit from standardization.

## Prior Art

Asset vaults have been thoroughly explored on Ethereum and with [EIP 4626](https://eips.ethereum.org/EIPS/eip-4626) they have their own standard for it. However as Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) are fundamentally different from Ethereum's ERC-20 tokens, the implementation will differ, but the interface may be used as a reference.

## Specification

### Required public functions

The following functions MUST be implemented to follow the SRC-6 standard. Any contract that implements the SRC-6 standard MUST implement the SRC-20 standard.

#### `fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64`

This function takes the `receiver` Identity and the SubId `vault_sub_id` of the sub-vault as an argument and returns the amount of shares minted to the `receiver`.

- This function MUST allow for depositing of the underlying asset in exchange for pro-rata shares of the vault.
- This function MAY reject arbitrary assets based on implementation and MUST revert if unaccepted assets are forwarded.
- This function MAY reject any arbitrary `receiver` based on implementation and MUST revert in the case of a blacklisted or non-whitelisted `receiver`.
- This function MUST mint an asset representing the pro-rata share of the vault, with the SubId of the `sha256((underlying_asset, vault_sub_id))` digest, where `underlying_asset` is the `AssetId` of the deposited asset and the `vault_sub_id` is the id of the vault.
- This function MUST emit a `Deposit` log.
- This function MUST return the amount of minted shares.

#### `fn withdraw(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> u64`

This function takes the `receiver` Identity, the `underlying_asset` `AssetId`, and the `vault_sub_id` of the sub vault, as arguments and returns the amount of assets transferred to the `receiver`.

- This function MUST allow for redeeming of the vault shares in exchange for a pro-rata amount of the underlying assets.
- This function MUST revert if any `AssetId` other than the `AssetId` representing the underlying asset's shares for the given sub vault at `vault_sub_id` is forwarded. (i.e. transferred share's `AssetId` must be equal to `AssetId::new(ContractId::this(), sha256((underlying_asset, vault_sub_id))`)
- This function MUST burn the received shares.
- This function MUST emit a `Withdraw` log.
- This function MUST return amount of assets transferred to the receiver.

#### `fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64`

This function returns the total assets under management by vault. Includes assets controlled by the vault but not directly possessed by vault. It takes the `underlying_asset` `AssetId` and the `vault_sub_id` of the sub vault as arguments and returns the total amount of assets of `AssetId` under management by vault.

- This function MUST return total amount of assets of `underlying_asset` `AssetId` under management by vault.
- This function MUST return 0 if there are no assets of `underlying_asset` `AssetId` under management by vault.
- This function MUST NOT revert under any circumstances.

#### `fn max_depositable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>`

This is a helper function for getting the maximum amount of assets that can be deposited. It takes the hypothetical `receiver` `Identity`, the `underlying_asset` `AssetId`, and the `vault_sub_id` `SubId` of the sub vault as an arguments and returns the maximum amount of assets that can be deposited into the contract, for the given asset.

- This function MUST return the maximum amount of assets that can be deposited into the contract, for the given `underlying_asset`, if the given `vault_sub_id` vault exists.
- This function MUST return an `Some(amount)` if the given `vault_sub_id` vault exists.
- This function MUST return an `None` if the given `vault_sub_id` vault does not exist.
- This function MUST account for both global and user specific limits. For example: if deposits are disabled, even temporarily, MUST return 0.

#### `fn max_withdrawable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>`

This is a helper function for getting maximum withdrawable. It takes the hypothetical `receiver` `Identity`, the `underlying_asset` `AssetId`, and the `vault_sub_id` SubId of the sub vault as an argument and returns the maximum amount of assets that can be withdrawn from the contract, for the given asset.

- This function MUST return the maximum amount of assets that can be withdrawn from the contract, for the given `underlying_asset`, if the given `vault_sub_id` vault exists.
- This function MUST return an `Some(amount)` if the given `vault_sub_id` vault exists.
- This function MUST return an `None` if the given `vault_sub_id` vault does not exist.
- This function MUST account for global limits. For example: if withdrawals are disabled, even temporarily, MUST return 0.

### Required logs

The following logs MUST be emitted at the specified occasions.

#### `Deposit`

`caller` has called the `deposit()` method sending `deposited_amount` assets of the `underlying_asset` Asset to the subvault of `vault_sub_id`, in exchange for `minted_shares` shares sent to the receiver `receiver`.

The `Deposit` struct MUST be logged whenever new shares are minted via the `deposit()` method.

The `Deposit` log SHALL have the following fields.

**`caller`: `Identity`**

The `caller` field MUST represent the `Identity` which called the deposit function.

**`receiver`: `Identity`**

The `receiver` field MUST represent the `Identity` which received the vault shares.

**`underlying_asset`: `AssetId`**

The `underlying_asset` field MUST represent the `AssetId` of the asset which was deposited into the vault.

**`vault_sub_id`: `SubId`**

The `vault_sub_id` field MUST represent the `SubId` of the vault which was deposited into.

**`deposited_amount`: `u64`**

The `deposited_amount` field MUST represent the `u64` amount of assets deposited into the vault.

**`minted_shares`: `u64`**

The `minted_shares` field MUST represent the `u64` amount of shares minted.

#### `Withdraw`

`caller` has called the `withdraw()` method sending `burned_shares` shares in exchange for `withdrawn_amount` assets of the `underlying_asset` Asset from the subvault of `vault_sub_id` to the receiver `receiver`.

The `Withdraw` struct MUST be logged whenever shares are redeemed for assets via the `withdraw()` method.

The `Withdraw` log SHALL have the following fields.

**`caller`: `Identity`**

The `caller` field MUST represent the Identity which called the withdraw function.

**`receiver`: `Identity`**

The `receiver` field MUST represent the Identity which received the withdrawn assets.

**`underlying_asset`: `AssetId`**

The `underlying_asset` field MUST represent the `AssetId` of the asset that was withdrawn.

**`vault_sub_id`: `SubId`**

The `vault_sub_id` field MUST represent the SubId of the vault from which was withdrawn.

**`withdrawn_amount`: `u64`**

The `withdrawn_amount` field MUST represent the `u64` amount of coins withdrawn.

**`burned_shares`: `u64`**

The `burned_shares` field MUST represent the `u64` amount of shares burned.

## Rationale

The ABI discussed covers the known use cases of asset vaults while allowing safe implementations.

## Backwards Compatibility

This standard is fully compatible with the [SRC-20 standard](./src-20-native-asset.md).

## Security Considerations

Incorrect implementation of asset vaults could allow attackers to steal underlying assets. It is recommended to properly audit any code using this standard to ensure exploits are not possible.

## Example ABI

```sway
abi SRC6 {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64;

    #[payable]
    #[storage(read, write)]
    fn withdraw(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> u64;

    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64;

    #[storage(read)]
    fn max_depositable(receiver: Identity, underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>;

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64>;
}
```

## Example Implementation

### Multi Asset Vault

A basic implementation of the vault standard that supports any number of sub vaults being created for every `AssetId`.

```sway
contract;

use std::{
    asset::transfer,
    call_frames::msg_asset_id,
    context::msg_amount,
    hash::{
        Hash,
        sha256,
    },
    storage::storage_string::*,
    string::String,
};

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src6::{Deposit, SRC6, Withdraw};

pub struct VaultInfo {
    /// Amount of assets currently managed by this vault
    managed_assets: u64,
    /// The vault_sub_id of this vault.
    vault_sub_id: SubId,
    /// The asset being managed by this vault
    asset: AssetId,
}

storage {
    /// Vault share AssetId -> VaultInfo.
    vault_info: StorageMap<AssetId, VaultInfo> = StorageMap {},
    /// Number of different assets managed by this contract.
    total_assets: u64 = 0,
    /// Total supply of shares for each asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// Asset name.
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset symbol.
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset decimals.
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC6 for Contract {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64 {
        let asset_amount = msg_amount();
        require(asset_amount != 0, "ZERO_ASSETS");

        let underlying_asset = msg_asset_id();
        let (shares, share_asset, share_asset_vault_sub_id) = preview_deposit(underlying_asset, vault_sub_id, asset_amount);

        _mint(receiver, share_asset, share_asset_vault_sub_id, shares);

        let mut vault_info = match storage.vault_info.get(share_asset).try_read() {
            Some(vault_info) => vault_info,
            None => VaultInfo {
                managed_assets: 0,
                vault_sub_id,
                asset: underlying_asset,
            },
        };
        vault_info.managed_assets = vault_info.managed_assets + asset_amount;
        storage.vault_info.insert(share_asset, vault_info);

        Deposit::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            asset_amount,
            shares,
        )
            .log();

        shares
    }

    #[payable]
    #[storage(read, write)]
    fn withdraw(
        receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> u64 {
        let shares = msg_amount();
        require(shares != 0, "ZERO_SHARES");

        let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

        require(msg_asset_id() == share_asset_id, "INVALID_ASSET_ID");
        let assets = preview_withdraw(share_asset_id, shares);

        let mut vault_info = storage.vault_info.get(share_asset_id).read();
        vault_info.managed_assets = vault_info.managed_assets - shares;
        storage.vault_info.insert(share_asset_id, vault_info);

        _burn(share_asset_id, share_asset_vault_sub_id, shares);

        transfer(receiver, underlying_asset, assets);

        Withdraw::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            assets,
            shares,
        )
            .log();

        assets
    }
    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64 {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
        // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
        managed_assets(vault_share_asset)
    }

    #[storage(read)]
    fn max_depositable(
        _receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
        // This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
        match storage.vault_info.get(vault_share_asset).try_read() {
            Some(vault_info) => Some(u64::max() - vault_info.managed_assets),
            None => None,
        }
    }

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
        // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, total_assets should be greater than max_withdrawable.
        match storage.vault_info.get(vault_share_asset).try_read() {
            Some(vault_info) => Some(vault_info.managed_assets),
            None => None,
        }
    }
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.try_read().unwrap_or(0)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.get(asset).write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.get(asset).clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.get(asset).write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.get(asset).clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.get(asset).write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();
    }
}

/// Returns the vault shares assetid and subid for the given assets assetid and the vaults sub id
fn vault_asset_id(asset: AssetId, vault_sub_id: SubId) -> (AssetId, SubId) {
    let share_asset_vault_sub_id = sha256((asset, vault_sub_id));
    let share_asset_id = AssetId::new(ContractId::this(), share_asset_vault_sub_id);
    (share_asset_id, share_asset_vault_sub_id)
}

#[storage(read)]
fn managed_assets(vault_share_asset_id: AssetId) -> u64 {
    match storage.vault_info.get(vault_share_asset_id).try_read() {
        Some(vault_info) => vault_info.managed_assets,
        None => 0,
    }
}

#[storage(read)]
fn preview_deposit(
    underlying_asset: AssetId,
    vault_sub_id: SubId,
    assets: u64,
) -> (u64, AssetId, SubId) {
    let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

    let shares_supply = storage.total_supply.get(share_asset_id).try_read().unwrap_or(0);
    if shares_supply == 0 {
        (assets, share_asset_id, share_asset_vault_sub_id)
    } else {
        (
            assets * shares_supply / managed_assets(share_asset_id),
            share_asset_id,
            share_asset_vault_sub_id,
        )
    }
}

#[storage(read)]
fn preview_withdraw(share_asset_id: AssetId, shares: u64) -> u64 {
    let supply = storage.total_supply.get(share_asset_id).read();
    if supply == shares {
        managed_assets(share_asset_id)
    } else {
        shares * (managed_assets(share_asset_id) / supply)
    }
}

#[storage(read, write)]
pub fn _mint(
    recipient: Identity,
    asset_id: AssetId,
    vault_sub_id: SubId,
    amount: u64,
) {
    use std::asset::mint_to;

    let supply = storage.total_supply.get(asset_id).try_read();
    // Only increment the number of assets minted by this contract if it hasn't been minted before.
    if supply.is_none() {
        storage.total_assets.write(storage.total_assets.read() + 1);
    }
    let new_supply = supply.unwrap_or(0) + amount;
    storage.total_supply.insert(asset_id, new_supply);
    mint_to(recipient, vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

#[storage(read, write)]
pub fn _burn(asset_id: AssetId, vault_sub_id: SubId, amount: u64) {
    use std::{asset::burn, context::this_balance};

    require(
        this_balance(asset_id) >= amount,
        "BurnError::NotEnoughCoins",
    );
    // If we pass the check above, we can assume it is safe to unwrap.
    let supply = storage.total_supply.get(asset_id).try_read().unwrap();
    let new_supply = supply - amount;
    storage.total_supply.insert(asset_id, new_supply);
    burn(vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

```

### Single Asset Vault

A basic implementation of the vault standard demonstrating how to restrict deposits and withdrawals to a single `AssetId`.

```sway
contract;

use std::{
    asset::transfer,
    call_frames::msg_asset_id,
    context::msg_amount,
    hash::{
        Hash,
        sha256,
    },
    storage::storage_string::*,
    string::String,
};

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src6::{Deposit, SRC6, Withdraw};

pub struct VaultInfo {
    /// Amount of assets currently managed by this vault
    managed_assets: u64,
    /// The vault_sub_id of this vault.
    vault_sub_id: SubId,
    /// The asset being managed by this vault
    asset: AssetId,
}

storage {
    /// Vault share AssetId -> VaultInfo.
    vault_info: StorageMap<AssetId, VaultInfo> = StorageMap {},
    /// Number of different assets managed by this contract.
    total_assets: u64 = 0,
    /// Total supply of shares.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// Asset name.
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset symbol.
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    /// Asset decimals.
    decimals: StorageMap<AssetId, u8> = StorageMap {},
}

impl SRC6 for Contract {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64 {
        let asset_amount = msg_amount();
        let underlying_asset = msg_asset_id();

        require(underlying_asset == AssetId::base(), "INVALID_ASSET_ID");
        let (shares, share_asset, share_asset_vault_sub_id) = preview_deposit(underlying_asset, vault_sub_id, asset_amount);
        require(asset_amount != 0, "ZERO_ASSETS");

        _mint(receiver, share_asset, share_asset_vault_sub_id, shares);

        let mut vault_info = match storage.vault_info.get(share_asset).try_read() {
            Some(vault_info) => vault_info,
            None => VaultInfo {
                managed_assets: 0,
                vault_sub_id,
                asset: underlying_asset,
            },
        };
        vault_info.managed_assets = vault_info.managed_assets + asset_amount;
        storage.vault_info.insert(share_asset, vault_info);

        Deposit::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            asset_amount,
            shares,
        )
            .log();

        shares
    }

    #[payable]
    #[storage(read, write)]
    fn withdraw(
        receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> u64 {
        let shares = msg_amount();
        require(shares != 0, "ZERO_SHARES");

        let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

        require(msg_asset_id() == share_asset_id, "INVALID_ASSET_ID");
        let assets = preview_withdraw(share_asset_id, shares);

        let mut vault_info = storage.vault_info.get(share_asset_id).read();
        vault_info.managed_assets = vault_info.managed_assets - shares;
        storage.vault_info.insert(share_asset_id, vault_info);

        _burn(share_asset_id, share_asset_vault_sub_id, shares);

        transfer(receiver, underlying_asset, assets);

        Withdraw::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            assets,
            shares,
        )
            .log();

        assets
    }

    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64 {
        if underlying_asset == AssetId::base() {
            let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            managed_assets(vault_share_asset)
        } else {
            0
        }
    }

    #[storage(read)]
    fn max_depositable(
        _receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;

        match (
            underlying_asset == AssetId::base(),
            storage.vault_info.get(vault_share_asset).try_read(),
        ) {
            // This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
            (true, Some(vault_info)) => Some(u64::max() - vault_info.managed_assets),
            _ => None,
        }
    }

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64> {
        let vault_share_asset = vault_asset_id(underlying_asset, vault_sub_id).0;

        match (
            underlying_asset == AssetId::base(),
            storage.vault_info.get(vault_share_asset).try_read(),
        ) {
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            (true, Some(vault_info)) => Some(vault_info.managed_assets),
            _ => None,
        }
    }
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.try_read().unwrap_or(0)
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.get(asset).write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.get(asset).clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.get(asset).write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.get(asset).clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.get(asset).write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();
    }
}

/// Returns the vault shares assetid and subid for the given assets assetid and the vaults sub id
fn vault_asset_id(underlying_asset: AssetId, vault_sub_id: SubId) -> (AssetId, SubId) {
    let share_asset_vault_sub_id = sha256((underlying_asset, vault_sub_id));
    let share_asset_id = AssetId::new(ContractId::this(), share_asset_vault_sub_id);
    (share_asset_id, share_asset_vault_sub_id)
}

#[storage(read)]
fn managed_assets(vault_share_asset_id: AssetId) -> u64 {
    match storage.vault_info.get(vault_share_asset_id).try_read() {
        Some(vault_info) => vault_info.managed_assets,
        None => 0,
    }
}

#[storage(read)]
fn preview_deposit(
    underlying_asset: AssetId,
    vault_sub_id: SubId,
    assets: u64,
) -> (u64, AssetId, SubId) {
    let (share_asset_id, share_asset_vault_sub_id) = vault_asset_id(underlying_asset, vault_sub_id);

    let shares_supply = storage.total_supply.get(share_asset_id).try_read().unwrap_or(0);
    if shares_supply == 0 {
        (assets, share_asset_id, share_asset_vault_sub_id)
    } else {
        (
            assets * shares_supply / managed_assets(share_asset_id),
            share_asset_id,
            share_asset_vault_sub_id,
        )
    }
}

#[storage(read)]
fn preview_withdraw(share_asset_id: AssetId, shares: u64) -> u64 {
    let supply = storage.total_supply.get(share_asset_id).read();
    if supply == shares {
        managed_assets(share_asset_id)
    } else {
        shares * (managed_assets(share_asset_id) / supply)
    }
}

#[storage(read, write)]
pub fn _mint(
    recipient: Identity,
    asset_id: AssetId,
    vault_sub_id: SubId,
    amount: u64,
) {
    use std::asset::mint_to;

    let supply = storage.total_supply.get(asset_id).try_read();
    // Only increment the number of assets minted by this contract if it hasn't been minted before.
    if supply.is_none() {
        storage.total_assets.write(storage.total_assets.read() + 1);
    }
    let new_supply = supply.unwrap_or(0) + amount;
    storage.total_supply.insert(asset_id, new_supply);
    mint_to(recipient, vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

#[storage(read, write)]
pub fn _burn(asset_id: AssetId, vault_sub_id: SubId, amount: u64) {
    use std::{asset::burn, context::this_balance};

    require(
        this_balance(asset_id) >= amount,
        "BurnError::NotEnoughCoins",
    );
    // If we pass the check above, we can assume it is safe to unwrap.
    let supply = storage.total_supply.get(asset_id).try_read().unwrap();
    let new_supply = supply - amount;
    storage.total_supply.insert(asset_id, new_supply);
    burn(vault_sub_id, amount);
    TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap())
        .log();
}

```

## Single Asset Single Sub Vault

A basic implementation of the vault standard demonstrating how to restrict deposits and withdrawals to a single `AssetId`, and to a single Sub vault.

```sway
contract;

use std::{
    asset::transfer,
    call_frames::msg_asset_id,
    context::msg_amount,
    hash::{
        Hash,
        sha256,
    },
    storage::storage_string::*,
    string::String,
};

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src6::{Deposit, SRC6, Withdraw};

configurable {
    /// The only sub vault that can be deposited and withdrawn from this vault.
    ACCEPTED_SUB_VAULT: SubId = SubId::zero(),
    PRE_CALCULATED_SHARE_VAULT_SUB_ID: SubId = 0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b,
}

storage {
    /// The total amount of assets managed by this vault.
    managed_assets: u64 = 0,
    /// The total amount of shares minted by this vault.
    total_supply: u64 = 0,
    /// The name of a specific asset minted by this contract.
    name: StorageString = StorageString {},
    /// The symbol of a specific asset minted by this contract.
    symbol: StorageString = StorageString {},
    /// The decimals of a specific asset minted by this contract.
    decimals: u8 = 9,
}

impl SRC6 for Contract {
    #[payable]
    #[storage(read, write)]
    fn deposit(receiver: Identity, vault_sub_id: SubId) -> u64 {
        require(vault_sub_id == ACCEPTED_SUB_VAULT, "INVALID_vault_sub_id");

        let underlying_asset = msg_asset_id();
        require(underlying_asset == AssetId::base(), "INVALID_ASSET_ID");

        let asset_amount = msg_amount();
        require(asset_amount != 0, "ZERO_ASSETS");
        let shares = preview_deposit(asset_amount);

        _mint(receiver, shares);

        storage
            .managed_assets
            .write(storage.managed_assets.read() + asset_amount);

        Deposit::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            asset_amount,
            shares,
        )
            .log();

        shares
    }

    #[payable]
    #[storage(read, write)]
    fn withdraw(
        receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> u64 {
        require(underlying_asset == AssetId::base(), "INVALID_ASSET_ID");
        require(vault_sub_id == ACCEPTED_SUB_VAULT, "INVALID_vault_sub_id");

        let shares = msg_amount();
        require(shares != 0, "ZERO_SHARES");

        let share_asset_id = vault_assetid();

        require(msg_asset_id() == share_asset_id, "INVALID_ASSET_ID");
        let assets = preview_withdraw(shares);

        storage
            .managed_assets
            .write(storage.managed_assets.read() - shares);

        _burn(share_asset_id, shares);

        transfer(receiver, underlying_asset, assets);

        Withdraw::new(
            msg_sender()
                .unwrap(),
            receiver,
            underlying_asset,
            vault_sub_id,
            assets,
            shares,
        )
            .log();

        assets
    }

    #[storage(read)]
    fn managed_assets(underlying_asset: AssetId, vault_sub_id: SubId) -> u64 {
        if underlying_asset == AssetId::base() && vault_sub_id == ACCEPTED_SUB_VAULT {
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            storage.managed_assets.read()
        } else {
            0
        }
    }

    #[storage(read)]
    fn max_depositable(
        _receiver: Identity,
        underlying_asset: AssetId,
        vault_sub_id: SubId,
    ) -> Option<u64> {
        if underlying_asset == AssetId::base() && vault_sub_id == ACCEPTED_SUB_VAULT {
            // This is the max value of u64 minus the current managed_assets. Ensures that the sum will always be lower than u64::MAX.
            Some(u64::max() - storage.managed_assets.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn max_withdrawable(underlying_asset: AssetId, vault_sub_id: SubId) -> Option<u64> {
        if underlying_asset == AssetId::base() && vault_sub_id == ACCEPTED_SUB_VAULT {
            // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable.
            Some(storage.managed_assets.read())
        } else {
            None
        }
    }
}

impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == vault_assetid() {
            Some(storage.total_supply.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == vault_assetid() {
            match storage.name.read_slice() {
                Some(name) => Some(name),
                None => None,
            }
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == vault_assetid() {
            match storage.symbol.read_slice() {
                Some(symbol) => Some(symbol),
                None => None,
            }
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == vault_assetid() {
            Some(storage.decimals.read())
        } else {
            None
        }
    }
}

abi SetSRC20Data {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    );
}

impl SetSRC20Data for Contract {
    #[storage(read, write)]
    fn set_src20_data(
        asset: AssetId,
        name: Option<String>,
        symbol: Option<String>,
        decimals: u8,
    ) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        require(asset == vault_assetid(), "INVALID_ASSET_ID");
        let sender = msg_sender().unwrap();

        match name {
            Some(unwrapped_name) => {
                storage.name.write_slice(unwrapped_name);
                SetNameEvent::new(asset, name, sender).log();
            },
            None => {
                let _ = storage.name.clear();
                SetNameEvent::new(asset, name, sender).log();
            }
        }

        match symbol {
            Some(unwrapped_symbol) => {
                storage.symbol.write_slice(unwrapped_symbol);
                SetSymbolEvent::new(asset, symbol, sender).log();
            },
            None => {
                let _ = storage.symbol.clear();
                SetSymbolEvent::new(asset, symbol, sender).log();
            }
        }

        storage.decimals.write(decimals);
        SetDecimalsEvent::new(asset, decimals, sender).log();
    }
}

/// Returns the vault shares assetid for the given assets assetid and the vaults sub id
fn vault_assetid() -> AssetId {
    let share_asset_id = AssetId::new(ContractId::this(), PRE_CALCULATED_SHARE_VAULT_SUB_ID);
    share_asset_id
}

#[storage(read)]
fn preview_deposit(assets: u64) -> u64 {
    let shares_supply = storage.total_supply.try_read().unwrap_or(0);
    if shares_supply == 0 {
        assets
    } else {
        assets * shares_supply / storage.managed_assets.try_read().unwrap_or(0)
    }
}

#[storage(read)]
fn preview_withdraw(shares: u64) -> u64 {
    let supply = storage.total_supply.read();
    if supply == shares {
        storage.managed_assets.read()
    } else {
        shares * (storage.managed_assets.read() / supply)
    }
}

#[storage(read, write)]
pub fn _mint(recipient: Identity, amount: u64) {
    use std::asset::mint_to;

    let supply = storage.total_supply.read();
    let new_supply = supply + amount;
    storage.total_supply.write(new_supply);
    mint_to(recipient, PRE_CALCULATED_SHARE_VAULT_SUB_ID, amount);
    TotalSupplyEvent::new(vault_assetid(), new_supply, msg_sender().unwrap())
        .log();
}

#[storage(read, write)]
pub fn _burn(asset_id: AssetId, amount: u64) {
    use std::{asset::burn, context::this_balance};

    require(
        this_balance(asset_id) >= amount,
        "BurnError::NotEnoughCoins",
    );
    // If we pass the check above, we can assume it is safe to unwrap.
    let supply = storage.total_supply.read();
    let new_supply = supply - amount;
    storage.total_supply.write(new_supply);
    burn(PRE_CALCULATED_SHARE_VAULT_SUB_ID, amount);
    TotalSupplyEvent::new(vault_assetid(), new_supply, msg_sender().unwrap())
        .log();
}

```


---

### File: docs/sway-standards/docs/src/src-7-asset-metadata.md

# SRC-7: Onchain Native Asset Metadata

The following standard attempts to define the retrieval of onchain arbitrary metadata for any [Native Asset](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). This standard should be used if a stateful approach is needed. Any contract that implements the SRC-7 standard MUST implement the [SRC-20](./src-20-native-asset.md) standard.

> **NOTE** If data is not needed onchain, it is recommended to use the [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md).

## Motivation

The SRC-7 standard seeks to enable stateful data-rich assets on the Fuel Network while maintaining compatibility between multiple assets minted by the same contract. The standard ensures type safety with the use of an `enum` and an `Option`. All metadata queries are done through a single function to facilitate cross-contract calls.

## Prior Art

The use of generic metadata was originally found in the Sway-Lib's [NFT Library](https://github.com/FuelLabs/sway-libs/tree/v0.12.0/libs/nft) which did not use Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). This library has since been deprecated.

A previous definition for a metadata standard was written in the original edit of the now defunct [SRC-721](https://github.com/FuelLabs/sway-standards/issues/2). This has since been replaced with the [SRC-20](./src-20-native-asset.md) standard as `SubId` was introduced to enable multiple assets to be minted from a single contract.

The standard takes inspiration from [ENS's public resolver](https://docs.ens.domains/contract-api-reference/publicresolver) with the use of a `String` as the key. This should enable human-readable keys to help minimize errors and enable the standardization of certain keys, such as "image" as opposed to an `enum` or `u64` representation of keys.

We also take a look at existing common metadata practices such as [OpenSea's Metadata Standards](https://docs.opensea.io/docs/metadata-standards) and seek to stay backwards compatible with them while enabling more functionality. Through the combination of `String` keys and various return types, both pre-defined URIs or specific attributes may be stored and retrieved with the SRC-7 standard.

## Specification

### Metadata Type

The following describes an enum that wraps various metadata types into a single return type. There SHALL be the following variants in the `Metadata` enum:

#### `B256`

The `B256` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `Sting` key pair is of the `b256` type.

#### `Bytes`

The `Bytes` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `String` key pair is of the `Bytes` type. The `Bytes` variant should be used when storing custom data such as but not limited to structs and enums.

#### `Int`

The `Int` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `Sting` key pair is of the `u64` type.

#### `String`

The `String` variant SHALL be used when the stored metadata for the corresponding `AssetId` and `String` key pair is of the `String` type. The `String` variant MUST be used when a URI is required but MAY contain any arbitrary `String` data.

### Required Functions

#### `fn metadata(asset: AssetId, key: String) -> Option<Metadata>`

This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `B256`, `Bytes`, `Int`, or `String` variant. If the asset does not exist or no metadata exists, the function MUST return `None`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-7 standard.

* IF a value is updated via a function call, a log MUST be emitted.
* IF a value is embedded in a contract as a constant, configurable, or other manner, an event MUST be emitted at least once.

#### SetMetadataEvent

The `SetMetadataEvent` MUST be emitted when the metadata of an asset has updated.

There SHALL be the following fields in the `SetMetadataEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` for the asset that has been updated.
* `metadata`: The `metadata` field SHALL be used for the corresponding `Option<Metadata>` which represents the metadata of the asset.
* `key`: The `key` field SHALL be used for the corresponding `String` which represents the key used for storing the metadata.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the metadata of the asset.

Example:

```sway
pub struct SetMetadataEvent {
    pub asset: AssetId,
    pub metadata: Option<Metadata>,
    pub key: String,
    pub sender: Identity,
}
```

## Rationale

The SRC-7 standard should allow for stateful data-rich assets to interact with one another in a safe manner.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) and the [SRC-20](./src-20-native-asset.md) standard. It also maintains compatibility with existing standards in other ecosystems.

## Security Considerations

This standard does not introduce any security concerns, as it does not call external contracts, nor does it define any mutations of the contract state.

## Example ABI

```sway
abi SRC7 {
     #[storage(read)]
     fn metadata(asset: AssetId, key: String) -> Option<Metadata>;
}
```

## Example Implementation

### Single Native Asset

Example of the SRC-7 implementation where metadata exists for only a single asset with one `SubId`.

```sway
contract;

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src7::{Metadata, SetMetadataEvent, SRC7};

use std::string::String;

configurable {
    /// The total supply of coins for the asset minted by this contract.
    TOTAL_SUPPLY: u64 = 100_000_000,
    /// The decimals of the asset minted by this contract.
    DECIMALS: u8 = 9u8,
    /// The name of the asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of the asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYTKN"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
    /// The metadata for the "attr:health" key.
    ATTR_HEALTH: u64 = 100,
}

impl SRC7 for Contract {
    /// Returns metadata for the corresponding `asset` and `key`.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the metadata.
    /// * `key`: [String] - The key to the specific metadata.
    ///
    /// # Returns
    ///
    /// * [Option<Metadata>] - `Some` metadata that corresponds to the `key` or `None`.
    ///
    /// # Reverts
    ///
    /// * When the AssetId provided does not match the default SubId.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src7::{SRC7, Metadata};
    /// use std::string::String;
    ///
    /// fn foo(contract_id: ContractId, asset: AssetId) {
    ///     let contract_abi = abi(SRC7, contract_id);
    ///     let key = String::from_ascii_str("social:x");
    ///     let data = contract_abi.metadata(asset, key);
    ///     assert(data.unwrap() == Metadata::String(String::from_ascii_str("fuel_network")));
    /// }
    /// ```
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        require(asset == AssetId::default(), "Invalid AssetId provided");

        if key == String::from_ascii_str("social:x") {
            Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))))
        } else if key == String::from_ascii_str("site:forum") {
            Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))))
        } else if key == String::from_ascii_str("attr:health") {
            Some(Metadata::Int(ATTR_HEALTH))
        } else {
            None
        }
    }
}

abi EmitSRC7Events {
    fn emit_src7_events();
}

impl EmitSRC7Events for Contract {
    fn emit_src7_events() {
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let metadata_1 = Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))));
        let metadata_2 = Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))));
        let metadata_3 = Some(Metadata::Int(ATTR_HEALTH));
        let key_1 = String::from_ascii_str("social:x");
        let key_2 = String::from_ascii_str("site:forum");
        let key_3 = String::from_ascii_str("attr:health");

        SetMetadataEvent::new(asset, metadata_1, key_1, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_2, key_2, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_3, key_3, sender)
            .log();
    }
}

// SRC7 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(TOTAL_SUPPLY)
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, TOTAL_SUPPLY, sender).log();
    }
}

```

### Multi Native Asset

Example of the SRC-7 implementation where metadata exists for multiple assets with differing `SubId` values.

```sway
contract;

use src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent};
use src7::{Metadata, SetMetadataEvent, SRC7};

use std::{hash::Hash, storage::storage_string::*, string::String};

// In this example, all assets minted from this contract have the same decimals, name, and symbol
configurable {
    /// The decimals of every asset minted by this contract.
    DECIMALS: u8 = 0u8,
    /// The name of every asset minted by this contract.
    NAME: str[7] = __to_str_array("MyAsset"),
    /// The symbol of every asset minted by this contract.
    SYMBOL: str[5] = __to_str_array("MYAST"),
    /// The metadata for the "social:x" key.
    SOCIAL_X: str[12] = __to_str_array("fuel_network"),
    /// The metadata for the "site:forum" key.
    SITE_FORUM: str[27] = __to_str_array("https://forum.fuel.network/"),
}

storage {
    /// The total number of distinguishable assets this contract has minted.
    total_assets: u64 = 0,
    /// The total supply of a particular asset.
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    /// The metadata for the "image:svg" key.
    svg_images: StorageMap<AssetId, StorageString> = StorageMap {},
    /// The metadata for the "attr:health" key.
    health_attributes: StorageMap<AssetId, u64> = StorageMap {},
}

impl SRC7 for Contract {
    /// Returns metadata for the corresponding `asset` and `key`.
    ///
    /// # Arguments
    ///
    /// * `asset`: [AssetId] - The asset of which to query the metadata.
    /// * `key`: [String] - The key to the specific metadata.
    ///
    /// # Returns
    ///
    /// * [Option<Metadata>] - `Some` metadata that corresponds to the `key` or `None`.
    ///
    /// # Examples
    ///
    /// ```sway
    /// use src7::{SRC7, Metadata};
    /// use std::string::String;
    ///
    /// fn foo(contract_id: ContractId, asset: AssetId) {
    ///     let contract_abi = abi(SRC7, contract_id);
    ///     let key = String::from_ascii_str("social:x");
    ///     let data = contract_abi.metadata(asset, key);
    ///     assert(data.unwrap() == Metadata::String(String::from_ascii_str("fuel_network")));
    /// }
    /// ```
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        // If this asset does not exist, return None
        if storage.total_supply.get(asset).try_read().is_none() {
            return None
        }

        if key == String::from_ascii_str("social:x") {
            // The "social:x" for all assets minted by this contract are the same.
            Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))))
        } else if key == String::from_ascii_str("site:forum") {
            // The "site:forums" for all assets minted by this contract are the same.
            Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))))
        } else if key == String::from_ascii_str("image:svg") {
            // The SVG image is stored as a String in storage for each asset
            let svg_image = storage.svg_images.get(asset).read_slice();

            match svg_image {
                Some(svg) => Some(Metadata::String(svg)),
                None => None,
            }
        } else if key == String::from_ascii_str("attr:health") {
            // The health attribute is stored as a u64 in storage for each asset
            let health_attribute = storage.health_attributes.get(asset).try_read();

            match health_attribute {
                Some(health) => Some(Metadata::Int(health)),
                None => None,
            }
        } else {
            None
        }
    }
}

abi SetSRC7Events {
    #[storage(read, write)]
    fn set_src7_events(asset: AssetId, svg_image: String, health_attribute: u64);
}

impl SetSRC7Events for Contract {
    #[storage(read, write)]
    fn set_src7_events(asset: AssetId, svg_image: String, health_attribute: u64) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        // If this asset does not exist, revert
        if storage.total_supply.get(asset).try_read().is_none() {
            revert(0);
        }

        storage.svg_images.try_insert(asset, StorageString {});
        storage.svg_images.get(asset).write_slice(svg_image);
        storage.health_attributes.insert(asset, health_attribute);

        let sender = msg_sender().unwrap();
        let metadata_1 = Some(Metadata::String(String::from_ascii_str(from_str_array(SOCIAL_X))));
        let metadata_2 = Some(Metadata::String(String::from_ascii_str(from_str_array(SITE_FORUM))));
        let metadata_3 = Some(Metadata::String(svg_image));
        let metadata_4 = Some(Metadata::Int(health_attribute));
        let key_1 = String::from_ascii_str("social:x");
        let key_2 = String::from_ascii_str("site:forum");
        let key_3 = String::from_ascii_str("image:svg");
        let key_4 = String::from_ascii_str("attr:health");

        SetMetadataEvent::new(asset, metadata_1, key_1, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_2, key_2, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_3, key_3, sender)
            .log();
        SetMetadataEvent::new(asset, metadata_4, key_4, sender)
            .log();
    }
}

// SRC7 extends SRC20, so this must be included
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(NAME))),
            None => None,
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(String::from_ascii_str(from_str_array(SYMBOL))),
            None => None,
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        match storage.total_supply.get(asset).try_read() {
            Some(_) => Some(DECIMALS),
            None => None,
        }
    }
}

abi SetSRC20Data {
    fn set_src20_data(asset: AssetId, total_supply: u64);
}

impl SetSRC20Data for Contract {
    fn set_src20_data(asset: AssetId, supply: u64) {
        // NOTE: There are no checks for if the caller has permissions to update the metadata
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
        TotalSupplyEvent::new(asset, supply, sender).log();
    }
}

```


---

### File: docs/sway-standards/docs/src/src-8-bridged-asset.md

# SRC-8: Bridged Asset

The following standard attempts to define the retrieval of relevant on-chain metadata for any bridged [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). Any contract that implements the SRC-8 standard MUST implement the [SRC-7](./src-7-asset-metadata.md) and [SRC-20](./src-20-native-asset.md) standards.

## Motivation

The SRC-8 standard seeks to enable relevant data for bridged assets on the Fuel Network. This data includes the origin chain, address, ID, decimals, and any arbitrary data. All metadata queries are done through a single function to facilitate cross-contract calls.

## Prior Art

The use of generic metadata for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) is defined in the [SRC-7](./src-7-asset-metadata.md) standard. This standard integrates into the existing [SRC-7](./src-7-asset-metadata.md) standard.

## Specification

### Asset Creation

The `SubId` of the asset MUST be the digest of the `sha256(origin_chain_id, origin_asset_address, origin_asset_id)` hash where:

- `origin_chain_id` is a `String` of the chain ID where the asset was originally minted.
- `origin_asset_address` is a `b256` of the asset's address on the chain where the asset was originally minted.
- `origin_asset_id` is a `b256` of the asset's ID such as an NFT's ID on the chain where the asset was originally minted. IF there is no ID, `b256::zero()` SHALL be used.

### SRC-20 Metadata

Any bridged assets MUST use the name and symbol of the asset on the chain where the asset was originally minted.

### SRC-7 Metadata

#### `bridged:chain`

The key `bridged:chain` SHALL return an `String` variant of the chain ID where the asset was originally minted.

#### `bridged:address`

The key `bridged:address` SHALL return a `B256` variant of the asset's address on the chain where the asset was originally minted. Native assets of a chain that do not have an address such as Ether on Ethereum SHALL use `b256::zero()`.

#### `bridged:id`

The key `bridged:id` MAY return a `B256` variant of the asset's ID such as an NFT's ID on the chain where the asset was originally minted. IF there is no ID, `None` SHALL be returned.

#### `bridged:decimals`

The key `bridged:decimals` MAY return an `Int` variant of the asset's decimals on the chain where the asset was originally minted. IF there are no decimals, `None` SHALL be returned.

## Rationale

The SRC-8 standard should allow for data on any bridged assets on the Fuel Network. This standard builds off existing standards and should allow other contracts to query any relevant information on the bridged asset.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets), the [SRC-20](./src-20-native-asset.md) standard, and the [SRC-7](./src-7-asset-metadata.md) standard.

The standard is also compatible with both tokens and NFTs native to other ecosystems by introducing a token ID element of the original chain.

## Security Considerations

This standard does not call external contracts, nor does it define any mutations of the contract state.

## Example

```sway
impl SRC7 for Contract {
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        if (asset != AssetId::default()) {
            return Option::None;
        }

        match key {
            String::from_ascii_str("bridged:chain") => {
                Option::Some(String::from_ascii_str("1"))
            },
            String::from_ascii_str("bridged:address") => {
                let origin_asset_address = b256::zero();
                Option::Some(Metadata::B256(origin_asset_address))
            },
            String::from_ascii_str("bridged:id") => {
                let origin_asset_id = b256::zero();
                Option::Some(Metadata::B256(origin_asset_id))
            },
            String::from_ascii_str("bridged:decimals") => {
                Option::Some(Metadata::Int(1))
            },
            _ => Option::None,
        }
    }
}

impl SRC20 for Contract {
    fn total_assets() -> u64 {
        1
    }

    fn total_supply(asset: AssetId) -> Option<u64> {
        match asset {
            AssetId::default() => Option::Some(1),
            _ => Option::None,
        }
    }

    fn name(asset: AssetId) -> Option<String> {
        match asset {
            AssetId::default() => Option::Some(String::from_ascii_str("Name")),
            _ => Option::None,
        }
    }

    fn symbol(asset: AssetId) -> Option<String> {
        match asset {
            AssetId::default() => Option::Some(String::from_ascii_str("Symbol")),
            _ => Option::None,
        }
    }

    fn decimals(asset: AssetId) -> Option<u8> {
        match asset {
            AssetId::default() => Option::Some(0u8),
            _ => Option::None,
        }
    }
}
```


---

### File: docs/sway-standards/docs/src/src-9-metadata-keys.md

# SRC-9: Native Asset

The following standard attempts to define the keys of relevant onchain metadata for any [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets). Any contract that implements the SRC-9 standard MUST implement the [SRC-7](./src-7-asset-metadata.md) and [SRC-20](./src-20-native-asset.md) standards. This is a living standard where revisions may be made as the ecosystem evolves.

> **NOTE** If data is not needed onchain, it is recommended to use the [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md).

## Motivation

The SRC-9 standard seeks to enable relevant onchain data for assets on the Fuel Network. This data may include images, text, contact, or all of the above. All metadata queries are done through a single function to facilitate cross-contract calls.

## Prior Art

The use of generic metadata for [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets) is defined in the [SRC-7](./src-7-asset-metadata.md) standard. This standard integrates into the existing [SRC-7](./src-7-asset-metadata.md) standard.

## Specification

The following keys are reserved for the SRC-9 standard. Use of the keys should follow the SRC-9 specification.

All keys SHALL use snake case.

### Quick Links

[Social](#social)
[Contact](#contact)
[External Links](#external-links)
[Resources](#resources)
[Images](#images)
[Video](#video)
[Audio](#audio)
[Media](#media)
[Logos](#logos)
[Attributes](#attributes)
[Global](#global)

### Social

The social prefix SHALL be used for any social media platform and SHALL return usernames.

Any social media metadata keys SHALL follow the following syntax `social:site` where:

- The `social` keyword must be prepended to denote this is a social platform
- The `site` keyword must be the website or platform of the social

#### `social:discord`

The key `social:discord` SHALL return a `String` variant of a username for the Discord platform.

#### `social:facebook`

The key `social:facebook` SHALL return a `String` variant of a username for the Facebook platform.

#### `social:farcaster`

The key `social:farcaster` SHALL return a `String` variant of a username for the Farcaster platform.

#### `social:friend.tech`

The key `social:friend.tech` SHALL return a `String` variant of a username for the Friend.tech platform.

#### `social:github`

The key `social:github` SHALL return a `String` variant of a username for the Github platform.

#### `social:instagram`

The key `social:instagram` SHALL return a `String` variant of a username for the Instagram platform.

#### `social:lens`

The key `social:lens` SHALL return a `String` variant of a username for the Lens Protocol.

#### `social:linkedin`

The key `social:linkedin` SHALL return a `String` variant of a username for the LinkedIn platform.

#### `social:reddit`

The key `social:reddit` SHALL return a `String` variant of a username for the Reddit platform.

#### `social:signal`

The key `social:signal` SHALL return a `String` variant of a username for the Signal platform.

#### `social:telegram`

The key `social:telegram` SHALL return a `String` variant of a username for the Telegram platform.

#### `social:tiktok`

The key `social:tiktok` SHALL return a `String` variant of a username for the TikTok platform.

#### `social:x`

The key `social:x` SHALL return a `String` variant of a username for the X or formerly Twitter platform.

#### `social:wechat`

The key `social:wechat` SHALL return a `String` variant of a username for the WeChat platform.

#### `social:whatsapp`

The key `social:whatsapp` SHALL return a `String` variant of a username for the WhatsApp platform.

#### `social:youtube`

The key `social:youtube` SHALL return a `String` variant of a username for the YouTube platform.

### Contact

The `contact` prefix SHALL be used for any contact information on a particular project's team for an asset.

Any contact information metadata keys SHALL follow the following syntax `contract:type` where:

- The `contact` keyword must be prepended to denote this is contact information
- The `type` keyword must be the method of contact

The key SHALL use snake case.

#### `contact:email`

The key `contact:email` SHALL return a `String` variant of an email.

#### `contact:mailing`

The key `contact:mailing` SHALL return a `String` variant of a mailing address. All mailing addresses MUST follow the UPU addressing format.

#### `contact:phone`

The key `contact:phone` SHALL return a `String` variant of a phone number. All phone numbers SHALL follow the E.164 standard.

#### `contact:company`

The key `contact:company` SHALL return a `String` variant of a company name.

### External Links

The `link` prefix SHALL be used for any external webpage hyperlink associated with an asset.

Any external webpage metadata keys SHALL follow the following syntax `link:site` where:

- The `link` keyword must be prepended to denote this is an external webpage
- The `site` keyword must be an external website

#### `link:home`

The key `link:home` SHALL return a `String` variant of the asset's project homepage.

#### `link:contact`

The key `link:contact` SHALL return a `String` variant of the asset's project contact information webpage.

#### `link:docs`

The key `link:docs` SHALL return a `String` variant of the asset's project documentation webpage.

#### `link:forum`

The key `link:forum` SHALL return a `String` variant of the asset's project forum webpage.

#### `link:blog`

The key `link:blog` SHALL return a `String` variant of the asset's project blog.

#### `link:linktree`

The key `link:linktree` SHALL return a `String` variant of the asset's project linktree information webpage.

### Resources

The `res` prefix SHALL be used for any resources or general information on an asset.

Any resource metadata keys SHALL follow the following syntax `rec:type` where:

- The `res` keyword must be prepended to denote this is a resource
- The `type` keyword must be the type of resource

#### `res:license`

The key `res:license` SHALL return a `String` variant of the asset's project license.

#### `res:tos`

The key `res:tos` SHALL return a `String` variant of the asset's project Terms of Service.

#### `res:author`

The key `res:author` SHALL return a `String` variant of the asset's project author. This MAY be a full name or pseudonym.

#### `res:about`

The key `res:about` SHALL return a `String` variant about the asset's project up to 2048 characters.

#### `res:description`

The key `res:description` SHALL return a `String` variant describing the asset's project up to 256 characters.

#### `res:date`

The key `res:date` SHALL return a `Int` variant of a UNIX timestamp.

#### `res:block`

The key `res:block` SHALL return a `Int` variant of a block number.

### Images

The `image` prefix SHALL be used for any image files associated with a singular asset.

Any image metadata keys SHALL follow the following syntax `image:type` where:

- The `image` keyword must be prepended to denote this is an image
- The `type` keyword must be the file type of the image

> **NOTE** If using an ifps hash to store an image offchain, it is recommended to use the [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md).

#### `image:svg`

The key `image:svg` SHALL return a `String` variant of an SVG image.

#### `image:png`

The key `image:png` SHALL return a `String` variant of a URI for a PNG image.

#### `image:jpeg`

The key `image:jpeg` SHALL return a `String` variant of a URI for a JPEG image.

#### `image:webp`

The key `image:webp` SHALL return a `String` variant of a URI for a WebP image.

#### `image:gif`

The key `image:gif` SHALL return a `String` variant of a URI for a GIF image.

#### `image:heif`

The key `image:heif` SHALL return a `String` variant of a URI for a HEIF image.

### Video

The `video` prefix SHALL be used for any video files associated with a singular asset.

Any video metadata keys SHALL follow the following syntax `video:type` where:

- The `video` keyword must be prepended to denote this is a video
- The `type` keyword must be the file type of the video

> **NOTE** If using an ifps hash to store a video offchain, it is recommended to use the [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md).

#### `video:mp4`

The key `video:mp4` SHALL return a `String` variant of a URI for an MP4 video.

#### `video:webm`

The key `video:webm` SHALL return a `String` variant of a URI for a WebM video.

#### `video:m4v`

The key `video:m4v` SHALL return a `String` variant of a URI for a M4V video.

#### `video:ogv`

The key `video:ogv` SHALL return a `String` variant of a URI for an OGV video.

#### `video:ogg`

The key `video:ogg` SHALL return a `String` variant of a URI for an OGG video.

### Audio

The `audio` prefix SHALL be used for any audio files associated with a singular asset.

Any audio metadata keys SHALL follow the following syntax `audio:type` where:

- The `audio` keyword must be prepended to denote this is audio metadata
- The `type` keyword must be the file type of the audio

> **NOTE** If using an ifps hash to store audio offchain, it is recommended to use the [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md).

#### `audio:mp3`

The key `audio:mp3` SHALL return a `String` variant of a URI for an MP3 file.

#### `audio:wav`

The key `audio:wav` SHALL return a `String` variant of a URI for a WAV file.

#### `audio:oga`

The key `audio:oga` SHALL return a `String` variant of a URI for an OGA file.

### Media

The `media` prefix SHALL be used for any media associated with a particular singular asset.

Any media metadata keys SHALL follow the following syntax `media:type` where:

- The `media` keyword must be prepended to denote this is a video
- The `type` keyword must be the file type of the media

> **NOTE** If using an ifps hash to store media offchain, it is recommended to use the [SRC-15; Offchain Asset Metadata Standard](./src-15-offchain-asset-metadata.md).

#### `media:gltf`

The key `media:gltf` SHALL return a `String` variant of a URI for a glTF file.

#### `media:glb`

The key `media:glb` SHALL return a `String` variant of a URI for a GLB file.

### Logos

The `logo` prefix SHALL be used for any images associated with a particular asset or project.

Any logo metadata keys SHALL follow the following syntax `logo:type` where:

- The `logo` keyword must be prepended to denote this is a logo
- The `type` keyword must be the type of logo

#### `logo:svg`

The key `logo:svg` SHALL return a `String` variant of an SVG image of a logo.

#### `logo:svg_light`

The key `logo:svg_light` SHALL return a `String` variant of an SVG image of a logo for light themes.

#### `logo:svg_dark`

The key `logo:svg_dark` SHALL return a `String` variant of an SVG image of a logo for dark themes.

#### `logo:small_light`

The key `logo:small_light` SHALL return a `String` variant of a URI for a 32x32 PNG image of a logo for light themes.

#### `logo:small_dark`

The key `logo:small_dark` SHALL return a `String` variant of a URI for a 32x32 PNG image of a logo for dark themes.

#### `logo:medium_light`

The key `logo:medium_light` SHALL return a `String` variant of a URI for a 256x256 PNG image of a logo for light themes.

#### `logo:medium_dark`

The key `logo:medium_dark` SHALL return a `String` variant of a URI for a 256x256 PNG image of a logo for dark themes.

#### `logo:large_light`

The key `logo:large_light` SHALL return a `String` variant of a URI for a 1024x1024 PNG image of a logo for light themes.

#### `logo:large_dark`

The key `logo:large_dark` SHALL return a `String` variant of a URI for a 1024x1024 PNG image of a logo for dark themes.

### Attributes

The `attr` prefix SHALL be used for any attributes associated with a singular asset.

Any attribute metadata keys SHALL follow the following syntax `attr:type` where:

- The `attr` keyword must be prepended to denote this is an attribute
- The `type` keyword must be the type of attribute

There are no standardized types of attributes.
Example: `attr:eyes`.

### Global

The `global` prefix SHALL be used for any attributes associated with ALL assets minted by a contract.

Any global metadata keys SHALL follow the following syntax `global:key` where:

- The `global` keyword must be prepended to denote this is a global metadata
- The `key` keyword must be the type of metadata using a SRC-9 key defined above

Example: `global:image:png`.

## Rationale

The SRC-9 standard should allow for standardized keys for metadata on the Fuel Network. This standard builds off existing standards and should allow other contracts to query any relevant information on the asset.

## Backwards Compatibility

This standard is compatible with Fuel's [Native Assets](https://docs.fuel.network/docs/sway/blockchain-development/native_assets), the [SRC-20](./src-20-native-asset.md) standard, and the [SRC-7](./src-7-asset-metadata.md) standard.

## Security Considerations

This standard does not call external contracts, nor does it define any mutations of the contract state.

## Example

```sway
impl SRC7 for Contract {
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        if (asset != AssetId::default()) {
            return Option::None;
        }

        match key {
            String::from_ascii_str("social:x") => {
                let social = String::from_ascii_str("fuel_network");
                Option::Some(Metadata::String(social))
            },
            _ => Option::None,
        }
    }
}
```


---

### File: docs/sway/docs/book/src/advanced/advanced_storage.md

# Advanced Storage

## Nested Storage Collections

Through the use of `StorageKey`s, you may have nested storage collections such as storing a `StorageString` in a `StorageMap<K, V>`.

For example, here we have a few common nested storage types declared in a `storage` block:

```sway
storage {
    nested_map_vec: StorageMap<u64, StorageVec<u8>> = StorageMap {},
    nested_map_string: StorageMap<u64, StorageString> = StorageMap {},
    nested_vec_bytes: StorageVec<StorageBytes> = StorageVec {},
}
```

Please note that storage initialization is needed to do this.

> **NOTE**: When importing a storage type, please be sure to use the glob operator i.e. `use std::storage::storage_vec::*`.

### Storing a `StorageVec<T>` in a `StorageMap<K, V>`

The following demonstrates how to write to a `StorageVec<T>` that is nested in a `StorageMap<T, V>`:

```sway
        // Setup and initialize storage for the StorageVec.
        storage.nested_map_vec.try_insert(10, StorageVec {});

        // Method 1: Push to the vec directly
        storage.nested_map_vec.get(10).push(1u8);
        storage.nested_map_vec.get(10).push(2u8);
        storage.nested_map_vec.get(10).push(3u8);

        // Method 2: First get the storage key and then push the values.
        let storage_key_vec: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        storage_key_vec.push(4u8);
        storage_key_vec.push(5u8);
        storage_key_vec.push(6u8);
        // Setup Bytes to store
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Setup and initialize storage for the StorageBytes.
        storage.nested_vec_bytes.push(StorageBytes {});

        // Method 1: Store the bytes by accessing StorageBytes directly.
        storage
            .nested_vec_bytes
            .get(0)
            .unwrap()
            .write_slice(my_bytes);

        // Method 2: First get the storage key and then write the bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        storage_key.write_slice(my_bytes);
```

The following demonstrates how to read from a `StorageVec<T>` that is nested in a `StorageMap<T, V>`:

```sway
        // Method 1: Access the StorageVec directly.
        let stored_val1: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val2: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val3: u8 = storage.nested_map_vec.get(10).pop().unwrap();

        // Method 2: First get the storage key and then access the value.
        let storage_key: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        let stored_val4: u8 = storage_key.pop().unwrap();
        let stored_val5: u8 = storage_key.pop().unwrap();
        let stored_val6: u8 = storage_key.pop().unwrap();
        // Method 1: Access the stored bytes directly.
        let stored_bytes: Bytes = storage.nested_vec_bytes.get(0).unwrap().read_slice().unwrap();

        // Method 2: First get the storage key and then access the stored bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        let stored_bytes: Bytes = storage_key.read_slice().unwrap();
```

### Storing a `StorageString` in a `StorageMap<K, V>`

The following demonstrates how to write to a `StorageString` that is nested in a `StorageMap<T, V>`:

```sway
        // Setup and initialize storage for the StorageString.
        storage.nested_map_string.try_insert(10, StorageString {});

        // Method 1: Store the string directly.
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.nested_map_string.get(10).write_slice(my_string);

        // Method 2: First get the storage key and then write the value.
        let my_string = String::from_ascii_str("Fuel is modular");
        let storage_key: StorageKey<StorageString> = storage.nested_map_string.get(10);
        storage_key.write_slice(my_string);
```

The following demonstrates how to read from a `StorageString` that is nested in a `StorageMap<T, V>`:

```sway
        // Method 1: Access the string directly.
        let stored_string: String = storage.nested_map_string.get(10).read_slice().unwrap();

        // Method 2: First get the storage key and then access the value.
        let storage_key: StorageKey<StorageString> = storage.nested_map_string.get(10);
        let stored_string: String = storage_key.read_slice().unwrap();
```

### Storing a `StorageBytes` in a `StorageVec<T>`

The following demonstrates how to write to a `StorageBytes` that is nested in a `StorageVec<T>`:

```sway
        // Setup and initialize storage for the StorageVec.
        storage.nested_map_vec.try_insert(10, StorageVec {});

        // Method 1: Push to the vec directly
        storage.nested_map_vec.get(10).push(1u8);
        storage.nested_map_vec.get(10).push(2u8);
        storage.nested_map_vec.get(10).push(3u8);

        // Method 2: First get the storage key and then push the values.
        let storage_key_vec: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        storage_key_vec.push(4u8);
        storage_key_vec.push(5u8);
        storage_key_vec.push(6u8);
        // Setup Bytes to store
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Setup and initialize storage for the StorageBytes.
        storage.nested_vec_bytes.push(StorageBytes {});

        // Method 1: Store the bytes by accessing StorageBytes directly.
        storage
            .nested_vec_bytes
            .get(0)
            .unwrap()
            .write_slice(my_bytes);

        // Method 2: First get the storage key and then write the bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        storage_key.write_slice(my_bytes);
```

The following demonstrates how to read from a `StorageBytes` that is nested in a `StorageVec<T>`:

```sway
        // Method 1: Access the StorageVec directly.
        let stored_val1: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val2: u8 = storage.nested_map_vec.get(10).pop().unwrap();
        let stored_val3: u8 = storage.nested_map_vec.get(10).pop().unwrap();

        // Method 2: First get the storage key and then access the value.
        let storage_key: StorageKey<StorageVec<u8>> = storage.nested_map_vec.get(10);
        let stored_val4: u8 = storage_key.pop().unwrap();
        let stored_val5: u8 = storage_key.pop().unwrap();
        let stored_val6: u8 = storage_key.pop().unwrap();
        // Method 1: Access the stored bytes directly.
        let stored_bytes: Bytes = storage.nested_vec_bytes.get(0).unwrap().read_slice().unwrap();

        // Method 2: First get the storage key and then access the stored bytes.
        let storage_key: StorageKey<StorageBytes> = storage.nested_vec_bytes.get(0).unwrap();
        let stored_bytes: Bytes = storage_key.read_slice().unwrap();
```

## Storage Namespace

If you want the values in storage to be positioned differently, for instance to avoid collisions with storage from another contract when loading code, you can use the namespace annotation to add a salt to the slot calculations.

```sway
storage {
    example_namespace {
        foo: u64 = 0,
    },
```

## Manual Storage Management

It is possible to leverage FuelVM storage operations directly using the `std::storage::storage_api::write` and `std::storage::storage_api::read` functions provided in the standard library. With this approach, you will have to manually assign the internal key used for storage. An example is as follows:

```sway
contract;

use std::storage::storage_api::{read, write};

abi StorageExample {
    #[storage(write)]
    fn store_something(amount: u64);

    #[storage(read)]
    fn get_something() -> u64;
}

const STORAGE_KEY: b256 = 0x0000000000000000000000000000000000000000000000000000000000000000;

impl StorageExample for Contract {
    #[storage(write)]
    fn store_something(amount: u64) {
        write(STORAGE_KEY, 0, amount);
    }

    #[storage(read)]
    fn get_something() -> u64 {
        let value: Option<u64> = read::<u64>(STORAGE_KEY, 0);
        value.unwrap_or(0)
    }
}

```

> **Note**: Though these functions can be used for any data type, they should mostly be used for arrays because arrays are not yet supported in `storage` blocks. Note, however, that _all_ data types can be used as types for keys and/or values in `StorageMap<K, V>` without any restrictions.


---

### File: docs/sway/docs/book/src/advanced/advanced_types.md

# Advanced Types

## Creating Type Synonyms with Type Aliases

Sway provides the ability to declare a type alias to give an existing type another name. For this we use the `type` keyword. For example, we can create the alias `Kilometers` to `u64` like so:

```sway
type Kilometers = u64;
```

Now, the alias `Kilometers` is a _synonym_ for `u64`. Note that `Kilometers` is **not** a separate new type. Values that have the type `Kilometers` will be treated the same as values of type `u64`:

```sway
    let x: u64 = 5;
    let y: Kilometers = 5;
    assert(x + y == 10);
```

Because `Kilometers` and `u64` are the same type, we can add values of both types and we can pass `Kilometers` values to functions that take `u64` parameters. However, using this method, we don’t get the type checking benefits that we get from introducing a _separate_ new type called `Kilometers`. In other words, if we mix up `Kilometers` and `i32` values somewhere, the compiler will not give us an error.

The main use case for type synonyms is to reduce repetition. For example, we might have a lengthy array type like this:

```sway
[MyStruct<u64, b256>; 5]
```

Writing this lengthy type in function signatures and as type annotations all over the code can be tiresome and error prone. Imagine having a project full of code like this:

```sway
fn foo_long(array: [MyStruct<u64, b256>; 5]) -> [MyStruct<u64, b256>; 5] {
    array
}
type MyArray = [MyStruct<u64, b256>; 5];

fn foo_shorter(array: MyArray) -> MyArray {
    array
}
```

A type alias makes this code more manageable by reducing the repetition. Below, we’ve introduced an alias named `MyArray` for the verbose type and can replace all uses of the type with the shorter alias `MyArray`:

```sway
type MyArray = [MyStruct<u64, b256>; 5];

fn foo_shorter(array: MyArray) -> MyArray {
    array
}
```

This code is much easier to read and write! Choosing a meaningful name for a type alias can help communicate your intent as well.


---

### File: docs/sway/docs/book/src/advanced/assembly.md

# Inline Assembly in Sway

While many users will never have to touch assembly language while writing Sway code, it is a powerful tool that enables many advanced use-cases (e.g., optimizations, building libraries, etc).

## ASM Block

In Sway, the way we use assembly inline is to declare an `asm` block like this:

```sway
asm() {...}
```

Declaring an `asm` block is similar to declaring a function.
We can specify register names to operate on as arguments, we can perform assembly instructions within the block, and we can return a value by specifying a return register.
Here's an example showing what this might look like:

```sway
pub fn add_1(num: u32) -> u32 {
    asm(r1: num, r2) {
        add r2 r1 one;
        r2: u32
    }
}
```

The return register is specified at the end of the `asm` block, after all the assembly instructions. It consists of the register name and an optional return type. In the above example, the return register name is `r2` and the return type is `u32`.
If the return type is omitted, it is `u64` by default.

The return register itself is optional. If it is not specified, similar to functions, the returned value from the `asm` block will be [unit](../basics/built_in_types.md#unit-type), `()`.

An `asm` block can only return a single register. If you really need to return more than one value, you can modify a tuple. Here's an example showing how you can implement this for `(u64, u64)`:

```sway
script;

fn adder(a: u64, b: u64, c: u64) -> (u64, u64) {
    let empty_tuple = (0u64, 0u64);
    asm(output: empty_tuple, r1: a, r2: b, r3: c, r4, r5) {
        add r4 r1 r2; // add a & b and put the result in r4
        add r5 r2 r3; // add b & c and put the result in r5
        sw output r4 i0; // store the word in r4 in output + 0 words
        sw output r5 i1; // store the word in r5 in output + 1 word
        output: (u64, u64) // return both values
    }
}

fn main() -> bool {
    let (first, second) = adder(1, 2, 3);
    assert(first == 3);
    assert(second == 5);
    true
}

```

Note that this is contrived example meant to demonstrate the syntax; there's absolutely no need to use assembly to add integers!

Note that in the above example:

- we initialized the register `r1` with the value of `num`.
- we declared a second register `r2` (you may choose any register names you want).
- we use the `add` opcode to add `one` to the value of `r1` and store it in `r2`.
- `one` is an example of a "reserved register", of which there are 16 in total. Further reading on this is linked below under "Semantics".
- we return `r2` and specify the return type as being `u32`.

An important note is that the `ji` and `jnei` opcodes are not available within an `asm` block. For those looking to introduce control flow to `asm` blocks, it is recommended to surround smaller chunks of `asm` with control flow (`if`, `else`, and `while`).

## Helpful Links

For examples of assembly in action, check out the [Sway standard library](https://github.com/FuelLabs/sway/tree/master/sway-lib-std).

For a complete list of all instructions supported in the FuelVM: [Instructions](https://fuellabs.github.io/fuel-specs/master/vm/instruction_set).

And to learn more about the FuelVM semantics: [Semantics](https://fuellabs.github.io/fuel-specs/master/vm#semantics).


---

### File: docs/sway/docs/book/src/advanced/associated_types.md

# Associated Types

Associated types in Sway allow you to define placeholder types within a trait, which can be customized by concrete
implementations of that trait. These associated types are used to specify the return types of trait methods or to
define type relationships within the trait.

Associated types are a powerful feature of Sway's trait system, enabling generic programming and abstraction over
types. They help improve code clarity and maintainability by allowing you to define generic traits without committing
to specific types.

## Declaring Associated Types

Associated types are declared within a trait using the type keyword. Here's the syntax for declaring an associated type:

```sway
trait MyTrait {
    type AssociatedType;
}
```

## Implementing Associated Types

Concrete implementations of a trait with associated types must provide a specific type for each associated type
defined in the trait. Here's an example of implementing a trait with an associated type:

```sway
struct MyStruct;

impl MyTrait for MyStruct {
    type AssociatedType = u32; // Implementing the associated type with u32
}
```

In this example, `MyStruct` implements `MyTrait` and specifies that the associated type `AssociatedType` is `u32`.

## Using Associated Types

Associated types are used within trait methods or where the trait is used as a bound for generic functions or
structs. You can use the associated type like any other type. Here's an example:

```sway
trait MyTrait {
    type AssociatedType;
    
    fn get_value(self) -> Self::AssociatedType;
}

struct MyStruct;

impl MyTrait for MyStruct {
    type AssociatedType = u32;

    fn get_value(self) -> Self::AssociatedType {
        42
    }
}
```

In this example, `get_value` is a trait method that returns an associated type `AssociatedType`.

## Use Cases

Associated types are particularly useful in scenarios where you want to define traits that work with different
types of data structures or abstractions, allowing the implementer to specify the concrete types. Some common use cases include:

- Collections: Traits for generic collections that allow users to specify the type of elements.
- Iterator Patterns: Traits for implementing iterators with varying element types.
- Serialization and Deserialization: Traits for serializing and deserializing data with different data formats.


---

### File: docs/sway/docs/book/src/advanced/generic_types.md

# Generic Types

## Basics

In Sway, generic types follow a very similar pattern to those in Rust. Let's look at some example syntax,
starting with a generic function:

```sway
fn noop<T>(argument: T) -> T {
    argument
}
```

Here, the `noop()` function trivially returns exactly what was given to it. `T` is a _type parameter_, and it says
that this function exists for all types T. More formally, this function could be typed as:

```math
noop :: ∀T. T -> T
```

Generic types are a way to refer to types _in general_, meaning without specifying a single type. Our `noop` function
would work with any type in the language, so we don't need to specify `noop(argument: u8) -> u8`, `noop(argument: u16) -> u16`, etc.

## Code Generation

One question that arises when dealing with generic types is: how does the assembly handle this? There are a few approaches to handling
generic types at the lowest level. Sway uses a technique called [monomorphization](https://en.wikipedia.org/wiki/Monomorphization). This
means that the generic function is compiled to a non-generic version for every type it is called on. In this way, generic functions are
purely shorthand for the sake of ergonomics.

## Trait Constraints

An important background to know before diving into trait constraints is that the `where` clause can be used to specify the required traits for the generic argument. So, when writing something like a `HashMap` you may
want to specify that the generic argument implements a `Hash` trait.

```sway
fn get_hashmap_key<T>(key: T) -> b256
    where T: Hash
{
    // Code within here can then call methods associated with the Hash trait on Key
}
```

Of course, our `noop()` function is not useful. Often, a programmer will want to declare functions over types which satisfy certain traits.
For example, let's try to implement the successor function, `successor()`, for all numeric types.

```sway
fn successor<T>(argument: T)
    where T: Add
{
    argument + 1
}
```

Run `forc build`, and you will get:

```console
.. |
 9 |   where T: Add
10 |   {
11 |       argument + 1                                        
   |                  ^ Mismatched types: expected type "T" but saw type "u64"
12 |   }
13 |
```

This is because we don't know for a fact that `1`, which in this case defaulted to `1u64`, actually can be added to `T`. What if `T` is `f64`? Or `b256`? What does it mean to add `1u64` in these cases?

We can solve this problem with another trait constraint. We can only find the successor of some value of type `T` if that type `T` defines some incrementor. Let's make a trait:

```sway
trait Incrementable {
    /// Returns the value to add when calculating the successor of a value.
    fn incrementor() -> Self;
}
```

Now, we can modify our `successor()` function:

```sway
fn successor<T>(argument: T)
    where T: Add,
          T: Incrementable
{
    argument + T::incrementor()
}
```

## Generic Structs and Enums

Just like functions, structs and enums can be generic. Let's take a look at the standard library version of `Option<T>`:

```sway
enum Option<T> {
    Some: T,
    None: (),
}
```

Just like an unconstrained generic function, this type exists for all (∀) types `T`. `Result<T, E>` is another example:

```sway
enum Result<T, E> {
    Ok: T,
    Err: E,
}
```

Both generic enums and generic structs can be trait constrained, as well. Consider this struct:

```sway
struct Foo<T>
    where T: Add
{
    field_one: T,
}
```

## Type Arguments

Similar to Rust, Sway has what is colloquially known as the [turbofish](https://github.com/rust-lang/rust/blob/e98309298d927307c5184f4869604bd068d26183/src/test/ui/parser/bastion-of-the-turbofish.rs). The turbofish looks like this: `::<>` (see the little fish with bubbles behind it?). The turbofish is used to annotate types in a generic context. Say you have the following function:

```sway
fn foo<T, E>(t: T) -> Result<T, E> {
    Ok(t)
}
```

In this code example, which is admittedly asinine, you can't possibly know what type `E` is. You'd need to provide the type manually, with a turbofish:

```sway
fn foo<T, E>(t: T) -> Result<T, E> {
    Ok::<T, MyErrorType>(t)
}
```

It is also common to see the turbofish used on the function itself:

```sway
fn main() {
    foo::<Bar, Baz>()
}
```


---

### File: docs/sway/docs/book/src/advanced/generics_and_trait_constraints.md

# Generics and Trait Constraints

## Generics as Constraints

At a high level, Sway allows you to define constraints, or restrictions, that
allow you to strike a balance between writing abstract and reusable code and
enforcing compile-time checks to determine if the abstract code that you've
written is correct.

The "abstract and reusable" part largely comes from [generic types](./generic_types.md) and the
"enforcing compile-time checks" part largely comes from trait constraints.
Generic types can be used with functions, structs, and enums (as we have seen in
this book), but they can also be used with traits.

## Generic Traits

Combining generic types with traits allows you to write abstract and reusable
traits that can be implemented for any number of data types.

For example, imagine that you want to write a trait for converting between
different types. This would be similar to Rust's `Into` and `From` traits. In
Sway your conversion trait would look something like:

```sway
trait Convert<T> {
    fn from(t: T) -> Self;
}
```

The trait `Convert` takes a generic type `T`. `Convert` has one method
`from`, which takes one parameter of type `T` and returns a `Self`. This means
that when you implement `Convert` for a data type, `from` will return the type
of that data type but will take as input the type that you define as `T`. Here
is an example:

```sway
struct Square {
    width: u64,
}

struct Rectangle {
    width: u64,
    length: u64,
}

impl Convert<Square> for Rectangle {
    fn from(t: Square) -> Self {
        Self {
            width: t.width,
            length: t.width,
        }
    }
}
```

In this example, you have two different data types, `Square` and `Rectangle`.
You know that all squares are rectangles and thus `Square` can convert into `Rectangle` (but not vice
versa) and thus you can implement the conversion trait for those types.

If we want to call these methods we can do so by:

```sway
fn main() {
    let s = Square { width: 5 };
    let r = Rectangle::from(s);
}
```

## Trait Constraints

Trait constraints allow you to use generic types and traits to place constraints
on what abstract code you are willing to accept in your program as correct.
These constraints take the form of compile-time checks for correctness.

If we wanted to use trait constraints with our `Convert` trait from the previous
section we could do so like so:

```sway
fn into_rectangle<T>(t: T) -> Rectangle
where
    Rectangle: Convert<T>,
{
    Rectangle::from(t)
}
```

This function allows you to take any generic data type `T` and convert it to the
type `Rectangle` _as long as `Convert<T>` is implemented for `Rectangle`_.
Calling this function with a type `T` for which `Convert<T>` is not implemented
for `Rectangle` will fail Sway's compile-time checks.


---

### File: docs/sway/docs/book/src/advanced/index.md

# Advanced Concepts

Advanced concepts.

- [Advanced Types](./advanced_types.md)
- [Advanced Storage](./advanced_storage.md)
- [Generic Types](./generic_types.md)
- [Traits](./traits.md)
- [Associated Types](./associated_types.md)
- [Generics and Trait Constraints](./generics_and_trait_constraints.md)
- [Assembly](./assembly.md)
- [Never Type](./never_type.md)


---

### File: docs/sway/docs/book/src/advanced/never_type.md

# Never Type

The Never type `!` represents the type of computations which never resolve to any value at all.

## Additional Information

`break`, `continue` and `return` expressions also have type `!`. For example we are allowed to
write:

```sway
let x: ! = {
    return 123
};
```

Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never
assigned a value (because `return` returns from the entire function), `x` can be given type
`Never`. We could also replace `return 123` with a `revert()` or a never-ending `loop` and this code
would still be valid.

A more realistic usage of `Never` is in this code:

```sway
let num: u32 = match get_a_number() {
    Some(num) => num,
    None => break,
};
```

Both match arms must produce values of type [`u32`], but since `break` never produces a value
at all we know it can never produce a value which isn't a [`u32`]. This illustrates another
behaviour of the `!` type - expressions with type `!` will coerce into any other type.

Note that `!` type coerces into any other type, another example of this would be:

```sway
let x: u32 = {
    return 123
};
```

Regardless of the type of `x`, the return block of type `Never` will always coerce into `x` type.

## Examples

```sway
fn foo() {
    let num: u64 = match Option::None::<u64> {
        Some(num) => num,
        None => return,
    };
}
```


---

### File: docs/sway/docs/book/src/advanced/traits.md

# Traits

## Declaring a Trait

A _trait_ opts a type into a certain type of behavior or functionality that can be shared among types. This allows for easy reuse of code and generic programming. If you have ever used a typeclass in Haskell, a trait in Rust, or even an interface in Java, these are similar concepts.

Let's take a look at some code:

```sway
trait Compare {
    fn equals(self, b: Self) -> bool;
} {
    fn not_equals(self, b: Self) -> bool {
        !self.equals(b)
    }
}
```

We have just declared a trait called `Compare`. After the name of the trait, there are two _blocks_ of code (a _block_ is code enclosed in `{` curly brackets `}`). The first block is the _interface surface_. The second block is the _methods_ provided by the trait. If a type can provide the methods in the interface surface, then it gets access to the methods in the trait for free! What the above trait is saying is: if you can determine if two values are equal, then for free, you can determine that they are not equal. Note that trait methods have access to the methods defined in the interface surface.

## Implementing a Trait

The example below implements a `Compare` trait for `u64` to check if two numbers are equal. Let's take a look at how that is done:

```sway
impl Compare for u64 {
    fn equals(self, b: Self) -> bool {
        self == b
    }
}
```

The above snippet declares all of the methods in the trait `Compare` for the type `u64`. Now, we have access to both the `equals` and `not_equals` methods for `u64`, as long as the trait `Compare` is in scope.

## Supertraits

When using multiple traits, scenarios often come up where one trait may require functionality from another trait. This is where supertraits come in as they allow you to require a trait when implementing another trait, i.e., a trait with a trait.
A good example of this is the `Ord` trait of the `std` library of Sway. The `Ord` trait requires the `Eq` trait, so `Eq` is kept as a separate trait as one may decide to implement `Eq`
without implementing other parts of the `Ord` trait.

```sway

trait Eq {
    fn equals(self, b: Self) -> bool;
}

trait Ord: Eq {
    fn gte(self, b: Self) -> bool;
}

impl Ord for u64 {
    fn gte(self, b: Self) -> bool {
        // As `Eq` is a supertrait of `Ord`, `Ord` can access the equals method
        self.equals(b) || self.gt(b)
    }
}
```

To require a supertrait, add a `:` after the trait name and then list the traits you would like to require and separate them with a `+`.

### ABI supertraits

ABIs can also have supertrait annotations:

```sway
contract;

struct Foo {}
impl ABIsupertrait for Foo {
    fn foo() {}
}

trait ABIsupertrait {
    fn foo();
}

abi MyAbi : ABIsupertrait {
    fn bar();
} {
    fn baz() {
        Self::foo() // supertrait method usage
    }
}

impl ABIsupertrait for Contract {
    fn foo() {}
}

// The implementation of MyAbi for Contract must also implement ABIsupertrait
impl MyAbi for Contract {
    fn bar() {
        Self::foo() // supertrait method usage
    }
}

```

The implementation of `MyAbi` for `Contract` must also implement the `ABIsupertrait` trait. Methods in `ABIsupertrait` are not available externally, i.e. they're not actually contract methods, but they can be used in the actual contract methods, as shown in the example above.

ABI supertraits are intended to make contract implementations compositional, allowing combining orthogonal contract features using, for instance, libraries.

### SuperABIs

In addition to supertraits, ABIs can have _superABI_ annotations:

```sway
contract;

abi MySuperAbi {
    fn foo();
}

abi MyAbi : MySuperAbi {
    fn bar();
}

impl MySuperAbi for Contract {
    fn foo() {}
}

// The implementation of MyAbi for Contract must also implement MySuperAbi
impl MyAbi for Contract {
    fn bar() {}
}

```

The implementation of `MyAbi` for `Contract` must also implement the `MySuperAbi` superABI. Methods in `MySuperAbi` will be part of the `MyAbi` contract interface, i.e. will be available externally (and hence cannot be called from other `MyAbi` contract methods).

SuperABIs are intended to make contract implementations compositional, allowing combining orthogonal contract features using, for instance, libraries.

## Associated Items

Traits can declare different kinds of associated items in their interface surface:

- [Functions](#associated-functions)
- [Constants](#associated-constants)
- [Types](#associated-types)

### Associated functions

Associated functions in traits consist of just function signatures. This indicates that each implementation of the trait for a given type must define all the trait functions.

```sway
trait Trait {
    fn associated_fn(self, b: Self) -> bool;
}
```

### Associated constants

Associated constants are constants associated with a type.

```sway
trait Trait {
    const ID: u32 = 0;
}
```

The initializer expression of an [associated constants](../basics/constants.md#associated-constants) in a trait definition may be omitted to indicate that each implementation of the `trait` for a given type must specify an initializer:

```sway
trait Trait {
    const ID: u32;
}
```

Check the `associated consts` section on [constants](../basics/constants.md) page.

### Associated types

Associated types in Sway allow you to define placeholder types within a trait, which can be customized by concrete
implementations of that trait. These associated types are used to specify the return types of trait methods or to
define type relationships within the trait.

```sway
trait MyTrait {
    type AssociatedType;
}
```

Check the `associated types` section on [associated types](./associated_types.md) page.

## Trait Constraints

When writing generic code, you can constraint the choice of types for a generic argument by using the `where` keyword. The `where` keyword specifies which traits the concrete generic parameter must implement. In the below example, the function `expects_some_trait` can be called only if the parameter `t` is of a type that has `SomeTrait` implemented. To call the `expects_both_traits`, parameter `t` must be of a type that implements _both_ `SomeTrait` and `SomeOtherTrait`.

```sway
trait SomeTrait { }
trait SomeOtherTrait { }

fn expects_some_trait<T>(t: T) where T: SomeTrait {
    // ...
}

fn expects_some_other_trait<T>(t: T) where T: SomeOtherTrait {
    // ...
}

fn expects_both_traits<T>(t: T) where T: SomeTrait + SomeOtherTrait {
    // ...
}
```

## Marker Traits

Sway types can be classified in various ways according to their intrinsic properties. These classifications are represented as marker traits. Marker traits are implemented by the compiler and cannot be explicitly implemented in code.

E.g., all types whose instances can be used in the `panic` expression automatically implement the `Error` marker trait. We can use that trait, e.g., to specify that a generic argument must be compatible with the `panic` expression:

```sway
fn panic_with_error<E>(err: E) where E: Error {
    panic err;
}
```

All marker traits are defined in the `std::marker` module.

## Use Cases

### Custom Types (structs, enums)

Often, libraries and APIs have interfaces that are abstracted over a type that implements a certain trait. It is up to the consumer of the interface to implement that trait for the type they wish to use with the interface. For example, let's take a look at a trait and an interface built off of it.

```sway
library;

pub enum Suit {
    Hearts: (),
    Diamonds: (),
    Clubs: (),
    Spades: (),
}

pub trait Card {
    fn suit(self) -> Suit;
    fn value(self) -> u8;
}

fn play_game_with_deck<T>(a: Vec<T>) where T: Card {
    // insert some creative card game here
}
```

Now, if you want to use the function `play_game_with_deck` with your struct, you must implement `Card` for your struct. Note that the following code example assumes a dependency _games_ has been included in the `Forc.toml` file.

```sway
script;

use games::*;

struct MyCard {
    suit: Suit,
    value: u8
}

impl Card for MyCard {
    fn suit(self) -> Suit {
        self.suit
    }
    fn value(self) -> u8 {
        self.value
    }
}

fn main() {
    let mut i = 52;
    let mut deck: Vec<MyCard> = Vec::with_capacity(50);
    while i > 0 {
        i = i - 1;
        deck.push(MyCard { suit: generate_random_suit(), value: i % 4}
    }
    play_game_with_deck(deck);
}

fn generate_random_suit() -> Suit {
  [ ... ]
}
```


---

### File: docs/sway/docs/book/src/basics/blockchain_types.md

# Blockchain Types

Sway is fundamentally a blockchain language, and it offers a selection of types tailored for the blockchain use case.

These are provided via the standard library ([`lib-std`](https://github.com/FuelLabs/sway/tree/master/sway-lib-std)) which both add a degree of type-safety, as well as make the intention of the developer more clear.

## `Address` Type

<!-- This section should explain the `Address` type -->
<!-- address:example:start -->
The `Address` type is a type-safe wrapper around the primitive `b256` type. Unlike the EVM, an address **never** refers to a deployed smart contract (see the `ContractId` type below). An `Address` can be either the hash of a public key (effectively an [externally owned account](https://ethereum.org/en/whitepaper/#ethereum-accounts) if you're coming from the EVM) or the hash of a [predicate](../sway-program-types/predicates.md). Addresses own UTXOs.
<!-- address:example:end -->

An `Address` is implemented as follows.

```sway
pub struct Address {
    value: b256,
}
```

Casting between the `b256` and `Address` types must be done explicitly:

```sway
let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_address: Address = Address::from(my_number);
let forty_two: b256 = my_address.into();
```

## `ContractId` Type

<!-- This section should explain the `ContractId` type -->
<!-- contract_id:example:start -->
The `ContractId` type is a type-safe wrapper around the primitive `b256` type. A contract's ID is a unique, deterministic identifier analogous to a contract's address in the EVM. Contracts cannot own UTXOs but can own assets.
<!-- contract_id:example:end -->

A `ContractId` is implemented as follows.

```sway
pub struct ContractId {
    value: b256,
}
```

Casting between the `b256` and `ContractId` types must be done explicitly:

```sway
let my_number: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
let my_contract_id: ContractId = ContractId::from(my_number);
let forty_two: b256 = my_contract_id.into();
```

### Getting a Contract's `ContractId`

To get the `ContractId` of a contract in an internal context use the `ContractId::this()` function:

```sway
impl MyContract for Contract {
    fn foo() {
        let this_contract_id: ContractId = ContractId::this();
    }
}
```

## `Identity` Type

<!-- This section should explain the `Identity` type -->
<!-- identity:example:start -->
The `Identity` type is an enum that allows for the handling of both `Address` and `ContractId` types. This is useful in cases where either type is accepted, e.g., receiving funds from an identified sender, but not caring if the sender is an address or a contract.
<!-- identity:example:end -->

An `Identity` is implemented as follows.

```sway
pub enum Identity {
    Address: Address,
    ContractId: ContractId,
}
```

Casting to an `Identity` must be done explicitly:

```sway
        let raw_address: b256 = 0xddec0e7e6a9a4a4e3e57d08d080d71a299c628a46bc609aab4627695679421ca;
        let my_identity: Identity = Identity::Address(Address::from(raw_address));
```

A `match` statement can be used to return to an `Address` or `ContractId` as well as handle cases in which their execution differs.

```sway
        let my_contract_id: ContractId = match my_identity {
            Identity::ContractId(identity) => identity,
            _ => revert(0),
        };
```

```sway
        match my_identity {
            Identity::Address(address) => takes_address(address),
            Identity::ContractId(contract_id) => takes_contract_id(contract_id),
        };
```
<!-- This section should explain the use case for the `Identity` type -->
<!-- use_identity:example:start -->
A common use case for `Identity` is for access control. The use of `Identity` uniquely allows both `ContractId` and `Address` to have access control inclusively.
<!-- use_identity:example:end -->

```sway
        let sender = msg_sender().unwrap();
        require(
            sender == storage
                .owner
                .read(),
            MyError::UnauthorizedUser(sender),
        );
```


---

### File: docs/sway/docs/book/src/basics/built_in_types.md

# Built-in Types

Every value in Sway is of a certain type. Although deep down, all values are just ones and zeroes in the underlying virtual machine, Sway needs to know what those ones and zeroes actually mean. This is accomplished with _types_.

<!-- This section should explain how Sway types are inferred -->
<!-- sway_types:example:start -->
Sway is a statically typed language. At compile time, the types of every value must be known. This does not mean you need to specify every single type: usually, the type can be reasonably inferred by the compiler.
<!-- sway_types:example:end -->

## Primitive Types

<!-- This section should list the primitive types in Sway -->
<!-- prim_types:example:start -->
Sway has the following primitive types:

1. `()` (unit type)
1. `u8` (8-bit unsigned integer)
1. `u16` (16-bit unsigned integer)
1. `u32` (32-bit unsigned integer)
1. `u64` (64-bit unsigned integer)
1. `u256` (256-bit unsigned integer)
1. `str[]` (fixed-length string)
1. `str` (string slices)
1. `bool` (Boolean `true` or `false`)
1. `b256` (256 bits (32 bytes), i.e. a hash)

All other types in Sway are built up of these primitive types, or references to these primitive types. You may notice that there are no signed integers&mdash;this is by design. In the blockchain domain that Sway occupies, floating-point values and negative numbers have smaller utility, so their implementation has been left up to libraries for specific use cases.
<!-- prim_types:example:end -->

## Unit Type

The unit type, `()`, is a type that allows only one value, and thus, represents a value with no information. It is used to indicate the absence of a meaningful value, or the result of a function that performs an action, but does not return any data. The value of the unit type, called simply unit, has the same symbol as the unit type, `()`. Unit type in Sway serves a similar purpose as `void` in imperative languages like C or Java.

For example:

```Sway
fn returns_unit() -> () { // Here, `()` represent the unit type.
    ()                    // Here, `()` represents the single unit value of the unit type.
}
```

In Sway, if the function return type is not specified, it is `()` by default. Thus, the above example is semantically same as the following:

```Sway
fn returns_unit() {
}
```

## Numeric Types

All of the unsigned integer types are numeric types.

Numbers can be declared with binary syntax, hexadecimal syntax, base-10 syntax, and underscores for delineation. Let's take a look at the following valid numeric primitives:

```sway
0xffffff    // hexadecimal
0b10101010  // binary
10          // base-10
100_000     // underscore delineated base-10
0x1111_0000 // underscore delineated binary
0xfff_aaa   // underscore delineated hexadecimal
```

<!-- This section should explain the default numeric type in Sway -->
<!-- default_num:example:start -->
The default numeric type is `u64`. The FuelVM's word size is 64 bits, and the cases where using a smaller numeric type saves space are minimal.

If a 64-bit or 256-bit arithmetic operation produces an overflow or an underflow,
computation gets reverted automatically by FuelVM.

8/16/32-bit arithmetic operations are emulated using their 64-bit analogues with
additional overflow/underflow checks inserted, which generally results in
somewhat higher gas consumption.

The same does not happen with 256-bit operations, including `b256`, which uses specialized operations and are as efficient as possible.
<!-- default_num:example:end -->

## Boolean Type

<!-- This section should explain the `bool` type -->
<!-- bool:example:start -->
The boolean type (`bool`) has two potential values: `true` or `false`. Boolean values are typically used for conditional logic or validation, for example in `if` expressions. Booleans can be negated, or flipped, with the unary negation operator `!`.
<!-- bool:example:end -->

For example:

```sway
fn returns_false() -> bool {
    let boolean_value: bool = true;
    !boolean_value
}
```

## String Slices

<!-- This section should explain the string type in Sway -->
<!-- str:example:start -->
In Sway, string literals are stored as variable length string slices. Which means that they are stored as a pointer to the actual string data and its length.
<!-- str:example:end -->

```sway
let my_string: str = "fuel";
```

String slices, because they contain pointers have limited usage. They cannot be used as constants, storage fields, or configurable constants, nor as main function arguments or returns.

For these cases one must use string arrays, as described below.

## String Arrays

<!-- This section should explain the string type in Sway -->
<!-- str:example:start -->
In Sway, static-length strings are a primitive type. This means that when you declare a string array, its size is a part of its type. This is necessary for the compiler to know how much memory to give for the storage of that data. The size of the string is denoted with square brackets.
<!-- str:example:end -->

Let's take a look:

```sway
let my_string: str[4] = __to_str_array("fuel");
```

Because the string literal `"fuel"` is four letters, the type is `str[4]`, denoting a static length of 4 characters. Strings default to UTF-8 in Sway.

As above, string literals are typed as string slices. So that is why the need for `__to_str_array` that convert them to string arrays at compile time.

Conversion during runtime can be done with `from_str_array` and `try_as_str_array`. The latter can fail, given that the specified string array must be big enough for the string slice content.

```sway
let a: str = "abcd";
let b: str[4] = a.try_as_str_array().unwrap();
let c: str = from_str_array(b);
```

## Compound Types

_Compound types_ are types that group multiple values into one type. In Sway, we have arrays and tuples.

## Tuple Types

<!-- This section should explain what a tuple is -->
<!-- tuple:example:start -->
A tuple is a general-purpose static-length aggregation of types. In more plain terms, a tuple is a single type that consists of an aggregate of zero or more types. The internal types that make up a tuple, and the tuple's arity, define the tuple's type.
<!-- tuple:example:end -->

Let's take a look at some examples.

```sway
let x: (u64, u64) = (0, 0);
```

This is a tuple, denoted by parenthesized, comma-separated values. Note that the type annotation, `(u64, u64)`, is similar in syntax to the expression which instantiates that type, `(0, 0)`.

```sway
let x: (u64, bool) = (42, true);
assert(x.1);
```

In this example, we have created a new tuple type, `(u64, bool)`, which is a composite of a `u64` and a `bool`.

<!-- This section should explain how to access a value in a tuple -->
<!-- tuple_val:example:start -->
To access a value within a tuple, we use _tuple indexing_: `x.1` stands for the first (zero-indexed, so the `bool`) value of the tuple. Likewise, `x.0` would be the zeroth, `u64` value of the tuple. Tuple values can also be accessed via destructuring.
<!-- tuple_val:example:end -->

```sway
struct Foo {}
let x: (u64, Foo, bool) = (42, Foo {}, true);
let (number, foo, boolean) = x;
```

To create one-arity tuples, we will need to add a trailing comma:

```sway
let x: u64 = (42);     // x is of type u64
let y: (u64) = (42);   // y is of type u64
let z: (u64,) = (42,); // z is of type (u64), i.e. a one-arity tuple
let w: (u64) = (42,);  // type error
```

## Arrays

<!-- This section should explain what an array is -->
<!-- array:example:start -->
An array is similar to a tuple, but an array's values must all be of the same type. Arrays can hold arbitrary types including non-primitive types.
<!-- array:example:end -->

An array is written as a comma-separated list inside square brackets:

```sway
let x = [1, 2, 3, 4, 5];
```

<!-- This section should explain arrays in depth -->
<!-- array_details:example:start -->
Arrays are allocated on the stack since their size is known. An array's size is _always_ static, i.e. it cannot change. An array of five elements cannot become an array of six elements.

Arrays can be iterated over, unlike tuples. An array's type is written as the type the array contains followed by the number of elements, semicolon-separated and within square brackets, e.g., `[u64; 5]`. To access an element in an array, use the _array indexing syntax_, i.e. square brackets.
<!-- array_details:example:end -->

Array elements can also be mutated if the underlying array is declared as mutable:

```sway
let mut x = [1, 2, 3, 4, 5];
x[0] = 0;
```

```sway
script;

struct Foo {
    f1: u32,
    f2: b256,
}

fn main() {
    // Array of integers with type ascription
    let array_of_integers: [u8; 5] = [1, 2, 3, 4, 5];

    // Array of strings
    let array_of_strings = ["Bob", "Jan", "Ron"];

    // Array of structs
    let array_of_structs: [Foo; 2] = [
        Foo {
            f1: 11,
            f2: 0x1111111111111111111111111111111111111111111111111111111111111111,
        },
        Foo {
            f1: 22,
            f2: 0x2222222222222222222222222222222222222222222222222222222222222222,
        },
    ];

    // Accessing an element of an array
    let mut array_of_bools: [bool; 2] = [true, false];
    assert(array_of_bools[0]);

    // Mutating the element of an array
    array_of_bools[1] = true;
    assert(array_of_bools[1]);
}

```


---

### File: docs/sway/docs/book/src/basics/comments_and_logging.md

# Comments and Logging

## Comments

<!-- This section should explain how to add comments in Sway -->
<!-- comments:example:start -->
Comments in Sway start with two slashes and continue until the end of the line. For comments that extend beyond a single line, you'll need to include `//` on each line.
<!-- comments:example:end -->

```sway
// hello world
```

```sway
// let's make a couple of lines
// commented.
```

You can also place comments at the ends of lines containing code.

```sway
fn main() {
    let baz = 8; // Eight is a lucky number
}
```

You can also do block comments

```sway
fn main() {
    /*
    You can write on multiple lines
    like this if you want
    */
    let baz = 8;
}
```

## Logging

<!-- This section should explain logging in Sway -->
<!-- logging:example:start -->
The `logging` library provides a generic `log` function that can be imported using `use std::logging::log` and used to log variables of any type. Each call to `log` appends a `receipt` to the list of receipts. There are two types of receipts that a `log` can generate: `Log` and `LogData`.
<!-- logging:example:end -->

```sway
fn log_values(){
  // Generates a Log receipt
  log(42);

  // Generates a LogData receipt
  let string = "sway";
  log(string);
}
```

### `Log` Receipt

<!-- This section should explain when `Log` receipts are produced -->
<!-- log_rec:example:start -->
The `Log` receipt is generated for _non-reference_ types, namely `bool`, `u8`, `u16`, `u32`, and `u64`.
<!-- log_rec:example:end -->

For example, logging an integer variable `x` that holds the value `42` using `log(x)` may generate the following receipt:

```console
"Log": {
  "id": "0000000000000000000000000000000000000000000000000000000000000000",
  "is": 10352,
  "pc": 10404,
  "ra": 42,
  "rb": 1018205,
  "rc": 0,
  "rd": 0
}
```

Note that `ra` will include the value being logged. The additional registers `rc` and `rd` will be zero when using `log` while `rb` may include a non-zero value representing a unique ID for the `log` instance. The unique ID is not meaningful on its own but allows the Rust and the TS SDKs to know the type of the data being logged, by looking up the log ID in the JSON ABI file.

### `LogData` Receipt

<!-- This section should explain when `LogData` receipts are produced -->
<!-- log_data_rec:example:start -->
`LogData` is generated for _reference_ types which include all types except for _non_reference_ types; and for  _non-reference_ types bigger than 64-bit integers, for example, `u256`;
<!-- log_data_rec:example:end -->

For example, logging a `b256` variable `b` that holds the value `0x1111111111111111111111111111111111111111111111111111111111111111` using `log(b)` may generate the following receipt:

```console
"LogData": {
  "data": "1111111111111111111111111111111111111111111111111111111111111111",
  "digest": "02d449a31fbb267c8f352e9968a79e3e5fc95c1bbeaa502fd6454ebde5a4bedc",
  "id": "0000000000000000000000000000000000000000000000000000000000000000",
  "is": 10352,
  "len": 32,
  "pc": 10444,
  "ptr": 10468,
  "ra": 0,
  "rb": 1018194
}
```

Note that `data` in the receipt above will include the value being logged as a hexadecimal. Similarly to the `Log` receipt, additional registers are written: `ra` will always be zero when using `log`, while `rb` will contain a unique ID for the `log` instance.

> **Note**
> The Rust SDK exposes [APIs](https://fuellabs.github.io/fuels-rs/master/calling-contracts/logs.html#logs) that allow you to retrieve the logged values and display them nicely based on their types as indicated in the JSON ABI file.


---

### File: docs/sway/docs/book/src/basics/commonly_used_library_types.md

# Commonly Used Library Types

The Sway Standard Library is the foundation of portable Sway software, a set of minimal shared abstractions for the broader Sway ecosystem. It offers core types, library-defined operations on language primitives, native asset management, blockchain contextual operations, access control, storage management, and support for types from other VMs, among many other things. Reference the standard library docs [here](https://fuellabs.github.io/sway/master/std/index.html).

## `Result<T, E>`

<!-- This section should explain what the `Result` type is -->
<!-- result:example:start -->
Type `Result` is the type used for returning and propagating recoverable errors. It is an `enum` with two variants: `Ok(T)`, representing success and containing a value, and `Err(E)`, representing error and containing an error value. The `T` and `E` in this definition are type parameters, allowing `Result` to be generic and to be used with any types.
<!-- result:example:end -->

```sway
/// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
pub enum Result<T, E> {
    /// Contains the success value.
    Ok: T,
    /// Contains the error value.
    Err: E,
}
```

<!-- This section should explain when to use the `Result` type -->
<!-- use_result:example:start -->
Functions return `Result` whenever errors are expected and recoverable.
<!-- use_result:example:end -->

Take the following example:

```sway
script;

enum MyContractError {
    DivisionByZero: (),
}

fn divide(numerator: u64, denominator: u64) -> Result<u64, MyContractError> {
    if (denominator == 0) {
        return Err(MyContractError::DivisionByZero);
    } else {
        Ok(numerator / denominator)
    }
}

fn main() -> Result<u64, str[4]> {
    let result = divide(20, 2);
    match result {
        Ok(value) => Ok(value),
        Err(MyContractError::DivisionByZero) => Err(__to_str_array("Fail")),
    }
}

```

To learn more about expressing irrecoverable errors in Sway, see the chapter on [Error Handling](error_handling.md).

## `Option<T>`

<!-- This section should explain the `Option` type -->
<!-- option:example:start -->
Type `Option` represents an optional value: every `Option` is either `Some` and contains a value, or `None`, and does not. `Option` types are very common in Sway code, as they have a number of uses:

- Initial values where `None` can be used as an initializer.
- Return value for otherwise reporting simple errors, where `None` is returned on error.

The implementation of `Option` matches on the variant: if it's `Ok` it returns the inner value, if it's `None`, it [reverts](https://github.com/FuelLabs/fuel-specs/blob/master/src/fuel-vm/instruction-set.md#rvrt-revert).
<!-- option:example:end -->

```sway
/// A type that represents an optional value, either `Some(val)` or `None`.
pub enum Option<T> {
    /// No value.
    None: (),
    /// Some value of type `T`.
    Some: T,
}
```

<!-- This section should explain when to use the `Option` type -->
<!-- use_option:example:start -->
`Option` is commonly paired with pattern matching to query the presence of a value and take action, allowing developers to choose how to handle the `None` case.
<!-- use_option:example:end -->

Below is an example that uses pattern matching to handle invalid divisions by 0 by returning an `Option`:

```sway
script;

fn divide(numerator: u64, denominator: u64) -> Option<u64> {
    if denominator == 0 {
        None
    } else {
        Some(numerator / denominator)
    }
}

fn main() {
    let result = divide(6, 2);
    // Pattern match to retrieve the value
    match result {
        // The division was valid
        Some(x) => std::logging::log(x),
        // The division was invalid
        None => std::logging::log("Cannot divide by 0"),
    }
}

```


---

### File: docs/sway/docs/book/src/basics/constants.md

# Constants

<!-- This section should explain what constants are in Sway -->
<!-- constants:example:start -->
Constants are similar to variables; however, there are a few differences:

- Constants are always evaluated at compile-time.
- Constants can be declared both inside of a [function](../index.md) and at global / `impl` scope.
- The `mut` keyword cannot be used with constants.
<!-- constants:example:end -->

```sway
const ID: u32 = 0;
```

Constant initializer expressions can be quite complex, but they cannot use, for
instance, assembly instructions, storage access, mutable variables, loops and
`return` statements. Although, function calls, primitive types and compound data
structures are perfectly fine to use:

```sway
fn bool_to_num(b: bool) -> u64 {
    if b {
        1
    } else {
        0
    }
}

fn arr_wrapper(a: u64, b: u64, c: u64) -> [u64; 3] {
    [a, b, c]
}

const ARR2 = arr_wrapper(bool_to_num(1) + 42, 2, 3);
```

## Associated Constants

<!-- This section should explain what associated constants are -->
<!-- assoc_constants:example:start -->
Associated constants are constants associated with a type and can be declared in an `impl` block or in a `trait` definition.

Associated constants declared inside a `trait` definition may omit their initializers to indicate that each implementation of the trait must specify those initializers.

The identifier is the name of the constant used in the path. The type is the type that the
definition has to implement.
<!-- assoc_constants:example:end -->

You can _define_ an associated `const` directly in the interface surface of a trait:

```sway
script;

trait ConstantId {
    const ID: u32 = 0;
}
```

Alternatively, you can also _declare_ it in the trait, and implement it in the interface of the
types implementing the trait.

```sway
script;

trait ConstantId {
    const ID: u32;
}

struct Struct {}

impl ConstantId for Struct {
    const ID: u32 = 1;
}

fn main() -> u32 {
    Struct::ID
}
```

### `impl self` Constants

Constants can also be declared inside non-trait `impl` blocks.

```sway
script;

struct Point {
    x: u64,
    y: u64,
}

impl Point {
    const ZERO: Point = Point { x: 0, y: 0 };
}

fn main() -> u64  {
    Point::ZERO.x
}
```

## Configurable Constants

<!-- This section should explain what configurable constants are in Sway -->
<!-- config_constants:example:start -->
Configurable constants are special constants that behave like regular constants in the sense that they cannot change during program execution, but they can be configured _after_ the Sway program has been built. The Rust and TS SDKs allow updating the values of these constants by injecting new values for them directly in the bytecode without having to build the program again. These are useful for contract factories and behave somewhat similarly to `immutable` variables from languages like Solidity.
<!-- config_constants:example:end -->

Configurable constants are declared inside a `configurable` block and require a type ascription and an initializer as follows:

```sway
configurable {
    U8: u8 = 8u8,
    BOOL: bool = true,
    ARRAY: [u32; 3] = [253u32, 254u32, 255u32],
    STR_4: str[4] = __to_str_array("fuel"),
    STRUCT: StructWithGeneric<u8> = StructWithGeneric {
        field_1: 8u8,
        field_2: 16,
    },
    ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}
```

At most one `configurable` block is allowed in a Sway project. Moreover, `configurable` blocks are not allowed in libraries.

Configurable constants can be read directly just like regular constants:

```sway
    fn return_configurables() -> (u8, bool, [u32; 3], str[4], StructWithGeneric<u8>) {
        (U8, BOOL, ARRAY, STR_4, STRUCT)
    }
```


---

### File: docs/sway/docs/book/src/basics/control_flow.md

# Control Flow

## `if` expressions

<!-- This section should explain `if` expressions in Sway -->
<!-- if:example:start -->
Sway supports _if_, _else_, and _else if_ expressions that allow you to branch your code depending on conditions.
<!-- if:example:end -->

For example:

```sway
fn main() {
    let number = 6;

    if number % 4 == 0 {
        // do something
    } else if number % 3 == 0 {
        // do something else
    } else {
        // do something else
    }
}
```

### Using `if` in a `let` statement

Like Rust, `if`s are expressions in Sway. What this means is you can use `if` expressions on the right side of a `let` statement to assign the outcome to a variable.

```sway
let my_data = if some_bool < 10 { foo() } else { bar() };
```

Note that all branches of the `if` expression must return a value of the same type.

### `match` expressions

<!-- This section should explain `match` expressions in Sway -->
<!-- match:example:start -->
Sway supports advanced pattern matching through exhaustive `match` expressions. Unlike an `if` expression, a `match` expression asserts **at compile time** that all possible patterns have been matched. If you don't handle all the patterns, you will get compiler error indicating that your `match` expression is non-exhaustive.
<!-- match:example:end -->

The basic syntax of a `match` expression is as follows:

```sway
let result = match expression {
    pattern1 => code_to_execute_if_expression_matches_pattern1,
    pattern2 => code_to_execute_if_expression_matches_pattern2,
    pattern3 | pattern4 => code_to_execute_if_expression_matches_pattern3_or_pattern4
    ...
    _ => code_to_execute_if_expression_matches_no_pattern,
}
```

Some examples of how you can use a `match` expression:

```sway
script;

// helper functions for our example
fn on_even(num: u64) {
    // do something with even numbers
}
fn on_odd(num: u64) {
    // do something with odd numbers
}

fn main(num: u64) -> u64 {
    // Match as an expression
    let is_even = match num % 2 {
        0 => true,
        _ => false,
    };

    // Match as control flow
    let x = 12;
    match x {
        5 => on_odd(x),
        _ => on_even(x),
    };

    // Match an enum
    enum Weather {
        Sunny: (),
        Rainy: (),
        Cloudy: (),
        Snowy: (),
    }
    let current_weather = Weather::Sunny;
    let avg_temp = match current_weather {
        Weather::Sunny => 80,
        Weather::Rainy => 50,
        Weather::Cloudy => 60,
        Weather::Snowy => 20,
    };

    let is_sunny = match current_weather {
        Weather::Sunny => true,
        Weather::Rainy | Weather::Cloudy | Weather::Snowy => false,
    };

    // match expression used for a return
    let outside_temp = Weather::Sunny;
    match outside_temp {
        Weather::Sunny => 80,
        Weather::Rainy => 50,
        Weather::Cloudy => 60,
        Weather::Snowy => 20,
    }
}

```

## Loops

### `while`

This is what a `while` loop looks like:

```sway
while counter < 10 {
    counter = counter + 1;
}
```

You need the `while` keyword, some condition (`value < 10` in this case) which will be evaluated each iteration, and a block of code inside the curly braces (`{...}`) to execute each iteration.

### `for`

This is what a `for` loop that computes the sum of a vector of numbers looks like:

```sway
for element in vector.iter() {
    sum += element;
}
```

You need the `for` keyword, some pattern that contains variable names such as `element` in this case, the `ìn` keyword followed by an iterator, and a block of code inside the curly braces (`{...}`) to execute each iteration. `vector.iter()` in the example above returns an iterator for the `vector`. In each iteration, the value of `element` is updated with the next value in the iterator until the end of the vector is reached and the `for` loop iteration ends.

Modifying the `vector` during iteration, by e.g. adding or removing elements, is a logical error and results in an [undefined behavior](../reference/undefined_behavior.md):

```sway
// The behavior of this `for` loop is undefined because
// the `vector` gets modified within the loop.
for element in vector.iter() {
    if element == 3 {
        vector.push(6); // Modification of the vector!
    }
}
```

### `break` and `continue`

`break` and `continue` keywords are available to use inside the body of a `while` or `for` loop. The purpose of the `break` statement is to break out of a loop early:

```sway
fn break_example() -> u64 {
    let mut counter = 1;
    let mut sum = 0;
    let num = 10;
    while true {
        if counter > num {
            break;
        }
        sum += counter;
        counter += 1;
    }
    sum // 1 + 2 + .. + 10 = 55
}
```

The purpose of the `continue` statement is to skip a portion of a loop in an iteration and jump directly into the next iteration:

```sway
fn continue_example() -> u64 {
    let mut counter = 0;
    let mut sum = 0;
    let num = 10;
    while counter < num {
        counter += 1;
        if counter % 2 == 0 {
            continue;
        }
        sum += counter;
    }
    sum // 1 + 3 + .. + 9 = 25
}
```

### Nested loops

You can also use nested `while` loops if needed:

```sway
while condition_1 == true {
    // do stuff...
    while condition_2 == true {
        // do more stuff...
    }
}
```


---

### File: docs/sway/docs/book/src/basics/converting_types.md

# Converting Types

Below are some common type conversions in Sway:

- [Identity Conversions](#identity-conversions)
- [String Conversions](#string-conversions)
- [Number Conversions](#number-conversions)
- [Byte Array Conversions](#byte-array-conversions)

## Identity Conversions

### Convert to `Identity`

```sway
    let identity_from_b256: Identity = Identity::Address(Address::from(b256_address));
    let identity_from_address: Identity = Identity::Address(address);
    let identity_from_contract_id: Identity = Identity::ContractId(contract_id);
```

### Convert `Identity` to `ContractId` or `Address`

```sway
    match my_identity {
        Identity::Address(address) => log(address),
        Identity::ContractId(contract_id) => log(contract_id),
    };
```

### Convert `ContractId` or `Address` to `b256`

```sway
    let b256_from_address: b256 = address.into();
    let b256_from_contract_id: b256 = contract_id.into();
```

### Convert `b256` to `ContractId` or `Address`

```sway
    let address_from_b256: Address = Address::from(b256_address);
    let contract_id_from_b256: ContractId = ContractId::from(b256_address);
```

## String Conversions

### Convert `str` to `str[]`

```sway
    let fuel_str: str = "fuel";
    let fuel_str_array: str[4] = fuel_str.try_as_str_array().unwrap();
```

### Convert `str[]` to `str`

```sway
    let fuel_str_array: str[4] = __to_str_array("fuel");
    let fuel_str: str = from_str_array(fuel_str_array);
```

## Number Conversions

### Convert to `u256`

```sway
    let u8_1: u8 = 2u8;
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2u64;
    let b256_1: b256 = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20;

    let u256_from_u8: u256 = u8_1.as_u256();
    let u256_from_u16: u256 = u16_1.as_u256();
    let u256_from_u32: u256 = u32_1.as_u256();
    let u256_from_u64: u256 = u64_1.as_u256();
    let u256_from_b256: u256 = b256_1.as_u256();
```

### Convert to `u64`

```sway
    let u8_1: u8 = 2u8;
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u64_from_u8: u64 = u8_1.as_u64();

    let u64_from_u16: u64 = u16_1.as_u64();

    let u64_from_u32: u64 = u32_1.as_u64();

    let u64_from_u256: Option<u64> = <u64 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `u32`

```sway
    let u8_1: u8 = 2u8;
    let u16_1: u16 = 2u16;
    let u64_1: u64 = 2;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u32_from_u8: u32 = u8_1.as_u32();

    let u32_from_u16: u32 = u16_1.as_u32();

    let u32_from_u64_1: Option<u32> = u64_1.try_as_u32();
    let u32_from_u64_2: Option<u32> = <u32 as TryFrom<u64>>::try_from(u64_1);

    let u32_from_u256: Option<u32> = <u32 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `u16`

```sway
    let u8_1: u8 = 2u8;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u16_from_u8: u16 = u8_1.as_u16();

    let u16_from_u32_1: Option<u16> = u32_1.try_as_u16();
    let u16_from_u32_2: Option<u16> = <u16 as TryFrom<u32>>::try_from(u32_1);

    let u16_from_u64_1: Option<u16> = u64_1.try_as_u16();
    let u16_from_u64_2: Option<u16> = <u16 as TryFrom<u64>>::try_from(u64_1);

    let u16_from_u256: Option<u16> = <u16 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `u8`

```sway
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;

    let u8_from_u16_1: Option<u8> = u16_1.try_as_u8();
    let u8_from_u16_2: Option<u8> = <u8 as TryFrom<u16>>::try_from(u16_1);

    let u8_from_u32_1: Option<u8> = u32_1.try_as_u8();
    let u8_from_u32_2: Option<u8> = <u8 as TryFrom<u32>>::try_from(u32_1);

    let u8_from_u64_1: Option<u8> = u64_1.try_as_u8();
    let u8_from_u64_2: Option<u8> = <u8 as TryFrom<u64>>::try_from(u64_1);

    let u8_from_u256: Option<u8> = <u8 as TryFrom<u256>>::try_from(u256_1);
```

### Convert to `Bytes`

```sway
use std::{bytes::Bytes, bytes_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*}};
```

```sway
use std::{bytes::Bytes, bytes_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*}};
    let num = 5;
    let little_endian_bytes: Bytes = num.to_le_bytes();
    let big_endian_bytes: Bytes = num.to_be_bytes();
```

### Convert from `Bytes`

```sway
use std::{bytes::Bytes, bytes_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*}};
```

```sway
    let u16_from_le_bytes: u16 = u16::from_le_bytes(little_endian_bytes);
    let u16_from_be_bytes: u16 = u16::from_be_bytes(big_endian_bytes);

    let u32_from_le_bytes: u32 = u32::from_le_bytes(little_endian_bytes);
    let u32_from_be_bytes: u32 = u32::from_be_bytes(big_endian_bytes);

    let u64_from_le_bytes: u64 = u64::from_le_bytes(little_endian_bytes);
    let u64_from_be_bytes: u64 = u64::from_be_bytes(big_endian_bytes);

    let u256_from_le_bytes = u256::from_le_bytes(little_endian_bytes);
    let u256_from_be_bytes = u256::from_be_bytes(big_endian_bytes);

    let b256_from_le_bytes = b256::from_le_bytes(little_endian_bytes);
    let b256_from_be_bytes = b256::from_be_bytes(big_endian_bytes);
```

## Byte Array Conversions

### Convert to a Byte Array

```sway
use std::array_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*};
```

```sway
use std::array_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*};
    let u16_1: u16 = 2u16;
    let u32_1: u32 = 2u32;
    let u64_1: u64 = 2u64;
    let u256_1: u256 = 0x0000000000000000000000000000000000000000000000000000000000000002u256;
    let b256_1: b256 = 0x000000000000000000000000000000000000000000000000000000000000002A;
    // little endian
    let le_byte_array_from_u16: [u8; 2] = u16_1.to_le_bytes();
    let le_byte_array_from_u32: [u8; 4] = u32_1.to_le_bytes();
    let le_byte_array_from_u64: [u8; 8] = u64_1.to_le_bytes();
    let le_byte_array_from_u256: [u8; 32] = u256_1.to_le_bytes();
    let le_byte_array_from_b256: [u8; 32] = b256_1.to_le_bytes();
    // big endian
    let be_byte_array_from_u16: [u8; 2] = u16_1.to_be_bytes();
    let be_byte_array_from_u32: [u8; 4] = u32_1.to_be_bytes();
    let be_byte_array_from_u64: [u8; 8] = u64_1.to_be_bytes();
    let be_byte_array_from_u256: [u8; 32] = u256_1.to_be_bytes();
    let be_byte_array_from_b256: [u8; 32] = b256_1.to_be_bytes();
```

### Convert from a Byte Array

```sway
use std::array_conversions::{b256::*, u16::*, u256::*, u32::*, u64::*};
```

```sway
    let u16_byte_array: [u8; 2] = [2_u8, 1_u8];
    let u32_byte_array: [u8; 4] = [4_u8, 3_u8, 2_u8, 1_u8];
    let u64_byte_array: [u8; 8] = [8_u8, 7_u8, 6_u8, 5_u8, 4_u8, 3_u8, 2_u8, 1_u8];
    let u256_byte_array: [u8; 32] = [
        32_u8, 31_u8, 30_u8, 29_u8, 28_u8, 27_u8, 26_u8, 25_u8, 24_u8, 23_u8, 22_u8,
        21_u8, 20_u8, 19_u8, 18_u8, 17_u8, 16_u8, 15_u8, 14_u8, 13_u8, 12_u8, 11_u8,
        10_u8, 9_u8, 8_u8, 7_u8, 6_u8, 5_u8, 4_u8, 3_u8, 2_u8, 1_u8,
    ];
    // little endian
    let le_u16_from_byte_array: u16 = u16::from_le_bytes(u16_byte_array);
    let le_u32_from_byte_array: u32 = u32::from_le_bytes(u32_byte_array);
    let le_u64_from_byte_array: u64 = u64::from_le_bytes(u64_byte_array);
    let le_u256_from_byte_array: u256 = u256::from_le_bytes(u256_byte_array);
    let le_b256_from_byte_array: b256 = b256::from_le_bytes(u256_byte_array);
    // big endian
    let be_u16_from_byte_array: u16 = u16::from_be_bytes(u16_byte_array);
    let be_u32_from_byte_array: u32 = u32::from_be_bytes(u32_byte_array);
    let be_u64_from_byte_array: u64 = u64::from_be_bytes(u64_byte_array);
    let be_u256_from_byte_array: u256 = u256::from_be_bytes(u256_byte_array);
    let be_b256_from_byte_array: b256 = b256::from_be_bytes(u256_byte_array);
```


---

### File: docs/sway/docs/book/src/basics/error_handling.md

# Error Handling

## Recoverable Errors

Recoverable errors represent expected faults. Similar to Rust, Sway expresses recoverable errors by using the `std::result::Result` enum, letting you propagate or transform the error without immediately reverting the transaction.

To learn more about expressing and handling recoverable errors, see the chapter on [`Result<T, E>` enum](commonly_used_library_types.md#resultt-e).

## Irrecoverable Errors

Irrecoverable errors indicate bugs or violated invariants. They trigger a VM-wide revert that atomically rolls back every state change in the transaction, and it cannot be caught or handled in Sway code, signaling that the program cannot sensibly continue.

### `panic` Expression

The recommended way of expressing an irrecoverable errors is to use the `panic` expression:

```sway
if some_error_occurred {
    panic "Some error has occurred.";
}
```

At runtime, the `panic` expression aborts and reverts the execution of the entire program. At compile time, for each `panic` encountered in code, Sway compiler will generate a unique revert code and create an entry in the ABI JSON `errorCodes` section. The generated `errorCodes` entry will contain the information about source location at which the `panic` occurs, as well as the error message.

**This mechanism allows for getting a rich troubleshooting information, without an additional on-chain cost.** The generated bytecode will contain only the revert instruction, and the remaining information, the error message and the error location, are stored off-chain, in the ABI JSON file.

For example, let's assume that the above code is situated in the module `some_module`, contained within the version `v1.2.3` of the package `some_package`.

At runtime, the `panic` will result in a compiler generated revert code, e.g., 18446744069414584323. At compile time, an entry similar to this will be added to the ABI JSON `errorCodes` section:

```json
"errorCodes": {
    "18446744069414584323": {
        "pos": {
          "pkg": "some_package@1.2.3",
          "file": "some_module.sw",
          "line": 13,
          "column": 9
        },
        "logId": null,
        "msg": "Some error has occurred."
    },
}
```

Rust and TypeScript SDK, as well as `forc test`, recognize revert codes generated from `panic` expressions. E.g., if a Sway unit test fails because of a revert caused by the above `panic` line, the `forc test` will display the following:

```console
test some_test, "path/to/failing/test.sw":42
    revert code: ffffffff00000003
    ├─ panic message: Some error has occurred.
    └─ panicked in:   some_package@1.2.3, src/some_module.sw:13:9
```

### Error Types

Passing textual error messages directly as a `panic` argument is the most convenient way to provide a helpful error message. It is sufficient for many use-cases. However, often we want:

- to provide an additional runtime information about the error.
- group a certain family of errors together.

For these use-cases, you can use _error types_. Error types are enums annotated with the `#[error_type]` attribute, whose all variants are attributed with the `#[error(m = "<error message>")]` attributes. Each variant represent a particular error, and the enum itself the family of errors. The convention is to postfix the names of error type enums with `Error`.

For example, let's assume we are checking if a provided `Identity` has certain access rights to our contract. The error type enum representing access rights violations could look like:

```sway
#[error_type]
pub enum AccessRightError {
    #[error(m = "The provided identity is not an administrator.")]
    NotAnAdmin: Identity,
    #[error(m = "The provided identity is not an owner.")]
    NotAnOwner: Identity,
    #[error(m = "The provided identity does not have write access.")]
    NoWriteAccess: Identity,
}
```

where each `Identity` represents the actual, provided identity.

In code, we can now check for access rights and panic if they are violated:

```sway
fn do_something_that_requires_admin_access(admin: Identity) {
    if !is_admin(admin) {
        panic AccessRightError::NotAnAdmin(admin);
    }

    // ...
}
```

Assuming we have a failing test for the above function, the test output will show the error message, but also the provided `Identity`. E.g.:

```console
test some_test_for_admin_access, "path/to/failing/test.sw":42
    revert code: ffffffff00000007
    ├─ panic message: The provided identity is not an administrator.
    ├─ panic value:   NotAnAdmin(Address(Address()))
    └─ panicked in:   some_other_package@0.1.0, src/admin_module.sw:11:9
```


---

### File: docs/sway/docs/book/src/basics/functions.md

# Functions

Functions in Sway are declared with the `fn` keyword. Let's take a look:

```sway
fn equals(first_param: u64, second_param: u64) -> bool {
    first_param == second_param
}
```

We have just declared a function named `equals` which takes two parameters: `first_param` and `second_param`. The parameters must both be 64-bit unsigned integers.

This function also returns a `bool` value, i.e. either `true` or `false`. This function returns `true` if the two given parameters are equal, and `false` if they are not. If we want to use this function, we can do so like this:

```sway
fn main() {
    equals(5, 5); // evaluates to `true`
    equals(5, 6); // evaluates to `false`
}
```

## Mutable Parameters

<!-- This section should explain how/when to use `ref mut` -->
<!-- ref_mut:example:start -->
We can make a function parameter mutable by adding `ref mut` before the parameter name. This allows mutating the argument passed into the function when the function is called.
<!-- ref_mut:example:end -->

For example:

```sway
fn increment(ref mut num: u32) {
    let prev = num;
    num = prev + 1u32;
}
```

This function is allowed to mutate its parameter `num` because of the `mut` keyword. In addition, the `ref` keyword instructs the function to modify the argument passed to it when the function is called, instead of modifying a local copy of it.

```sway
    let mut num: u32 = 0;
    increment(num);
    assert(num == 1u32); // The function `increment()` modifies `num`
```

Note that the variable `num` itself has to be declared as mutable for the above to compile.

> **Note**
> It is not currently allowed to use `mut` without `ref` or vice versa for a function parameter.

Similarly, `ref mut` can be used with more complex data types such as:

```sway
fn swap_tuple(ref mut pair: (u64, u64)) {
    let temp = pair.0;
    pair.0 = pair.1;
    pair.1 = temp;
}

fn update_color(ref mut color: Color, new_color: Color) {
    color = new_color;
}
```

We can then call these functions as shown below:

```sway
    let mut tuple = (42, 24);
    swap_tuple(tuple);
    assert(tuple.0 == 24); // The function `swap_tuple()` modifies `tuple.0`
    assert(tuple.1 == 42); // The function `swap_tuple()` modifies `tuple.1`
    let mut color = Color::Red;
    update_color(color, Color::Blue);
    assert(match color {
        Color::Blue => true,
        _ => false,
    }); // The function `update_color()` modifies the color to Blue
```

> **Note**
> The only place, in a Sway program, where the `ref` keyword is valid is before a mutable function parameter.


---

### File: docs/sway/docs/book/src/basics/index.md

# Sway Language Basics

Sway is a programming language designed for the FuelVM. It is a statically typed, compiled language with type inference and traits. Sway aims to make smart contract development safer and more efficient through the use of strong static analysis and compiler feedback.

Get started with the basics of Sway:

- [Variables](./variables.md)
- [Built-in Types](./built_in_types.md)
- [Commonly Used Library Types](./commonly_used_library_types.md)
- [Blockchain Types](./blockchain_types.md)
- [Functions](./functions.md)
- [Structs, Tuples, and Enums](./structs_tuples_and_enums.md)
- [Methods and Associated Functions](./methods_and_associated_functions.md)
- [Constants](./constants.md)
- [Comments and Logging](./comments_and_logging.md)
- [Control Flow](./control_flow.md)
- [Error Handling](./error_handling.md)


---

### File: docs/sway/docs/book/src/basics/methods_and_associated_functions.md

# Methods and Associated Functions

<!-- This section should explain methods & associated functions in Sway -->
<!-- methods_af:example:start -->
## Methods

Methods are similar to [functions](functions.md) in that we declare them with the `fn` keyword and they have parameters and return a value. However, unlike functions, _Methods_ are defined within the context of a struct (or enum), and either refers to that type or mutates it. The first parameter of a method is always `self`, which represents the instance of the struct (or enum) the method is being called on.

## Associated Functions

_Associated functions_ are very similar to _methods_, in that they are also defined in the context of a struct or enum, but they do not actually use any of the data in the struct and as a result do not take _self_ as a parameter. Associated functions could be standalone functions, but they are included in a specific type for organizational or semantic reasons.

### Constructors

Constructors are associated functions that construct, or in other words instantiate, new instances of a type. Their return type is always the type itself. E.g., public structs that have private fields must provide a public constructor, or otherwise they cannot be instantiated outside of the module in which they are declared.

## Declaring Methods and Associated Functions

To declare methods and associated functions for a struct or enum, use an `impl` block. Here, `impl` is short for implementation.
<!-- methods_af:example:end -->

```sway
script;

struct Foo {
    bar: u64,
    baz: bool,
}

impl Foo {
    // this is a _method_, as it takes `self` as a parameter.
    fn is_baz_true(self) -> bool {
        self.baz
    }

    // this is an _associated function_, since it does not take `self` as a parameter.
    // it is at the same time a _constructor_ because it instantiates and returns
    // a new instance of `Foo`.
    fn new_foo(number: u64, boolean: bool) -> Foo {
        Foo {
            bar: number,
            baz: boolean,
        }
    }
}

fn main() {
    let foo = Foo::new_foo(42, true);
    assert(foo.is_baz_true());
}

```

<!-- This section should explain how to call a method -->
<!-- call_method:example:start -->
To call a method, simply use dot syntax: `foo.iz_baz_true()`.
<!-- call_method:example:end -->

<!-- This section should explain how methods + assoc. fns can accept `ref mut` params -->
<!-- ref_mut:example:start -->
Similarly to [free functions](functions.md), methods and associated functions may accept `ref mut` parameters.
<!-- ref_mut:example:end -->

For example:

```sway
struct Coordinates {
    x: u64,
    y: u64,
}

impl Coordinates {
    fn move_right(ref mut self, distance: u64) {
        self.x += distance;
    }
}
```

and when called:

```sway
    let mut point = Coordinates { x: 1, y: 1 };
    point.move_right(5);
    assert(point.x == 6);
    assert(point.y == 1);
```


---

### File: docs/sway/docs/book/src/basics/structs_tuples_and_enums.md

# Structs, Tuples, and Enums

## Structs

<!-- This section should explain structs in Sway -->
<!-- structs:example:start -->
Structs in Sway are a named grouping of types. You may also be familiar with structs via another name: _product types_. Sway does not make any significantly unique usages of structs; they are similar to most other languages which have structs. If you're coming from an object-oriented background, a struct is like the data attributes of an object.

Those data attributes are called _fields_ and can be either public or private.

Private struct fields can be accessed only within the module in which their struct is declared. Public fields are accessible everywhere where the struct is accessible. This access control on the field level allows more fine grained encapsulation of data.

<!-- structs:example:end -->

To explain these concepts, let's take a look at the following example, in which we have a module called _data_structures_.

In that module, we declare a struct named `Foo` with two fields. The first field is named `bar`, it is public and it accepts values of type `u64`. The second field is named `baz`, it is also public and it accepts `bool` values.

In a similar way, we define the structs `Point`, `Line`, and `TupleInStruct`. Since all those structs are public, and all their fields are public, they can be instantiated in other modules using the _struct instantiation syntax_ as shown below.

On the other hand, the struct `StructWithPrivateFields` can be instantiated only within the _data_structures_ module, because it contains private fields. To be able to create instances of such structs outside of the module in which they are declared, the struct must offer [constructor associated functions](methods_and_associated_functions.md#constructors).

```sway
// the _data_structures_ module
library;

// Declare a struct type
pub struct Foo {
    pub bar: u64,
    pub baz: bool,
}

// Struct types for destructuring
pub struct Point {
    pub x: u64,
    pub y: u64,
}

pub struct Line {
    pub p1: Point,
    pub p2: Point,
}

pub struct TupleInStruct {
    pub nested_tuple: (u64, (u32, (bool, str))),
}

// Struct type instantiable only in the module _data_structures_
pub struct StructWithPrivateFields {
    pub public_field: u64,
    private_field: u64,
    other_private_field: u64,
}

```

<!-- This section should explain how to instantiate a struct in Sway -->
<!-- new_struct:example:start -->
In order to instantiate the struct we use _struct instantiation syntax_, which is very similar to the declaration syntax except with expressions in place of types.

There are three ways to instantiate the struct.

- Hard coding values for the fields
- Passing in variables with names different than the struct fields
- Using a shorthand notation via variables that are the same as the field names
<!-- new_struct:example:end -->

```sway
library;

mod data_structures;
use data_structures::{Foo, Line, Point, TupleInStruct};

fn hardcoded_instantiation() -> Foo {
    // Instantiate `foo` as `Foo`
    let mut foo = Foo {
        bar: 42,
        baz: false,
    };

    // Access and write to "baz"
    foo.baz = true;

    // Return the struct
    foo
}

fn variable_instantiation() -> Foo {
    // Declare variables with the same names as the fields in `Foo`
    let number = 42;
    let truthness = false;

    // Instantiate `foo` as `Foo`
    let mut foo = Foo {
        bar: number,
        baz: truthness,
    };

    // Access and write to "baz"
    foo.baz = true;

    // Return the struct
    foo
}

fn shorthand_instantiation() -> Foo {
    // Declare variables with the same names as the fields in `Foo`
    let bar = 42;
    let baz = false;

    // Instantiate `foo` as `Foo`
    let mut foo = Foo { bar, baz };

    // Access and write to "baz"
    foo.baz = true;

    // Return the struct
    foo
}

fn struct_destructuring() {
    let point1 = Point { x: 0, y: 0 };
    // Destructure the values from the struct into variables
    let Point { x, y } = point1;

    let point2 = Point { x: 1, y: 1 };
    // If you do not care about specific struct fields then use ".." at the end of your variable list
    let Point { x, .. } = point2;

    let line = Line {
        p1: point1,
        p2: point2,
    };
    // Destructure the values from the nested structs into variables
    let Line {
        p1: Point { x: x0, y: y0 },
        p2: Point { x: x1, y: y1 },
    } = line;
    // You may also destructure tuples nested in structs and structs nested in tuples
    let tuple_in_struct = TupleInStruct {
        nested_tuple: (42u64, (42u32, (true, "ok"))),
    };
    let TupleInStruct {
        nested_tuple: (a, (b, (c, d))),
    } = tuple_in_struct;

    let struct_in_tuple = (Point { x: 2, y: 4 }, Point { x: 3, y: 6 });
    let (Point { x: x0, y: y0 }, Point { x: x1, y: y1 }) = struct_in_tuple;
}

```

> **Note**
> You can mix and match all 3 ways to instantiate the struct at the same time.
> Moreover, the order of the fields does not matter when instantiating however we encourage declaring the fields in alphabetical order and instantiating them in the same alphabetical order

Furthermore, multiple variables can be extracted from a struct using the destructuring syntax.

### Struct Memory Layout

> **Note**
> This information is not vital if you are new to the language, or programming in general

Structs have zero memory overhead. What that means is that in memory, each struct field is laid out sequentially. No metadata regarding the struct's name or other properties is preserved at runtime. In other words, structs are compile-time constructs. This is the same in Rust, but different in other languages with runtimes like Java.

## Tuples

<!-- This section should explain what tuples are and how to access tuple values -->
<!-- tuples:example:start -->
Tuples are a [basic static-length type](./built_in_types.md#tuple-types) which contain multiple different types within themselves. The type of a tuple is defined by the types of the values within it, and a tuple can contain basic types as well as structs and enums.

You can access values directly by using the `.` syntax. Moreover, multiple variables can be extracted from a tuple using the destructuring syntax.
<!-- tuples:example:end -->

```sway
library;

fn tuple() {
    // You can declare the types yourself
    let tuple1: (u8, bool, u64) = (100, false, 10000);

    // Or have the types be inferred
    let mut tuple2 = (5, true, ("Sway", 8));

    // Retrieve values from tuples
    let number = tuple1.0;
    let sway = tuple2.2.1;

    // Destructure the values from the tuple into variables
    let (n1, truthness, n2) = tuple1;

    // If you do not care about specific values then use "_"
    let (_, truthness, _) = tuple2;

    // Internally mutate the tuple
    tuple2.1 = false;

    // Or change the values all at once (must keep the same data types)
    tuple2 = (9, false, ("Fuel", 99));
}

```

## Enums

<!-- This section should explain what enums are -->
<!-- enums:example:start -->
_Enumerations_, or _enums_, are also known as _sum types_. An enum is a type that could be one of several variants. To declare an enum, you enumerate all potential variants.
<!-- enums:example:end -->

Here, we have defined five potential colors. Each enum variant is just the color name. As there is no extra data associated with each variant, we say that each variant is of type `()`, or unit.

```sway
library;

// Declare the enum
enum Color {
    Blue: (),
    Green: (),
    Red: (),
    Silver: (),
    Grey: (),
}

fn main() {
    // To instantiate a variable with the value of an enum the syntax is
    let blue = Color::Blue;
    let silver = Color::Silver;
}

```

### Enums of Structs

It is also possible to have an enum variant contain extra data. Take a look at this more substantial example, which combines struct declarations with enum variants:

```sway
library;

struct Item {
    price: u64,
    amount: u64,
    id: u64,
}

enum MyEnum {
    Item: Item,
}

fn main() {
    let my_enum = MyEnum::Item(Item {
        price: 5,
        amount: 2,
        id: 42,
    });
}

```

### Enums of Enums

It is possible to define enums of enums:

```sway
library;

pub enum Error {
    StateError: StateError,
    UserError: UserError,
}

pub enum StateError {
    Void: (),
    Pending: (),
    Completed: (),
}

pub enum UserError {
    InsufficientPermissions: (),
    Unauthorized: (),
}

```

#### Preferred usage

The preferred way to use enums is to use the individual (not nested) enums directly because they are easy to follow and the lines are short:

```sway
library;

use ::enum_of_enums::{StateError, UserError};

fn preferred() {
    let error1 = StateError::Void;
    let error2 = UserError::Unauthorized;
}

```

#### Inadvisable

If you wish to use the nested form of enums via the `Error` enum from the example above, then you can instantiate them into variables using the following syntax:

```sway
library;

use ::enum_of_enums::{Error, StateError, UserError};

fn avoid() {
    let error1 = Error::StateError(StateError::Void);
    let error2 = Error::UserError(UserError::Unauthorized);
}

```

Key points to note:

- You must import all of the enums you need instead of just the `Error` enum
- The lines may get unnecessarily long (depending on the names)
- The syntax is not the most ergonomic

### Enum Memory Layout

> **Note**
> This information is not vital if you are new to the language, or programming in general.

Enums do have some memory overhead. To know which variant is being represented, Sway stores a one-word (8-byte) tag for the enum variant. The space reserved after the tag is equivalent to the size of the _largest_ enum variant. So, to calculate the size of an enum in memory, add 8 bytes to the size of the largest variant. For example, in the case of `Color` above, where the variants are all `()`, the size would be 8 bytes since the size of the largest variant is 0 bytes.


---

### File: docs/sway/docs/book/src/basics/variables.md

# Variables

<!-- This section should explain how variables are immutable -->
<!-- immutable_vars:example:start -->
Variables in Sway are _immutable by default_. This means that, by default, once a variable is declared, its value cannot change. This is one of the ways how Sway encourages safe programming, and many modern languages have this same default.
<!-- immutable_vars:example:end -->

Let's take a look at variables in detail.

## Declaring a Variable

Let's look at a variable declaration:

```sway
let foo = 5;
```

Great! We have just declared a variable, `foo`. What do we know about `foo`?

1. It is immutable.
1. Its value is `5`.
1. Its type is `u64`, a 64-bit unsigned integer.

`u64` is the default numeric type, and represents a 64-bit unsigned integer. See the section [Built-in Types](./built_in_types.md) for more details.

We can also make a mutable variable. Let's take a look:

```sway
let mut foo = 5;
foo = 6;
```

Now, `foo` is mutable, and the reassignment to the number `6` is valid. That is, we are allowed to _mutate_ the variable `foo` to change its value.

When assigning to a mutable variable, the right-hand side of the assignment is evaluated before the left-hand side. In the below example, the mutable variable `i` will first be increased and the resulting value of `1` will be stored to `array[1]`, thus resulting in `array` being changed to `[0, 1, 0]`.

```sway
let mut array = [0, 0, 0];
let mut i = 0;

array[i] = {
    i += 1;
    i
};
```

## Type Annotations

<!-- This section should explain type annotations -->
<!-- type_annotations:example:start -->
A variable declaration can contain a _type annotation_. A type annotation serves the purpose of declaring the type, in addition to the value, of a variable.
<!-- type_annotations:example:end -->

Let's take a look:

```sway
let foo: u32 = 5;
```

We have just declared the _type_ of the variable `foo` as a `u32`, which is an unsigned 32-bit integer. Let's take a look at a few other type annotations:

```sway
let bar: str[4] = __to_str_array("sway");
let baz: bool = true;
```

<!-- This section should explain what happens if there is a type conflict -->
<!-- type_conflict:example:start -->
If the value declared cannot be assigned to the declared type, there will be an error generated by the compiler.
<!-- type_conflict:example:end -->


---

### File: docs/sway/docs/book/src/blockchain-development/access_control.md

# Access Control

<!-- This section should explain access control in Sway -->
<!-- access_control:example:start -->
Smart contracts require the ability to restrict access to and identify certain users or contracts. Unlike account-based blockchains, transactions in UTXO-based blockchains (i.e. Fuel) do not necessarily have a unique transaction sender. Additional logic is needed to handle this difference, and is provided by the standard library.
<!-- access_control:example:end -->

## `msg_sender`

<!-- This section should explain what the `msg_sender` method is -->
<!-- msg_sender:example:start -->
To deliver an experience akin to the EVM's access control, the `std` library provides a `msg_sender` function, which identifies a unique caller based upon the call and/or transaction input data.
<!-- msg_sender:example:end -->

```sway
contract;

abi MyOwnedContract {
    fn receive(field_1: u64) -> bool;
}

const OWNER = Address::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);

impl MyOwnedContract for Contract {
    fn receive(field_1: u64) -> bool {
        let sender = msg_sender().unwrap();
        if let Identity::Address(addr) = sender {
            assert(addr == OWNER);
        } else {
            revert(0);
        }

        true
    }
}

```

<!-- This section should explain how the `msg_sender` method works -->
<!-- msg_sender_details:example:start -->
The `msg_sender` function works as follows:

- If the caller is a contract, then `Ok(Sender)` is returned with the `ContractId` sender variant.
- If the caller is external (i.e. from a script), then all coin input owners in the transaction are checked. If all owners are the same, then `Ok(Sender)` is returned with the `Address` sender variant.
- If the caller is external and coin input owners are different, then the caller cannot be determined and a `Err(AuthError)` is returned.
<!-- msg_sender_details:example:end -->

## Contract Ownership

Many contracts require some form of ownership for access control. The [SRC-5 Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) has been defined to provide an interoperable interface for ownership within contracts.

To accomplish this, use the [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html) to keep track of the owner. This allows setting and revoking ownership using the variants `Some(..)` and `None` respectively. This is better, safer, and more readable than using the `Identity` type directly where revoking ownership has to be done using some magic value such as `b256::zero()` or otherwise.

- The following is an example of how to properly lock a function such that only the owner may call a function:

```sway
    #[storage(read)]
    fn only_owner() {
        storage.owner.only_owner();
        // Do stuff here
    }
```

Setting ownership can be done in one of two ways; During compile time or run time.

- The following is an example of how to properly set ownership of a contract during compile time:

```sway
storage {
    owner: Ownership = Ownership::initialized(Identity::Address(Address::zero())),
}
```

- The following is an example of how to properly set ownership of a contract during run time:

```sway
    #[storage(write)]
    fn set_owner(identity: Identity) {
        storage.owner.set_ownership(identity);
    }
```

- The following is an example of how to properly revoke ownership of a contract:

```sway
    #[storage(write)]
    fn revoke_ownership() {
        storage.owner.renounce_ownership();
    }
```

- The following is an example of how to properly retrieve the state of ownership:

```sway
    #[storage(read)]
    fn owner() -> State {
        storage.owner.owner()
    }
```

## Access Control Libraries

[Sway-Libs](../reference/sway_libs.md) provides the following libraries to enable further access control.

- [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html); used to apply restrictions on functions such that only a **single** user may call them. This library provides helper functions for the [SRC-5; Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md).
- [Admin Library](https://fuellabs.github.io/sway-libs/book/admin/index.html); used to apply restrictions on functions such that only a select few users may call them like a whitelist.
- [Pausable Library](https://fuellabs.github.io/sway-libs/book/pausable/index.html); allows contracts to implement an emergency stop mechanism.
- [Reentrancy Guard Library](https://fuellabs.github.io/sway-libs/book/reentrancy/index.html); used to detect and prevent reentrancy attacks.


---

### File: docs/sway/docs/book/src/blockchain-development/calling_contracts.md

# Calling Contracts

Smart contracts can be _called_ by other contracts or scripts. In the FuelVM, this is done primarily with the [`call`](https://fuellabs.github.io/fuel-specs/master/vm/instruction_set#call-call-contract) instruction.

Sway provides a nice way to manage callable interfaces with its ABI system. The Fuel ABI specification can be found [here](https://fuellabs.github.io/fuel-specs/master/protocol/abi).

## Example

Here is an example of a contract calling another contract in Sway. A script can call a contract in the same way.

```sway
// ./contract_a.sw
contract;

abi ContractA {
    fn receive(field_1: bool, field_2: u64) -> u64;
}

impl ContractA for Contract {
    fn receive(field_1: bool, field_2: u64) -> u64 {
        assert(field_1 == true);
        assert(field_2 > 0);
        return_45()
    }
}

fn return_45() -> u64 {
  45
}
```

```sway
// ./contract_b.sw
contract;

use contract_a::ContractA;

abi ContractB {
    fn make_call();
}

const contract_id = 0x79fa8779bed2f36c3581d01c79df8da45eee09fac1fd76a5a656e16326317ef0;

impl ContractB for Contract {
    fn make_call() {
      let x = abi(ContractA, contract_id);
      let return_value = x.receive(true, 3); // will be 45
    }
}
```

> **Note**: The ABI is for external calls only therefore you cannot define a method in the ABI and call it in the same contract. If you want to define a function for a contract, but keep it private so that only your contract can call it, you can define it outside of the `impl` and call it inside the contract, similar to the `return_45()` function above.

## Advanced Calls

All calls forward a gas stipend, and may additionally forward one native asset with the call.

Here is an example of how to specify the amount of gas (`gas`), the asset ID of the native asset (`asset_id`), and the amount of the native asset (`coins`) to forward:

```sway
script;

abi MyContract {
    fn foo(field_1: bool, field_2: u64);
}

fn main() {
    let x = abi(MyContract, 0x79fa8779bed2f36c3581d01c79df8da45eee09fac1fd76a5a656e16326317ef0);
    let asset_id = 0x7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777_7777;
    x.foo {
        gas: 5000, asset_id: asset_id, coins: 5000
    }
    (true, 3);
}
```

## Handling Re-entrancy

A common attack vector for smart contracts is [re-entrancy](https://docs.soliditylang.org/en/v0.8.4/security-considerations.html#re-entrancy). Similar to the EVM, the FuelVM allows for re-entrancy.

A _stateless_ re-entrancy guard is included in the [`sway-libs`](https://fuellabs.github.io/sway-libs/book/reentrancy/index.html) library. The guard will panic (revert) at run time if re-entrancy is detected.

```sway
contract;

use reentrancy::reentrancy_guard;

abi MyContract {
    fn some_method();
}

impl ContractB for Contract {
    fn some_method() {
        reentrancy_guard();
        // do something
    }
}
```

### CEI pattern violation static analysis

Another way of avoiding re-entrancy-related attacks is to follow the so-called
_CEI_ pattern. CEI stands for "Checks, Effects, Interactions", meaning that the
contract code should first perform safety checks, also known as
"pre-conditions", then perform effects, i.e. modify or read the contract storage
and execute external contract calls (interaction) only at the very end of the
function/method.

Please see this [blog post](https://fravoll.github.io/solidity-patterns/checks_effects_interactions.html)
for more detail on some vulnerabilities in case of storage modification after
interaction and this [blog post](https://chainsecurity.com/curve-lp-oracle-manipulation-post-mortem) for
more information on storage reads after interaction.

The Sway compiler implements a check that the CEI pattern is not violated in the
user contract and issues warnings if that's the case.

For example, in the following contract the CEI pattern is violated, because an
external contract call is executed before a storage write.

```sway
contract;

mod other_contract;

use other_contract::*;
use std::hash::*;

abi MyContract {
    #[storage(read, write)]
    fn withdraw(external_contract_id: ContractId);
}

storage {
    balances: StorageMap<Identity, u64> = StorageMap::<Identity, u64> {},
}

impl MyContract for Contract {
    #[storage(read, write)]
    fn withdraw(external_contract_id: ContractId) {
        let sender = msg_sender().unwrap();
        let bal = storage.balances.get(sender).try_read().unwrap_or(0);

        assert(bal > 0);

        // External call
        let caller = abi(OtherContract, external_contract_id.into());
        caller.external_call {
            coins: bal,
        }();

        // Storage update _after_ external call
        storage.balances.insert(sender, 0);
    }
}

```

Here, `other_contract` is defined as follows:

```sway
library;

abi OtherContract {
    #[payable]
    fn external_call();
}

```

The CEI pattern analyzer issues a warning as follows, pointing to the
interaction before a storage modification:

```sh
warning
  --> /path/to/contract/main.sw:28:9
   |
26 |
27 |           let caller = abi(OtherContract, external_contract_id.into());
28 |           caller.external_call { coins: bal }();
   |  _________-
29 | |
30 | |         // Storage update _after_ external call
31 | |         storage.balances.insert(sender, 0);
   | |__________________________________________- Storage write after external contract interaction in function or method "withdraw". Consider making all storage writes before calling another contract
32 |       }
33 |   }
   |
____
```

In case there is a storage read after an interaction, the CEI analyzer will issue a similar warning.

In addition to storage reads and writes after an interaction, the CEI analyzer reports analogous warnings about:

- balance tree updates, i.e. balance tree reads with subsequent writes, which may be produced by the `tr` and `tro` ASM instructions or library functions using them under the hood;
- balance trees reads with `bal` instruction;
- changes to the output messages that can be produced by the `__smo` intrinsic function or the `smo` ASM instruction.

## Differences from the EVM

While the Fuel contract calling paradigm is similar to the EVM's (using an ABI, forwarding gas and data), it differs in _two_ key ways:

1. [**Native assets**](./native_assets.md): FuelVM calls can forward any native asset not just base asset.

2. **No data serialization**: Contract calls in the FuelVM do not need to serialize data to pass it between contracts; instead they simply pass a pointer to the data. This is because the FuelVM has a shared global memory which all call frames can read from.

## Fallback

When a contract is compiled, a special section called "contract selection" is also generated. This section checks if the contract call method matches any of the available ABI methods. If this fails, one of two possible actions will happen:

1 - if no fallback function was specified, the contract will revert;
2 - otherwise, the fallback function will be called.

For all intents and purposes the fallback function is considered a contract method, which means that it has all the limitations that other contract methods have. As for the fallback function signature, the function cannot have arguments, but it can return anything.

If for some reason the fallback function needs to returns different types, the intrinsic `__contract_ret` can be used.

```sway
contract;

abi MyContract {
    fn some_method();
}

impl MyContract for Contract {
    fn some_method() {
    }
}

#[fallback]
fn fallback() {
}
```

You may still access the method selector and call arguments in the fallback function.
For instance, let's assume a function `fn foobar(bool, u64) {}` gets called on a contract that doesn't have it, with arguments `true` and `42`.
It can execute the following fallback:

```sway
#[fallback]
fn fallback() {
    // the method selector is the first four bytes of sha256("foobar(bool,u64)")
    // per https://fuellabs.github.io/fuel-specs/master/protocol/abi#function-selector-encoding
    let method_selector = std::call_frames::first_param::<u64>();

    // the arguments tuple is (true, 42)
    let arguments = std::call_frames::second_param::<(bool, u64)>();
}
```


---

### File: docs/sway/docs/book/src/blockchain-development/external_code.md

# External Code Execution

The `std-lib` includes a function called `run_external` that allows Sway contracts to execute arbitrary external Sway code.

This functionality enables features like upgradeable contracts and
proxies.

## Upgradeable Contracts

Upgradeable contracts are designed to allow the logic of a smart contract to be updated after deployment.

Consider this example proxy contract:

```sway
#[namespace(my_storage_namespace)]
storage {
    target_contract: Option<ContractId> = None,
}

impl Proxy for Contract {
    #[storage(write)]
    fn set_target_contract(id: ContractId) {
        storage.target_contract.write(Some(id));
    }

    #[storage(read)]
    fn double_input(_value: u64) -> u64 {
        let target = storage.target_contract.read().unwrap();
        run_external(target)
    }
}
```

The contract has two functions:

- `set_target_contract` updates the `target_contract` variable in storage with the `ContractId` of an external contract.
- `double_input` reads the `target_contract` from storage and uses it to run external code. If the `target_contract` has a function with the same name (`double_input`), the code in the external `double_input` function will run.
In this case, the function will return a `u64`.

Notice in the `Proxy` example above, the storage block has a `namespace` attribute. Using this attribute is considered a best practice for all proxy contracts in Sway, because it will prevent storage collisions with the implementation contract, as the implementation contract has access to both storage contexts.

Below is what an implementation contract could look like for this:

```sway
storage {
    value: u64 = 0,
    // to stay compatible, this has to stay the same in the next version
}

impl Implementation for Contract {
    #[storage(write)]
    fn double_input(value: u64) -> u64 {
        let new_value = value * 2;
        storage.value.write(new_value);
        new_value
    }
}
```

This contract has one function called `double_input`, which calculates the input value times two, updates the `value` variable in storage, and returns the new value.

## How does this differ from calling a contract?

There are a couple of major differences between calling a contract directly and using the `run_external` method.

First, to use `run_external`, the ABI of the external contract is not required. The proxy contract has no knowledge of the external contract except for its `ContractId`.

### Upgradeable Contract Storage

Second, the storage context of the proxy contract is retained for the loaded code.
This means that in the examples above, the `value` variable gets updated in the storage for the *proxy* contract.

For example, if you were to read the `value` variable by directly calling the implementation contract, you would get a different result than if you read it through the proxy contract.
The proxy contract loads the code and executes it in its own context.

## Fallback functions

If the function name doesn't exist in the target contract but a `fallback` function does, the `fallback` function will be triggered.

> If there is no fallback function, the transaction will revert.

You can access function parameters for fallback functions using the `call_frames` module in the `std-lib`.
For example, to access the `_foo` input parameter in the proxy function below, you can use the `called_args` method in the `fallback` function:

```sway
    fn does_not_exist_in_the_target(_foo: u64) -> u64 {
        run_external(TARGET)
    }
```

```sway
#[fallback]
fn fallback() -> u64 {
    use std::call_frames::*;
    __log(3);
    __log(called_method());
    __log("double_value");
    __log(called_method() == "double_value");
    let foo = called_args::<u64>();
    foo * 3
}
```

In this case, the `does_not_exist_in_the_target` function will return `_foo * 3`.

## Limitations

Some limitations of `run_external` function are:

- It can only be used with other contracts. Scripts, predicates, and library code cannot be run externally.
- If you change the implementation contract, you must maintain the same order of previous storage variables and types, as this is what has been stored in the proxy storage.
- You can't use the call stack in another call frame before you use `run_external`. You can only use the call stack within the call frame that contains `run_external`.


---

### File: docs/sway/docs/book/src/blockchain-development/hashing_and_cryptography.md

# Hashing and Cryptography

The Sway standard library provides easy access to a selection of cryptographic hash functions (`sha256` and EVM-compatible `keccak256`), and EVM-compatible `secp256k1`-based signature recovery operations.

## Hashing

```sway
script;

use std::hash::*;

impl Hash for Location {
    fn hash(self, ref mut state: Hasher) {
        match self {
            Location::Earth => {
                0_u8.hash(state);
            }
            Location::Mars => {
                1_u8.hash(state);
            }
        }
    }
}

impl Hash for Stats {
    fn hash(self, ref mut state: Hasher) {
        self.strength.hash(state);
        self.agility.hash(state);
    }
}

impl Hash for Person {
    fn hash(self, ref mut state: Hasher) {
        self.name.hash(state);
        self.age.hash(state);
        self.alive.hash(state);
        self.location.hash(state);
        self.stats.hash(state);
        self.some_tuple.hash(state);
        self.some_array.hash(state);
        self.some_b256.hash(state);
    }
}

const VALUE_A = 0x9280359a3b96819889d30614068715d634ad0cf9bba70c0f430a8c201138f79f;

enum Location {
    Earth: (),
    Mars: (),
}

struct Person {
    name: str,
    age: u64,
    alive: bool,
    location: Location,
    stats: Stats,
    some_tuple: (bool, u64),
    some_array: [u64; 2],
    some_b256: b256,
}

struct Stats {
    strength: u64,
    agility: u64,
}

fn main() {
    let zero = b256::min();
    // Use the generic sha256 to hash some integers
    let sha_hashed_u8 = sha256(u8::max());
    let sha_hashed_u16 = sha256(u16::max());
    let sha_hashed_u32 = sha256(u32::max());
    let sha_hashed_u64 = sha256(u64::max());

    // Or hash a b256
    let sha_hashed_b256 = sha256(VALUE_A);

    // You can hash booleans too
    let sha_hashed_bool = sha256(true);

    // Strings are not a problem either
    let sha_hashed_str = sha256("Fastest Modular Execution Layer!");

    // Tuples of any size work too
    let sha_hashed_tuple = sha256((true, 7));

    // As do arrays
    let sha_hashed_array = sha256([4, 5, 6]);

    // Enums work too
    let sha_hashed_enum = sha256(Location::Earth);

    // Complex structs are not a problem
    let sha_hashed_struct = sha256(Person {
        name: "John",
        age: 9000,
        alive: true,
        location: Location::Mars,
        stats: Stats {
            strength: 10,
            agility: 9,
        },
        some_tuple: (true, 8),
        some_array: [17, 76],
        some_b256: zero,
    });

    log(sha_hashed_u8);
    log(sha_hashed_u16);
    log(sha_hashed_u32);
    log(sha_hashed_u64);
    log(sha_hashed_b256);
    log(sha_hashed_bool);
    log(sha_hashed_str);
    log(sha_hashed_tuple);
    log(sha_hashed_array);
    log(sha_hashed_enum);
    log(sha_hashed_struct);

    // Use the generic keccak256 to hash some integers
    let keccak_hashed_u8 = keccak256(u8::max());
    let keccak_hashed_u16 = keccak256(u16::max());
    let keccak_hashed_u32 = keccak256(u32::max());
    let keccak_hashed_u64 = keccak256(u64::max());

    // Or hash a b256
    let keccak_hashed_b256 = keccak256(VALUE_A);

    // You can hash booleans too
    let keccak_hashed_bool = keccak256(true);

    // Strings are not a problem either
    let keccak_hashed_str = keccak256("Fastest Modular Execution Layer!");

    // Tuples of any size work too
    let keccak_hashed_tuple = keccak256((true, 7));

    // As do arrays
    let keccak_hashed_array = keccak256([4, 5, 6]);

    // Enums work too
    let keccak_hashed_enum = keccak256(Location::Earth);

    // Complex structs are not a problem
    let keccak_hashed_struct = keccak256(Person {
        name: "John",
        age: 9000,
        alive: true,
        location: Location::Mars,
        stats: Stats {
            strength: 10,
            agility: 9,
        },
        some_tuple: (true, 8),
        some_array: [17, 76],
        some_b256: zero,
    });

    log(keccak_hashed_u8);
    log(keccak_hashed_u16);
    log(keccak_hashed_u32);
    log(keccak_hashed_u64);
    log(keccak_hashed_b256);
    log(keccak_hashed_bool);
    log(keccak_hashed_str);
    log(keccak_hashed_tuple);
    log(keccak_hashed_array);
    log(keccak_hashed_enum);
    log(keccak_hashed_struct);
}

```

## Cryptographic Signature Recovery and Verification

Fuel supports 3 asymmetric cryptographic signature schemes; `Secp256k1`, `Secp256r1`, and `Ed25519`.

### Public Key Recovery

Given a `Signature` and a sign `Message`, you can recover a `PublicKey`.

```sway
    // Secp256rk1 Public Key Recovery
    let secp256k1_signature: Signature = Signature::Secp256k1(Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    )));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A recovered public key pair.
    let secp256k1_public_key = secp256k1_signature.recover(signed_message);
    assert(secp256k1_public_key.is_ok());
    assert(
        secp256k1_public_key
            .unwrap() == PublicKey::from((
            0x41a55558a3486b6ee3878f55f16879c0798afd772c1506de44aba90d29b6e65c,
            0x341ca2e0a3d5827e78d838e35b29bebe2a39ac30b58999e1138c9467bf859965,
        )),
    );

    // Secp256r1 Public Key Recovery
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876712afadbff382e1bf31c44437823ed761cc3600d0016de511ac,
        0x44ac566bd156b4fc71a4a4cb2655d3da360c695edb27dc3b64d621e122fea23d,
    )));
    let signed_message = Message::from(0x1e45523606c96c98ba970ff7cf9511fab8b25e1bcd52ced30b81df1e4a9c4323);
    // A recovered public key pair.
    let secp256r1_public_key = secp256r1_signature.recover(signed_message);
    assert(secp256r1_public_key.is_ok());
    assert(
        secp256r1_public_key
            .unwrap() == PublicKey::from((
            0xd6ea577a54ae42411fbc78d686d4abba2150ca83540528e4b868002e346004b2,
            0x62660ecce5979493fe5684526e8e00875b948e507a89a47096bc84064a175452,
        )),
    );
```

### Signed Message Address Recovery

Given a `Signature` and signed `Message`, you can recover a Fuel `Address`.

```sway
    // Secp256k1 Address Recovery
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    )));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A recovered Fuel address.
    let secp256k1_address = secp256k1_signature.address(signed_message);
    assert(secp256k1_address.is_ok());
    assert(
        secp256k1_address
            .unwrap() == Address::from(0x02844f00cce0f608fa3f0f7408bec96bfd757891a6fda6e1fa0f510398304881),
    );

    // Secp256r1 Address Recovery
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876713afa8bf3383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A recovered Fuel address.
    let secp256r1_address = secp256r1_signature.address(signed_message);
    assert(secp256r1_address.is_ok());
    assert(
        secp256r1_address
            .unwrap() == Address::from(0xb4a5fabee8cc852084b71f17107e9c18d682033a58967027af0ab01edf2f9a6a),
    );

```

#### Signed Message EVM Address Recovery

Recovery of EVM addresses is also supported.

```sway
    // Secp256k1 EVM Address Recovery
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A recovered EVM address.
    let secp256k1_evm_address = secp256k1_signature.evm_address(signed_message);
    assert(secp256k1_evm_address.is_ok());
    assert(
        secp256k1_evm_address
            .unwrap() == EvmAddress::from(0x0000000000000000000000000ec44cf95ce5051ef590e6d420f8e722dd160ecb),
    );

    // Secp256r1 EVM Address Recovery
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0x62CDC20C0AB6AA7B91E63DA9917792473F55A6F15006BC99DD4E29420084A3CC,
        0xF4D99AF28F9D6BD96BDAAB83BFED99212AC3C7D06810E33FBB14C4F29B635414,
    )));
    let signed_message = Message::from(0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563);
    // A recovered EVM address.
    let secp256r1_evm_address = secp256r1_signature.evm_address(signed_message);
    assert(secp256r1_evm_address.is_ok());
    assert(
        secp256r1_evm_address
            .unwrap() == EvmAddress::from(0x000000000000000000000000408eb2d97ef0beda0a33848d9e052066667cb00a),
    );
```

### Public Key Signature Verification

Given a `Signature`, `PublicKey`, and `Message`, you can verify that the message was signed using the public key.

```sway
    // Secp256k1 Signature Verification
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    )));
    let secp256k1_public_key = PublicKey::from((
        0x41a55558a3486b6ee3878f55f16879c0798afd772c1506de44aba90d29b6e65c,
        0x341ca2e0a3d5827e78d838e35b29bebe2a39ac30b58999e1138c9467bf859965,
    ));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A verified public key
    let secp256k1_verified = secp256k1_signature.verify(secp256k1_public_key, signed_message);
    assert(secp256k1_verified.is_ok());

    // Secp256r1 Signature Verification
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876712afadbff382e1bf31c44437823ed761cc3600d0016de511ac,
        0x44ac566bd156b4fc71a4a4cb2655d3da360c695edb27dc3b64d621e122fea23d,
    )));
    let secp256r1_public_key = PublicKey::from((
        0xd6ea577a54ae42411fbc78d686d4abba2150ca83540528e4b868002e346004b2,
        0x62660ecce5979493fe5684526e8e00875b948e507a89a47096bc84064a175452,
    ));
    let signed_message = Message::from(0x1e45523606c96c98ba970ff7cf9511fab8b25e1bcd52ced30b81df1e4a9c4323);
    // A verified public key 
    let secp256r1_verified = secp256r1_signature.verify(secp256r1_public_key, signed_message);
    assert(secp256r1_verified.is_ok());

    // Ed25519 Signature Verification
    let ed25519_public_key = PublicKey::from(0x314fa58689bbe1da2430517de2d772b384a1c1d2e9cb87e73c6afcf246045b10);
    let ed25519_signature = Signature::Ed25519(Ed25519::from((
        0xf38cef9361894be6c6e0eddec28a663d099d7ddff17c8077a1447d7ecb4e6545,
        0xf5084560039486d3462dd65a40c80a74709b2f06d450ffc5dc00345c6b2cdd00,
    )));
    let hashed_message = Message::from(sha256(b256::zero()));
    // A verified public key  
    let ed25519_verified = ed25519_signature.verify(ed25519_public_key, hashed_message);
    assert(ed25519_verified.is_ok());
```

### Address Signature Verification

Given a `Signature`, `Address`, and `Message`, you can verify that the message was signed by the address.

```sway
    // Secp256k1 Address Verification
    let secp256k1_address = Address::from(0x02844f00cce0f608fa3f0f7408bec96bfd757891a6fda6e1fa0f510398304881);
    let secp256k1_signature = Secp256k1::from((
        0x61f3caf4c0912cec69ff0b226638d397115c623a7f057914d48a7e4daf1cf6d8,
        0x2555de81cd3a40382d3d64eb1c77e463eea5a76d65ec85f283e0b3d568352678,
    ));
    let signed_message = Message::from(0xa13f4ab54057ce064d3dd97ac3ff30ed704e73956896c03650fe59b1a561fe15);
    // A verified address
    let secp256k1_verified = secp256k1_signature.verify_address(secp256k1_address, signed_message);
    assert(secp256k1_verified.is_ok());

    // Secp256r1 Address Verification
    let secp256r1_address = Address::from(0xb4a5fabee8cc852084b71f17107e9c18d682033a58967027af0ab01edf2f9a6a);
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0xbd0c9b8792876713afa8bf3383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A verified address
    let secp256r1_verified = secp256r1_signature.verify_address(secp256r1_address, signed_message);
    assert(secp256r1_verified.is_ok());

```

#### EVM Address Signature Verification

Recovery of EVM addresses verification is also supported.

```sway
    // Secp256k1 Address Verification
    let secp256k1_evm_address = EvmAddress::from(0x0000000000000000000000000ec44cf95ce5051ef590e6d420f8e722dd160ecb);
    let secp256k1_signature = Signature::Secp256k1(Secp256k1::from((
        0xbd0c9b8792876713afa8bff383eebf31c43437823ed761cc3600d0016de5110c,
        0x44ac566bd156b4fc71a4a4cb2655d3dd360c695edb17dc3b64d611e122fea23d,
    )));
    let signed_message = Message::from(0xee45573606c96c98ba970ff7cf9511f1b8b25e6bcd52ced30b89df1e4a9c4323);
    // A recovered EVM address.
    let secp256k1_verified = secp256k1_signature.verify_evm_address(secp256k1_evm_address, signed_message);
    assert(secp256k1_verified.is_ok());

    // Secp256r1 Address Verification
    let secp256r1_evm_address = EvmAddress::from(0x000000000000000000000000408eb2d97ef0beda0a33848d9e052066667cb00a);
    let secp256r1_signature = Signature::Secp256r1(Secp256r1::from((
        0x62CDC20C0AB6AA7B91E63DA9917792473F55A6F15006BC99DD4E29420084A3CC,
        0xF4D99AF28F9D6BD96BDAAB83BFED99212AC3C7D06810E33FBB14C4F29B635414,
    )));
    let signed_message = Message::from(0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563);
    // A recovered EVM address.
    let secp256r1_verified = secp256r1_signature.verify_evm_address(secp256r1_evm_address, signed_message);
    assert(secp256r1_verified.is_ok());
```


---

### File: docs/sway/docs/book/src/blockchain-development/identifiers.md

# Identifiers

Addresses in Sway are similar to EVM addresses. The two major differences are:

1. Sway addresses are 32 bytes long (instead of 20)
2. Sway addresses are computed with the SHA-256 hash of the public key instead of the keccak-256 hash.

Contracts, on the other hand, are uniquely identified with a contract ID rather than an address. A contract's ID is also 32 bytes long and is calculated [here](https://fuellabs.github.io/fuel-specs/master/protocol/id/contract).


---

### File: docs/sway/docs/book/src/blockchain-development/index.md

# Blockchain Development with Sway

Sway is fundamentally a blockchain language. Because of this, it has some features and requirements that you may not have seen in general-purpose programming languages.

These are also some concepts related to the FuelVM and Fuel ecosystem that you may utilize when writing Sway.

- [Hashing and Cryptography](./hashing_and_cryptography.md)
- [Contract Storage](./storage.md)
- [Function Purity](./purity.md)
- [Identifiers](./identifiers.md)
- [Native Assets](./native_assets.md)
- [Access Control](./access_control.md)
- [Calling Contracts](./calling_contracts.md)
- [External Code Execution](./external_code.md)


---

### File: docs/sway/docs/book/src/blockchain-development/native_assets.md

# Native Assets

<!-- This section should explain native assets in Sway -->
<!-- native_assets:example:start -->
The FuelVM has built-in support for working with multiple assets.

## Key Differences Between EVM and FuelVM Assets

### ERC-20 vs Native Asset

On the EVM, Ether is the native asset. As such, sending ETH to an address or contract is an operation built into the EVM, meaning it doesn't rely on the existence of a smart contract to update balances to track ownership as with ERC-20 tokens.

On the FuelVM, _all_ assets are native and the process for sending _any_ native asset is the same.

While you would still need a smart contract to handle the minting and burning of assets, the sending and receiving of these assets can be done independently of the asset contract.

Just like the EVM however, Fuel has a standard that describes a standard API for Native Assets using the Sway Language. The ERC-20 equivalent for the Sway Language is the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md).

> **NOTE** It is important to note that Fuel does not have tokens.

### ERC-721 vs Native Asset

On the EVM, an ERC-721 token or NFT is a contract that contains multiple tokens which are non-fungible with one another.

On the FuelVM, the ERC-721 equivalent is a Native Asset where each asset has a supply of one. This is defined in the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md#non-fungible-asset-restrictions) under the Non-Fungible Asset Restrictions.

In practice, this means all NFTs are treated the same as any other Native Asset on Fuel. When writing Sway code, no additional cases for handling non-fungible and fungible assets are required.

### No Token Approvals

An advantage Native Assets bring is that there is no need for token approvals; as with Ether on the EVM. With millions of dollars hacked every year due to misused token approvals, the FuelVM eliminates this attack vector.

### Asset vs Coin vs Token

An "Asset" is a Native Asset on Fuel and has the associated `AssetId` type. Assets are distinguishable from one another. A "Coin" represents a singular unit of an Asset. Coins of the same Asset are not distinguishable from one another.

Fuel does not use tokens like other ecosystems such as Ethereum and uses Native Assets with a UTXO design instead.

## The `AssetId` type

The `AssetId` type represents any Native Asset on Fuel. An `AssetId` is used for interacting with an asset on the network.

The `AssetId` of any Native Asset on Fuel is calculated by taking the SHA256 hash digest of the originating `ContractId` that minted the asset and a `SubId` i.e. `sha256((contract_id, sub_id))`.

### Creating a New `AssetId`

There are 3 ways to instantiate a new `AssetId`:

#### Default

When a contract will only ever mint a single asset, it is recommended to use the `DEFAULT_ASSET_ID` sub id. This is referred to as the default asset of a contract.

To get the default asset from an internal contract call, call the `default()` function:

```sway
    let asset_id: AssetId = AssetId::default();
```

#### New

If a contract mints multiple assets or if the asset has been minted by an external contract, the `new()` function will be needed. The `new()` function takes the `ContractId` of the contract which minted the token as well as a `SubId`.

To create a new `AssetId` using a `ContractId` and `SubId`, call the `new()` function:

```sway
    let my_contract_id: ContractId = ContractId::from(0x1000000000000000000000000000000000000000000000000000000000000000);
    let my_sub_id: SubId = 0x2000000000000000000000000000000000000000000000000000000000000000;

    let asset_id: AssetId = AssetId::new(my_contract_id, my_sub_id);
```

#### From

In the case where the `b256` value of an asset is already known, you may call the `from()` function with the `b256` value.

```sway
    let asset_id: AssetId = AssetId::from(0x0000000000000000000000000000000000000000000000000000000000000000);
```

## The `SubId` type

The SubId is used to differentiate between different assets that are created by the same contract. The `SubId` is a `b256` value.

When creating a single new asset on Fuel, we recommend using the `DEFAULT_SUB_ID` or `SubId::zero()`.

## The Base Asset

On the Fuel Network, the base asset is Ether. This is the only asset on the Fuel Network that does not have a `SubId`.

The Base Asset can be returned anytime by calling the `base()` function of the `AssetId` type.

```sway
    let base_asset: AssetId = AssetId::base();
```

## Basic Native Asset Functionality

### Minting A Native Asset

To mint a new asset, the `std::asset::mint()` function must be called internally within a contract. A `SubId` and amount of coins must be provided. These newly minted coins will be owned by the contract which minted them. To mint another asset from the same contract, replace the `DEFAULT_SUB_ID` with your desired `SubId`.

```sway
        mint(DEFAULT_SUB_ID, mint_amount);
```

You may also mint an asset to a specific entity with the `std::asset::mint_to()` function. Be sure to provide a target `Identity` that will own the newly minted coins.

```sway
        mint_to(target_identity, DEFAULT_SUB_ID, mint_amount);
```

If you intend to allow external users to mint assets using your contract, the [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md#fn-mintrecipient-identity-vault_sub_id-subid-amount-u64) defines a standard API for minting assets. The [Sway-Libs Asset Library](https://fuellabs.github.io/sway-libs/book/asset/supply.html) also provides an additional library to support implementations of the SRC-3 Standard into your contract.

### Burning a Native Asset

To burn an asset, the `std::asset::burn()` function must be called internally from the contract which minted them. The `SubId` used to mint the coins and amount must be provided. The burned coins must be owned by the contract. When an asset is burned it doesn't exist anymore.

```sway
        burn(DEFAULT_SUB_ID, burn_amount);
```

If you intend to allow external users to burn assets using your contract, the [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md#fn-mintrecipient-identity-vault_sub_id-subid-amount-u64) defines a standard API for burning assets. The [Sway-Libs Asset Library](https://fuellabs.github.io/sway-libs/book/asset/supply.html) also provides an additional library to support implementations of the SRC-3 Standard into your contract.

### Transfer a Native Asset

To internally transfer a Native Asset, the `std::asset::transfer()` function must be called. A target `Identity` or user must be provided as well as the `AssetId` of the asset and an amount.

```sway
        transfer(target, asset_id, coins);
```

### Native Asset And Transactions

#### Getting The Transaction Asset

To query for the Native Asset sent in a transaction, you may call the `std::call_frames::msg_asset_id()` function.

```sway
        let amount = msg_asset_id();
```

#### Getting The Transaction Amount

To query for the amount of coins sent in a transaction, you may call the `std::context::msg_amount()` function.

```sway
        let amount = msg_amount();
```

### Native Assets and Contracts

#### Checking A Contract's Balance

To internally check a contract's balance, call the `std::context::this_balance()` function with the corresponding `AssetId`.

```sway
        this_balance(asset_id)
```

To check the balance of an external contract, call the `std::context::balance_of()` function with the corresponding `AssetId`.

```sway
        balance_of(target_contract, asset_id)
```

> **NOTE** Due to the FuelVM's UTXO design, balances of `Address`'s cannot be returned in the Sway Language. This must be done off-chain using the SDK.

#### Receiving Native Assets In A Contract

By default, a contract may not receive a Native Asset in a contract call. To allow transferring of assets to the contract, add the `#[payable]` attribute to the function.

```sway
    #[payable]
    fn deposit() {
        assert(msg_amount() > 0);
    }
```

## Native Asset Standards

There are a number of standards developed to enable further functionality for Native Assets and help cross contract functionality. Information on standards can be found in the [Sway Standards Repo](https://github.com/FuelLabs/sway-standards).

We currently have the following standards for Native Assets:

- [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md) defines the implementation of a standard API for Native Assets using the Sway Language.
- [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md) is used to enable mint and burn functionality for Native Assets.
- [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) is used to store metadata for Native Assets.
- [SRC-6; Vault Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-6-vault.md) defines the implementation of a standard API for asset vaults developed in Sway.

## Native Asset Libraries

Additional Libraries have been developed to allow you to quickly create an deploy dApps that follow the [Sway Standards](https://github.com/FuelLabs/sway-standards).

- [Asset Library](https://fuellabs.github.io/sway-libs/book/asset/index.html) provides functionality to implement the [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3; Mint and Burn Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) standards.

<!-- native_assets:example:end -->

## Single Native Asset Example

In this fully fleshed out example, we show a native asset contract which mints a single asset. This is the equivalent to the ERC-20 Standard use in Ethereum. Note there are no token approval functions.

It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-5; Ownership](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) standards. It does not use any external libraries.

```sway
// ERC20 equivalent in Sway.
contract;

use standards::{
    src3::SRC3,
    src5::{
        SRC5, 
        State, 
        AccessError,
    },
    src20::{
        SetDecimalsEvent, 
        SetNameEvent, 
        SetSymbolEvent, 
        SRC20, 
        TotalSupplyEvent,
    },
};
use std::{
    asset::{
        burn,
        mint_to,
    },
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    string::String,
    contract_id::ContractId
};

configurable {
    DECIMALS: u8 = 9u8,
    NAME: str[7] = __to_str_array("MyAsset"),
    SYMBOL: str[5] = __to_str_array("MYTKN"),
}

storage {
    total_supply: u64 = 0,
    owner: State = State::Uninitialized,
}

// Native Asset Standard
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        1
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        if asset == AssetId::default() {
            Some(storage.total_supply.read())
        } else {
            None
        }
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(NAME)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        if asset == AssetId::default() {
            Some(String::from_ascii_str(from_str_array(SYMBOL)))
        } else {
            None
        }
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        if asset == AssetId::default() {
            Some(DECIMALS)
        } else {
            None
        }
    }
}

// Ownership Standard
impl SRC5 for Contract {
    #[storage(read)]
    fn owner() -> State {
        storage.owner.read()
    }
}

// Mint and Burn Standard
impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        require(sub_id.is_some() && sub_id.unwrap() == DEFAULT_SUB_ID, "incorrect-sub-id");
        require_access_owner();

        let new_supply = storage.total_supply.read() + amount;
        storage
            .total_supply
            .write(new_supply);
        mint_to(recipient, DEFAULT_SUB_ID, amount);
        
        TotalSupplyEvent::new(
            AssetId::default(), 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }

    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        require(sub_id == DEFAULT_SUB_ID, "incorrect-sub-id");
        require(msg_amount() >= amount, "incorrect-amount-provided");
        require(
            msg_asset_id() == AssetId::default(),
            "incorrect-asset-provided",
        );
        require_access_owner();

        let new_supply = storage.total_supply.read() - amount;
        storage
            .total_supply
            .write(new_supply);
        burn(DEFAULT_SUB_ID, amount);
        
        TotalSupplyEvent::new(
            AssetId::default(), 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }
}

abi SingleAsset {
    #[storage(read, write)]
    fn constructor(owner_: Identity);
}

impl SingleAsset for Contract {
    #[storage(read, write)]
    fn constructor(owner_: Identity) {
        require(storage.owner.read() == State::Uninitialized, "owner-initialized");
        storage.owner.write(State::Initialized(owner_));
    }
}

#[storage(read)]
fn require_access_owner() {
    require(
        storage.owner.read() == State::Initialized(msg_sender().unwrap()),
        AccessError::NotOwner,
    );
}

abi EmitSRC20Events {
    fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
    fn emit_src20_events() {
        // Metadata that is stored as a configurable should only be emitted once.
        let asset = AssetId::default();
        let sender = msg_sender().unwrap();
        let name = Some(String::from_ascii_str(from_str_array(NAME)));
        let symbol = Some(String::from_ascii_str(from_str_array(SYMBOL)));

        SetNameEvent::new(asset, name, sender).log();
        SetSymbolEvent::new(asset, symbol, sender).log();
        SetDecimalsEvent::new(asset, DECIMALS, sender).log();
    }
}
```

## Multi Native Asset Example

In this fully fleshed out example, we show a native asset contract which mints multiple assets. This is the equivalent to the ERC-1155 Standard use in Ethereum. Note there are no token approval functions.

It implements the [SRC-20; Native Asset](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-5; Ownership](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) standards. It does not use any external libraries.

```sway
// ERC1155 equivalent in Sway.
contract;

use standards::{
    src5::{
        SRC5, 
        State, 
        AccessError
    },
    src20::{
        SetDecimalsEvent, 
        SetNameEvent, 
        SetSymbolEvent, 
        SRC20, 
        TotalSupplyEvent,
    }
    src3::SRC3,
};
use std::{
    asset::{
        burn,
        mint_to,
    },
    call_frames::msg_asset_id,
    hash::{
        Hash,
    },
    context::this_balance,
    storage::storage_string::*,
    string::String,
    contract_id::ContractId
};

storage {
    total_assets: u64 = 0,
    total_supply: StorageMap<AssetId, u64> = StorageMap {},
    name: StorageMap<AssetId, StorageString> = StorageMap {},
    symbol: StorageMap<AssetId, StorageString> = StorageMap {},
    decimals: StorageMap<AssetId, u8> = StorageMap {},
    owner: State = State::Uninitialized,
}

// Native Asset Standard
impl SRC20 for Contract {
    #[storage(read)]
    fn total_assets() -> u64 {
        storage.total_assets.read()
    }

    #[storage(read)]
    fn total_supply(asset: AssetId) -> Option<u64> {
        storage.total_supply.get(asset).try_read()
    }

    #[storage(read)]
    fn name(asset: AssetId) -> Option<String> {
        storage.name.get(asset).read_slice()
    }
    
    #[storage(read)]
    fn symbol(asset: AssetId) -> Option<String> {
        storage.symbol.get(asset).read_slice()
    }

    #[storage(read)]
    fn decimals(asset: AssetId) -> Option<u8> {
        storage.decimals.get(asset).try_read()
    }
}

// Mint and Burn Standard
impl SRC3 for Contract {
    #[storage(read, write)]
    fn mint(recipient: Identity, sub_id: Option<SubId>, amount: u64) {
        require(sub_id.is_some(), "Error: SubId is None");
        require_access_owner();

        let asset_id = AssetId::new(ContractId::this(), sub_id.unwrap());
        let supply = storage.total_supply.get(asset_id).try_read();
        if supply.is_none() {
            storage.total_assets.write(storage.total_assets.try_read().unwrap_or(0) + 1);
        }
        let new_supply = supply.unwrap_or(0) + amount;
        storage.total_supply.insert(asset_id, new_supply);
        mint_to(recipient, sub_id, amount);
        
        TotalSupplyEvent::new(
            asset_id, 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }
    
    #[storage(read, write)]
    fn burn(sub_id: SubId, amount: u64) {
        require_access_owner();
        let asset_id = AssetId::new(ContractId::this(), sub_id);
        require(this_balance(asset_id) >= amount, "not-enough-coins");
        
        let supply = storage.total_supply.get(asset_id).try_read();
        let new_supply = supply.unwrap_or(0) - amount;
        storage.total_supply.insert(asset_id, new_supply);
        burn(sub_id, amount);

        TotalSupplyEvent::new(
            asset_id, 
            new_supply, 
            msg_sender().unwrap()
        ).log();
    }
}

abi MultiAsset {
    #[storage(read, write)]
    fn constructor(owner_: Identity);
    
    #[storage(read, write)]
    fn set_name(asset: AssetId, name: Option<String>);

    #[storage(read, write)]
    fn set_symbol(asset: AssetId, symbol: Option<String>);

    #[storage(read, write)]
    fn set_decimals(asset: AssetId, decimals: u8);
}

impl MultiAsset for Contract {
    #[storage(read, write)]
    fn constructor(owner_: Identity) {
        require(storage.owner.read() == State::Uninitialized, "owner-initialized");
        storage.owner.write(State::Initialized(owner_));
    }
    
    #[storage(read, write)]
    fn set_name(asset: AssetId, name: Option<String>) {
        require_access_owner();
        storage.name.insert(asset, StorageString {});
        storage.name.get(asset).write_slice(name);

        SetNameEvent::new(asset, name, msg_sender().unwrap()).log();
    }

    #[storage(read, write)]
    fn set_symbol(asset: AssetId, symbol: Option<String>) {
        require_access_owner();
        storage.symbol.insert(asset, StorageString {});
        storage.symbol.get(asset).write_slice(symbol);

        SetSymbolEvent::new(asset, symbol, msg_sender().unwrap()).log();
    }

    #[storage(read, write)]
    fn set_decimals(asset: AssetId, decimals: u8) {
        require_access_owner();
        storage.decimals.insert(asset, decimals);

        SetDecimalsEvent::new(asset, decimals, msg_sender().unwrap()).log();
    }
}

#[storage(read)]
fn require_access_owner() {
    require(
        storage.owner.read() == State::Initialized(msg_sender().unwrap()),
        AccessError::NotOwner,
    );
}
```


---

### File: docs/sway/docs/book/src/blockchain-development/purity.md

# Purity

<!-- This section should explain pure functions in Sway -->
<!-- pure:example:start -->
A function is _pure_ if it does not access any [persistent storage](./storage.md). Conversely, the function is _impure_ if it does access any storage. Naturally, as storage is only available in smart contracts, impure functions cannot be used in predicates, scripts, or libraries. A pure function cannot call an impure function.

In Sway, functions are pure by default but can be opted into impurity via the `storage` function attribute. The `storage` attribute may take `read` and/or `write` arguments indicating which type of access the function requires.

The `storage` attribute without any arguments, `#[storage()]`, indicates a pure function, and has the same effect as not having the attribute at all.
<!-- pure:example:end -->

```sway
#[storage(read)]
fn get_amount() -> u64 {
    ...
}

#[storage(read, write)]
fn increment_amount(increment: u64) -> u64 {
    ...
}

fn a_pure_function() {
    ...
}

#[storage()]
fn also_a_pure_function() {
    ...
}
```

> **Note**: the `#[storage(write)]` attribute also permits a function to read from storage. This is due to the fact that partially writing a storage slot requires first reading the slot.

<!-- This section should explain impure functions in Sway -->
<!-- impure:example:start -->
Impure functions which call other impure functions must have at least the same storage privileges or a superset of those for the function called. For example, to call a function with write access a caller must also have write access, or both read and write access. To call a function with read and write access the caller must also have both privileges.
<!-- impure:example:end -->

The `storage` attribute may also be applied to [methods and associated functions](../basics/methods_and_associated_functions.md), [trait](../advanced/traits.md) and [ABI](../sway-program-types/smart_contracts.md#the-abi-declaration) declarations.

<!-- This section should explain the benefits of using pure functions in Sway -->
<!-- pure_benefits:example:start -->
A pure function gives you some guarantees: you will not incur excessive storage gas costs, the compiler can apply additional optimizations, and they are generally easy to reason about and audit.

> **Note**: Purity does not provide an absolute guarantee that a storage access will not happen as a result of calling a pure function. E.g., it is possible for a pure function to call another contract, which can then call a write function in the original contract. The guarantee that the purity gives in this example is, that the original pure function itself does not change the storage, as well as that any function later called, that accesses storage, is clearly marked as impure.
<!-- pure_benefits:example:end -->

[A similar concept exists in Solidity](https://docs.soliditylang.org/en/v0.8.10/contracts.html#pure-functions). Note that Solidity refers to contract storage as _contract state_, and in the Sway/Fuel ecosystem, these two terms are largely interchangeable.


---

### File: docs/sway/docs/book/src/blockchain-development/storage.md

# Storage

<!-- This section should explain storage in Sway -->
<!-- storage:example:start -->
When developing a [smart contract](../sway-program-types/smart_contracts.md), you will typically need some sort of persistent storage. In this case, persistent storage, often just called _storage_ in this context, is a place where you can store values that are persisted inside the contract itself. This is in contrast to a regular value in _memory_, which disappears after the contract exits.

Put in conventional programming terms, contract storage is like saving data to a hard drive. That data is saved even after the program that saved it exits. That data is persistent. Using memory is like declaring a variable in a program: it exists for the duration of the program and is non-persistent.

Some basic use cases of storage include declaring an owner address for a contract and saving balances in a wallet.
<!-- storage:example:end -->

## Storage Accesses Via the `storage` Keyword

Declaring variables in storage requires a `storage` block that contains a list of all your variables, their types, and their initial values. The initial value can be any expression that can be evaluated to a constant during compilation, as follows:

```sway
storage {
    var1: u64 = 1,
    var2: b256 = b256::zero(),
    var3: Address = Address::zero(),
    var4: Option<u8> = None,
}
```

To write into a storage variable, you need to use the `storage` keyword as follows:

```sway
        storage.var1.write(42);
        storage
            .var2
            .write(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .var3
            .write(Address::from(0x1111111111111111111111111111111111111111111111111111111111111111));
        storage.var4.write(Some(2u8));
```

To read a storage variable, you also need to use the `storage` keyword. You may use `read()` or `try_read()`, however we recommend using `try_read()` for additional safety.

```sway
        let var1: u64 = storage.var1.read();
        let var2: b256 = storage.var2.try_read().unwrap_or(b256::zero());
        let var3: Address = storage.var3.try_read().unwrap_or(Address::zero());
        let var4: Option<u8> = storage.var4.try_read().unwrap_or(None);
```

## Storing Structs

To store a struct in storage, each variable must be assigned in the `storage` block. This can be either my assigning the fields individually or using a public [constructor](../basics/methods_and_associated_functions.md#constructors) that can be evaluated to a constant during compilation.

```sway
struct Type1 {
    x: u64,
    y: u64,
}

struct Type2 {
    w: b256,
    z: bool,
}

impl Type2 {
    // a constructor that evaluates to a constant during compilation
    fn default() -> Self {
        Self {
            w: 0x0000000000000000000000000000000000000000000000000000000000000000,
            z: true,
        }
    }
}

storage {
    var1: Type1 = Type1 { x: 0, y: 0 },
    var2: Type2 = Type2::default(),
}
```

You may write to both fields of a struct and the entire struct as follows:

```sway
        // Store individual fields
        storage.var1.x.write(42);
        storage.var1.y.write(77);

        // Store an entire struct
        let new_struct = Type2 {
            w: 0x1111111111111111111111111111111111111111111111111111111111111111,
            z: false,
        };
        storage.var2.write(new_struct);
```

The same applies to reading structs from storage, where both the individual and struct as a whole may be read as follows:

```sway
        let var1_x: u64 = storage.var1.x.try_read().unwrap_or(0);
        let var1_y: u64 = storage.var1.y.try_read().unwrap_or(0);
        let var2: Type2 = storage.var2.try_read().unwrap_or(Type2::default());
```

## Common Storage Collections

We support the following common storage collections:

- `StorageMap<K, V>`
- `StorageVec<T>`
- `StorageBytes`
- `StorageString`

Please note that these types are not initialized during compilation. This means that if you try to access a key from a storage map before the storage has been set, for example, the call will revert.

Declaring these variables in storage requires a `storage` block as follows:

```sway
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
```

### `StorageMaps<K, V>`

Generic storage maps are available in the standard library as `StorageMap<K, V>` which have to be defined inside a `storage` block and allow you to call `insert()` and `get()` to insert values at specific keys and get those values respectively. Refer to [Storage Maps](../common-collections/storage_map.md) for more information about `StorageMap<K, V>`.

**Warning** While the `StorageMap<K, V>` is currently included in the prelude, to use it the `Hash` trait must still be imported. This is a known issue and will be resolved.

```sway
use std::hash::Hash;

// ANCHOR: storage_vec_import
use std::storage::storage_vec::*;
// ANCHOR: storage_vec_import

// ANCHOR: storage_bytes_import
use std::storage::storage_bytes::*;
// ANCHOR: storage_bytes_import

// ANCHOR: storage_string_import
use std::storage::storage_string::*;
// ANCHOR: storage_string_import

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

To write to a storage map, call either the `insert()` or `try_insert()` functions as follows:

```sway
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
```

The following demonstrates how to read from a storage map:

```sway
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
```

### `StorageVec<T>`

Generic storage vectors are available in the standard library as `StorageVec<T>` which have to be defined inside a `storage` block and allow you to call `push()` and `pop()` to push and pop values from a vector respectively. Refer to [Storage Vector](../common-collections/storage_vec.md) for more information about `StorageVec<T>`.

The following demonstrates how to import `StorageVec<T>`:

```sway
use std::storage::storage_vec::*;

// ANCHOR: storage_bytes_import
use std::storage::storage_bytes::*;
// ANCHOR: storage_bytes_import

// ANCHOR: storage_string_import
use std::storage::storage_string::*;
// ANCHOR: storage_string_import

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

> **NOTE**: When importing the `StorageVec<T>`, please be sure to use the glob operator: `use std::storage::storage_vec::*`.

The following demonstrates how to write to a `StorageVec<T>`:

```sway
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
```

The following demonstrates how to read from a `StorageVec<T>`:

```sway
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
```

### `StorageBytes`

Storage of `Bytes` is available in the standard library as `StorageBytes` which have to be defined inside a `storage` block. `StorageBytes` cannot be manipulated in the same way a `StorageVec<T>` or `StorageMap<K, V>` can but stores bytes more efficiently thus reducing gas. Only the entirety of a `Bytes` may be read/written to storage. This means any changes would require loading the entire `Bytes` to the heap, making changes, and then storing it once again. If frequent changes are needed, a `StorageVec<u8>` is recommended.

The following demonstrates how to import `StorageBytes`:

```sway
use std::storage::storage_bytes::*;

// ANCHOR: storage_string_import
use std::storage::storage_string::*;
// ANCHOR: storage_string_import

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

> **NOTE**: When importing the `StorageBytes`, please be sure to use the glob operator: `use std::storage::storage_bytes::*`.

The following demonstrates how to write to a `StorageBytes`:

```sway
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
```

The following demonstrates how to read from a `StorageBytes`:

```sway
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
```

### `StorageString`

Storage of `String` is available in the standard library as `StorageString` which have to be defined inside a `storage` block. `StorageString` cannot be manipulated in the same way a `StorageVec<T>` or `StorageMap<K, V>`. Only the entirety of a `String` may be read/written to storage.

The following demonstrates how to import `StorageString`:

```sway
use std::storage::storage_string::*;

// ANCHOR: advanced_storage_declaration
storage {
    storage_map: StorageMap<u64, bool> = StorageMap {},
    storage_vec: StorageVec<b256> = StorageVec {},
    storage_string: StorageString = StorageString {},
    storage_bytes: StorageBytes = StorageBytes {},
}
// ANCHOR_END: advanced_storage_declaration

abi StorageExample {
    #[storage(write)]
    fn store_map();
    #[storage(read)]
    fn get_map();
    #[storage(write)]
    fn store_vec();
    #[storage(read, write)]
    fn get_vec();
    #[storage(write)]
    fn store_string();
    #[storage(read)]
    fn get_string();
    #[storage(write)]
    fn store_bytes();
    #[storage(read)]
    fn get_bytes();
}

impl StorageExample for Contract {
    #[storage(write)]
    fn store_map() {
        // ANCHOR: map_storage_write
        storage.storage_map.insert(12, true);
        storage.storage_map.insert(59, false);

        // try_insert() will only insert if a value does not already exist for a key.
        let result = storage.storage_map.try_insert(103, true);
        assert(result.is_ok());
        // ANCHOR_END: map_storage_write
    }
    #[storage(read)]
    fn get_map() {
        // ANCHOR: map_storage_read
        // Access directly
        let stored_val1: bool = storage.storage_map.get(12).try_read().unwrap_or(false);

        // First get the storage key and then access the value.
        let storage_key2: StorageKey<bool> = storage.storage_map.get(59);
        let stored_val2: bool = storage_key2.try_read().unwrap_or(false);

        // Unsafely access the value.
        let stored_val3: bool = storage.storage_map.get(103).read();
        // ANCHOR_END: map_storage_read
    }

    #[storage(write)]
    fn store_vec() {
        // ANCHOR: vec_storage_write
        storage
            .storage_vec
            .push(0x1111111111111111111111111111111111111111111111111111111111111111);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000001);
        storage
            .storage_vec
            .push(0x0000000000000000000000000000000000000000000000000000000000000002);

        // Set will overwrite the element stored at the given index.
        storage.storage_vec.set(2, b256::zero());
        // ANCHOR_END: vec_storage_write
    }
    #[storage(read, write)]
    fn get_vec() {
        // ANCHOR: vec_storage_read
        // Method 1: Access the element directly
        // Note: get() does not remove the element from the vec.
        let stored_val1: b256 = storage.storage_vec.get(0).unwrap().try_read().unwrap_or(b256::zero());

        // Method 2: First get the storage key and then access the value.
        let storage_key2: StorageKey<b256> = storage.storage_vec.get(1).unwrap();
        let stored_val2: b256 = storage_key2.try_read().unwrap_or(b256::zero());

        // pop() will remove the last element from the vec.
        let length: u64 = storage.storage_vec.len();
        let stored_val3: b256 = storage.storage_vec.pop().unwrap();
        assert(length != storage.storage_vec.len());
        // ANCHOR_END: vec_storage_read
    }

    #[storage(write)]
    fn store_string() {
        // ANCHOR: string_storage_write
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
        // ANCHOR_END: string_storage_write
    }
    #[storage(read)]
    fn get_string() {
        // ANCHOR: string_storage_read
        let stored_string: String = storage.storage_string.read_slice().unwrap();
        // ANCHOR_END: string_storage_read
    }

    #[storage(write)]
    fn store_bytes() {
        // ANCHOR: bytes_storage_write
        // Setup Bytes
        let mut my_bytes = Bytes::new();
        my_bytes.push(1u8);
        my_bytes.push(2u8);
        my_bytes.push(3u8);

        // Write to storage
        storage.storage_bytes.write_slice(my_bytes);
        // ANCHOR_END: bytes_storage_write
    }
    #[storage(read)]
    fn get_bytes() {
        // ANCHOR: bytes_storage_read
        let stored_bytes: Bytes = storage.storage_bytes.read_slice().unwrap();
        // ANCHOR_END: bytes_storage_read
    }
}

```

> **NOTE**: When importing the `StorageString`, please be sure to use the glob operator: `use std::storage::storage_string::*`.

The following demonstrates how to write to a `StorageString`:

```sway
        let my_string = String::from_ascii_str("Fuel is blazingly fast");
        storage.storage_string.write_slice(my_string);
```

The following demonstrates how to read from a `StorageString`:

```sway
        let stored_string: String = storage.storage_string.read_slice().unwrap();
```

## Advanced Storage

For more advanced storage techniques please refer to the [Advanced Storage](../advanced/advanced_storage.md) page.


---

### File: docs/sway/docs/book/src/blockchain-development/time.md

# Time Library

The `std::time` library provides utilities for handling time durations and timestamps in Sway smart contracts.

## Duration

Represents a span of time in seconds.

### Creating Durations

```sway
fn create_durations() {
    // Using constants
    let zero = Duration::ZERO;
    let second = Duration::SECOND;
    let minute = Duration::MINUTE;
    let hour = Duration::HOUR;
    let day = Duration::DAY;
    let week = Duration::WEEK;

    // Using constructor methods
    let thirty_seconds = Duration::seconds(30);
    let two_hours = Duration::hours(2);
    let three_days = Duration::days(3);
}
```

### Converting Durations

Time `std::time` library supports conversion between different time scales such as `seconds`, `minutes`, `hours`, `days`, and `weeks`.

```sway
fn convert_durations() {
    let two_days = Duration::days(2);

    assert(two_days.as_seconds() == 172800); // 2 * 86400
    assert(two_days.as_minutes() == 2880); // 2 * 1440
    assert(two_days.as_hours() == 48); // 2 * 24
    assert(two_days.as_days() == 2);
    assert(two_days.as_weeks() == 0); // Truncated value
}
```

### Operations

The `std::time` supports operations on the `Duration` type.

```sway
fn duration_operations() {
    let day1 = Duration::DAY;
    let day2 = Duration::days(1);

    // Equality
    assert(day1 == day2);

    // Addition
    let two_days = day1 + day2;
    assert(two_days.as_days() == 2);

    // Subtraction
    let half_day = two_days - Duration::days(1).add(Duration::hours(12));
    assert(half_day.as_hours() == 12);

    // Comparison
    assert(Duration::MINUTE < Duration::HOUR);
}
```

## Time

Represents a UNIX timestamp (seconds since Jan 1, 1970).

### Creating Timestamps

There are 3 major ways to create a new timestamp.

```sway
fn create_timestamps() {
    // Current block time
    let now = Time::now();

    // Specific block time
    let block_time = Time::block(12345);

    // From UNIX timestamp
    let custom_time = Time::new(1672531200); // Jan 1, 2023 00:00:00 UTC
}
```

### Time Operations

Operations on the `Time` type are supported with conjunction of the `Duration` type.

```sway
fn time_operations() {
    let now = Time::now();
    let yesterday = now.subtract(Duration::DAY);
    let tomorrow = now.add(Duration::DAY);

    // Duration calculations
    let elapsed = now.duration_since(yesterday).unwrap();
    assert(elapsed.as_days() == 1);

    // Comparison
    assert(yesterday < now);
    assert(tomorrow > now);
}
```

### TAI64 Conversion

The Fuel VM internally uses TAI64 time. Conversions between UNIX and TAI64 are maintained with the `Time` type.

```sway
fn tai64_conversion() {
    let now = Time::now();

    // Convert to TAI64
    let tai64 = now.as_tai64();

    // Convert back to UNIX time
    let converted = Time::from_tai64(tai64);
    assert(now == converted);
}
```

### TAI64 vs UNIX Time

#### Conversion Details

The library uses:

```sway
const TAI_64_CONVERTER: u64 = 10 + (1 << 62);
```

(1 << 62) (0x4000000000000000) marks value as TAI64. 10 accounts for initial TAI-UTC offset in 1970.

Conversion formulas:

`UNIX → TAI64: tai64 = unix + TAI_64_CONVERTER`

`TAI64 → UNIX: unix = tai64 - TAI_64_CONVERTER`

#### Key Differences

| Feature      | TAI64                    | UNIX                      |
|--------------|--------------------------|---------------------------|
| Epoch        | 1970-01-01 00:00:00 TAI  | 1970-01-01 00:00:00 UTC   |
| Leap Seconds | No leap seconds          | Includes leap seconds     |
| Stability    | Continuous time scale    | Discontinuous adjustments |
| Value Range  | (1 << 62) + offset (10s) | Seconds since epoch       |

#### Why TAI64?

* Deterministic execution: No leap second ambiguities
* Monotonic time: Always increases steadily
* Blockchain-friendly: Aligns with Fuel's timestamp mechanism

## Best Practices

1. Use `Duration` for time spans instead of raw seconds
2. Always handle `TimeError` results from `duration_since()` and `elapsed()`
3. Convert to TAI64 when interacting with blockchain primitives
4. Use `Time::block()` for historical time comparisons
5. Prefer duration constants (`SECOND`, `HOUR`, etc.) for readability

## Limitations

1. Durations only support second-level precision
2. Time comparisons are limited to u64 range (584 billion years)
3. No calendar/date functionality (only timestamps)
4. Duration conversions truncate fractional units


---

### File: docs/sway/docs/book/src/common-collections/index.md

# Common Collections

Sway’s standard library includes a number of very useful data structures called collections. Most other data types represent one specific value, but collections can contain multiple values. Unlike the built-in array and tuple types which are allocated on the "stack" and cannot grow in size, the data these collections point to is stored either on the "heap" or in contract "storage", which means the amount of data does not need to be known at compile time and can grow as the program runs. Each kind of collection has different capabilities and costs, and choosing an appropriate one for your current situation is a skill you’ll develop over time. In this chapter, we’ll discuss three collections that are used very often in Sway programs:

A vector on the heap allows you to store a variable number of values next to each other.

A `StorageVec` is similar to a vector on the heap but uses persistent storage.

A `StorageMap` allows you to associate a value with a particular key.

We’ll discuss how to create and update a vector, `StorageVec`, and `StorageMap`, as well as what makes each special.

- [Vectors on the Heap](./vec.md)
- [`StorageVec`](./storage_vec.md)
- [`StorageMap`](./storage_map.md)


---

### File: docs/sway/docs/book/src/common-collections/storage_map.md

# Storage Maps

Another important common collection is the storage map.

<!-- This section should explain storage maps in Sway -->
<!-- storage_map:example:start -->
The type `StorageMap<K, V>` from the standard library stores a mapping of keys of type `K` to values of type `V` using a hashing function, which determines how it places these keys and values into _storage slots_. This is similar to [Rust's `HashMap<K, V>`](https://doc.rust-lang.org/std/collections/struct.HashMap.html) but with a few differences.

Storage maps are useful when you want to look up data not by using an index, as you can with vectors, but by using a key that can be of any type. For example, when building a ledger-based sub-currency smart contract, you could keep track of the balance of each wallet in a storage map in which each key is a wallet’s `Address` and the values are each wallet’s balance. Given an `Address`, you can retrieve its balance.

Similarly to `StorageVec<T>`, `StorageMap<K, V>` can only be used in a contract because only contracts are allowed to access persistent storage.

`StorageMap<T>` is included in the [standard library prelude](../introduction/standard_library.md#standard-library-prelude) which means that there is no need to import it manually.
<!-- storage_map:example:end -->

## Creating a New Storage Map

To create a new empty storage map, we have to declare the map in a `storage` block as follows:

```sway
    map: StorageMap<Address, u64> = StorageMap::<Address, u64> {},
```

<!-- This section should explain how to implement storage maps in Sway -->
<!-- use_storage_maps:example:start -->
Just like any other storage variable, two things are required when declaring a `StorageMap`: a type annotation and an initializer. The initializer is just an empty struct of type `StorageMap` because `StorageMap<K, V>` itself is an empty struct! Everything that is interesting about `StorageMap<K, V>` is implemented in its methods.

Storage maps, just like `Vec<T>` and `StorageVec<T>`, are implemented using generics which means that the `StorageMap<K, V>` type provided by the standard library can map keys of any type `K` to values of any type `V`. In the example above, we’ve told the Sway compiler that the `StorageMap<K, V>` in `map` will map keys of type `Address` to values of type `u64`.
<!-- use_storage_maps:example:end -->

## Updating a Storage Map

<!-- This section should explain how to update storage maps in Sway -->
<!-- update_storage_maps:example:start -->
To insert key-value pairs into a storage map, we can use the `insert` method.
<!-- update_storage_maps:example:end -->

For example:

```sway
    #[storage(write)]
    fn insert_into_storage_map() {
        let addr1 = Address::from(0x0101010101010101010101010101010101010101010101010101010101010101);
        let addr2 = Address::from(0x0202020202020202020202020202020202020202020202020202020202020202);

        storage.map.insert(addr1, 42);
        storage.map.insert(addr2, 77);
    }
```

Note two details here. First, in order to use `insert`, we need to first access the storage map using the `storage` keyword. Second, because `insert` requires _writing_ into storage, a `#[storage(write)]` annotation is required on the ABI function that calls `insert`.

> **Note**
> The storage annotation is also required for any private function defined in the contract that tries to insert into the map.

<!-- markdownlint-disable-line MD028 -->
> **Note**
> There is no need to add the `mut` keyword when declaring a `StorageMap<K, V>`. All storage variables are mutable by default.

## Accessing Values in a Storage Map

<!-- This section should explain how to access storage map values in Sway -->
<!-- access_storage_maps:example:start -->
We can get a value out of the storage map by providing its `key` to the `get` method.
<!-- access_storage_maps:example:end -->

For example:

```sway
    #[storage(read, write)]
    fn get_from_storage_map() {
        let addr1 = Address::from(0x0101010101010101010101010101010101010101010101010101010101010101);
        let addr2 = Address::from(0x0202020202020202020202020202020202020202020202020202020202020202);

        storage.map.insert(addr1, 42);
        storage.map.insert(addr2, 77);

        let value1 = storage.map.get(addr1).try_read().unwrap_or(0);
    }
```

Here, `value1` will have the value that's associated with the first address, and the result will be `42`. The `get` method returns an `Option<V>`; if there’s no value for that key in the storage map, `get` will return `None`. This program handles the `Option` by calling `unwrap_or` to set `value1` to zero if `map` doesn't have an entry for the key.

## Storage Maps with Multiple Keys

Maps with multiple keys can be implemented using tuples as keys. For example:

```sway
    map_two_keys: StorageMap<(b256, bool), b256> = StorageMap::<(b256, bool), b256> {},
```

## Nested Storage Maps

It is possible to nest storage maps as follows:

```sway
    nested_map: StorageMap<u64, StorageMap<u64, u64>> = StorageMap::<u64, StorageMap<u64, u64>> {},
    #[storage(read, write)]
    fn access_nested_map() {
        storage.nested_map.get(0).insert(1, 42);
        storage.nested_map.get(2).insert(3, 24);

        assert(storage.nested_map.get(0).get(1).read() == 42);
        assert(storage.nested_map.get(0).get(0).try_read().is_none()); // Nothing inserted here
        assert(storage.nested_map.get(2).get(3).read() == 24);
        assert(storage.nested_map.get(2).get(2).try_read().is_none()); // Nothing inserted here
    }
```

The nested map can then be accessed as follows:

```sway
    #[storage(read, write)]
    fn access_nested_map() {
        storage.nested_map.get(0).insert(1, 42);
        storage.nested_map.get(2).insert(3, 24);

        assert(storage.nested_map.get(0).get(1).read() == 42);
        assert(storage.nested_map.get(0).get(0).try_read().is_none()); // Nothing inserted here
        assert(storage.nested_map.get(2).get(3).read() == 24);
        assert(storage.nested_map.get(2).get(2).try_read().is_none()); // Nothing inserted here
    }
```


---

### File: docs/sway/docs/book/src/common-collections/storage_vec.md

# Storage Vectors

The second collection type we’ll look at is `StorageVec<T>`. Just like vectors on the heap (i.e. `Vec<T>`), storage vectors allow you to store more than one value in a single data structure where each value is assigned an index and can only store values of the same type. However, unlike `Vec<T>`, the elements of a `StorageVec` are stored in _persistent storage_, and consecutive elements are not necessarily stored in storage slots that have consecutive keys.

In order to use `StorageVec<T>`, you must first import `StorageVec` as follows:

```sway
use std::storage::storage_vec::*;
```

Another major difference between `Vec<T>` and `StorageVec<T>` is that `StorageVec<T>` can only be used in a contract because only contracts are allowed to access persistent storage.

## Creating a New `StorageVec`

To create a new empty `StorageVec`, we have to declare the vector in a `storage` block as follows:

```sway
    v: StorageVec<u64> = StorageVec {},
```

Just like any other storage variable, two things are required when declaring a `StorageVec`: a type annotation and an initializer. The initializer is just an empty struct of type `StorageVec` because `StorageVec<T>` itself is an empty struct! Everything that is interesting about `StorageVec<T>` is implemented in its methods.

Storage vectors, just like `Vec<T>`, are implemented using generics which means that the `StorageVec<T>` type provided by the standard library can hold any type. When we create a `StorageVec` to hold a specific type, we can specify the type within angle brackets. In the example above, we’ve told the Sway compiler that the `StorageVec<T>` in `v` will hold elements of the `u64` type.

## Updating a `StorageVec`

To add elements to a `StorageVec`, we can use the `push` method, as shown below:

```sway
    #[storage(read, write)]
    fn push_to_storage_vec() {
        storage.v.push(5);
        storage.v.push(6);
        storage.v.push(7);
        storage.v.push(8);
    }
```

Note two details here. First, in order to use `push`, we need to first access the vector using the `storage` keyword. Second, because `push` requires accessing storage, a `storage` annotation is required on the ABI function that calls `push`. While it may seem that `#[storage(write)]` should be enough here, the `read` annotation is also required because each call to `push` requires _reading_ (and then updating) the length of the `StorageVec` which is also stored in persistent storage.

> **Note**
> The storage annotation is also required for any private function defined in the contract that tries to push into the vector.

<!-- markdownlint-disable-line MD028 -->
> **Note**
> There is no need to add the `mut` keyword when declaring a `StorageVec<T>`. All storage variables are mutable by default.

## Reading Elements of Storage Vectors

To read a value stored in a vector at a particular index, you can use the `get` method as shown below:

```sway
    #[storage(read)]
    fn read_from_storage_vec() {
        let third = storage.v.get(2);
        match third {
            Some(third) => log(third.read()),
            None => revert(42),
        }
    }
```

Note three details here. First, we use the index value of `2` to get the third element because vectors are indexed by number, starting at zero. Second, we get the third element by using the `get` method with the index passed as an argument, which gives us an `Option<StorageKey<T>>`. Third, the ABI function calling `get` only requires the annotation `#[storage(read)]` as one might expect because `get` does not write to storage.

When the `get` method is passed an index that is outside the vector, it returns `None` without panicking. This is particularly useful if accessing an element beyond the range of the vector may happen occasionally under normal circumstances. Your code will then have logic to handle having either `Some(element)` or `None`. For example, the index could be coming as a contract method argument. If the argument passed is too large, the method `get` will return a `None` value, and the contract method may then decide to revert when that happens or return a meaningful error that tells the user how many items are in the current vector and give them another chance to pass a valid value.

## Iterating over the Values in a Vector

Iterating over a storage vector is conceptually the same as [iterating over a `Vec<T>`](./vec.md). The only difference is an additional call to `read()` to actually read the stored value.

```sway
    #[storage(read)]
    fn iterate_over_a_storage_vec() {
        // Iterate over all the elements
        // in turn using the `while` loop.
        // **This approach is not recommended.**
        // For iterating over all the elements
        // in turn use the `for` loop instead.
        let mut i = 0;
        while i < storage.v.len() {
            log(storage.v.get(i).unwrap().read());
            i += 1;
        }

        // The preferred and most performant way
        // to iterate over all the elements in turn is
        // to use the `for` loop.
        for elem in storage.v.iter() {
            log(elem.read());
        }

        // Use the `while` loop only when more
        // control over traversal is needed.
        // E.g., in the below example we iterate
        // the vector backwards, accessing only
        // every second element.
        let mut i = storage.v.len() - 1;
        while 0 <= i {
            log(storage.v.get(i).unwrap().read());
            i -= 2;
        }
    }
```

Note that **modifying a vector during iteration, by e.g. adding or removing elements, is a logical error and results in an [undefined behavior](../reference/undefined_behavior.md)**:

## Using an Enum to store Multiple Types

Storage vectors, just like `Vec<T>`, can only store values that are the same type. Similarly to what we did for `Vec<T>` in the section [Using an Enum to store Multiple Types](./vec.md#using-an-enum-to-store-multiple-types), we can define an enum whose variants will hold the different value types, and all the enum variants will be considered the same type: that of the enum. This is shown below:

```sway
enum TableCell {
    Int: u64,
    B256: b256,
    Boolean: bool,
}
```

Then we can declare a `StorageVec` in a `storage` block to hold that enum and so, ultimately, holds different types:

```sway
    row: StorageVec<TableCell> = StorageVec {},
```

We can now push different enum variants to the `StorageVec` as follows:

```sway
    #[storage(read, write)]
    fn push_to_multiple_types_storage_vec() {
        storage.row.push(TableCell::Int(3));
        storage
            .row
            .push(TableCell::B256(0x0101010101010101010101010101010101010101010101010101010101010101));
        storage.row.push(TableCell::Boolean(true));
    }
```

Now that we’ve discussed some of the most common ways to use storage vectors, be sure to review the API documentation for all the many useful methods defined on `StorageVec<T>` by the standard library. For now, these can be found in the [source code for `StorageVec<T>`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/storage.sw). For example, in addition to `push`, a `pop` method removes and returns the last element, a `remove` method removes and returns the element at some chosen index within the vector, an `insert` method inserts an element at some chosen index within the vector, etc.

## Nested Storage Vectors

It is possible to nest storage vectors as follows:

```sway
    nested_vec: StorageVec<StorageVec<u64>> = StorageVec {},
```

The nested vector can then be accessed as follows:

```sway
    #[storage(read, write)]
    fn access_nested_vec() {
        storage.nested_vec.push(StorageVec {});
        storage.nested_vec.push(StorageVec {});

        let mut inner_vec0 = storage.nested_vec.get(0).unwrap();
        let mut inner_vec1 = storage.nested_vec.get(1).unwrap();

        inner_vec0.push(0);
        inner_vec0.push(1);

        inner_vec1.push(2);
        inner_vec1.push(3);
        inner_vec1.push(4);

        assert(inner_vec0.len() == 2);
        assert(inner_vec0.get(0).unwrap().read() == 0);
        assert(inner_vec0.get(1).unwrap().read() == 1);
        assert(inner_vec0.get(2).is_none());

        assert(inner_vec1.len() == 3);
        assert(inner_vec1.get(0).unwrap().read() == 2);
        assert(inner_vec1.get(1).unwrap().read() == 3);
        assert(inner_vec1.get(2).unwrap().read() == 4);
        assert(inner_vec1.get(3).is_none());
    }
```


---

### File: docs/sway/docs/book/src/common-collections/vec.md

# Vectors on the Heap

The first collection type we’ll look at is `Vec<T>`, also known as a vector. Vectors allow you to store more than one value in a single data structure that puts all the values next to each other in memory. Vectors can only store values of the same type. They are useful when you have a list of items, such as the lines of text in a file or the prices of items in a shopping cart.

`Vec<T>` is included in the [standard library prelude](../introduction/standard_library.md#standard-library-prelude) which means that there is no need to import it manually.

## Creating a New Vector

To create a new empty vector, we call the `Vec::new` function, as shown below:

```sway
    let v: Vec<u64> = Vec::new();
```

Note that we added a type annotation here. Because we aren’t inserting any values into this vector, the Sway compiler doesn’t know what kind of elements we intend to store. Vectors are implemented using generics which means that the `Vec<T>` type provided by the standard library can hold any type. When we create a vector to hold a specific type, we can specify the type within angle brackets. In the example above, we’ve told the Sway compiler that the `Vec<T>` in `v` will hold elements of the `u64` type.

## Updating a Vector

To create a vector and then add elements to it, we can use the `push` method, as shown below:

```sway
    let mut v = Vec::new();

    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);
```

As with any variable, if we want to be able to change its value, we need to make it mutable using the `mut` keyword, as discussed in the section [Declaring a Variable](../basics/variables.md#declaring-a-variable). The numbers we place inside are all of type `u64`, and the Sway compiler infers this from the data, so we don’t need the `Vec<u64>` annotation.

## Reading Elements of Vectors

To read a value stored in a vector at a particular index, you can use the `get` method as shown below:

```sway
    let third = v.get(2);
    match third {
        Some(third) => log(third),
        None => revert(42),
    }
    let does_not_exist = v.get(100);
    // ...decide here how to handle an out-of-bounds access
```

Note two details here. First, we use the index value of `2` to get the third element because vectors are indexed by number, starting at zero. Second, we get the third element by using the `get` method with the index passed as an argument, which gives us an `Option<T>`.

When the `get` method is passed an index that is outside the vector, it returns `None` without panicking. This is particularly useful if accessing an element beyond the range of the vector may happen occasionally under normal circumstances. Your code will then have logic to handle having either `Some(element)` or `None`. For example, the index could be coming as a contract method argument. If the argument passed is too large, the method `get` will return a `None` value, and the contract method may then decide to revert when that happens or return a meaningful error that tells the user how many items are in the current vector and give them another chance to pass a valid value.

## Iterating over the Values in a Vector

To access elements of a vector, we can iterate through the valid indices using a `while` loop and the `len` method as shown below:

```sway
    let mut i = 0;
    while i < v.len() {
        log(v.get(i).unwrap());
        i += 1;
    }
```

Note two details here. First, we use the method `len` which returns the length of the vector. Second, we call the method `unwrap` to extract the `Option` returned by `get`. We know that `unwrap` will not fail (i.e. will not cause a revert) because each index `i` passed to `get` is known to be smaller than the length of the vector.

The idiomatic and convenient way to access each element in a vector in turn, is to use the `for` loop in the combination with the `iter` method. The `iter` method returns an iterator that iterates over all the elements of the vector sequentially.

```sway
    for elem in v.iter() {
        log(elem);
    }
    for elem in v.iter() {
        log(elem);
        if elem == 3 {
            v.push(6); // Modification causes undefined behavior!
        }
    }
```

Note that **modifying a vector during iteration, by e.g. adding or removing elements, is a logical error and results in an [undefined behavior](../reference/undefined_behavior.md)**:

```sway
    for elem in v.iter() {
        log(elem);
        if elem == 3 {
            v.push(6); // Modification causes undefined behavior!
        }
    }
```

Accessing vector elements via `while` loop should be used only when more control over traversal is needed. E.g., in the below example we iterate the vector backwards, accessing only every second element.

```sway
    // Start from the end
    let mut i = v.len() - 1;
    while 0 <= i {
        log(v.get(i).unwrap());
        // Access every second element
        i -= 2;
    }
```

## Using an Enum to store Multiple Types

Vectors can only store values that are the same type. This can be inconvenient; there are definitely use cases for needing to store a list of items of different types. Fortunately, the variants of an enum are defined under the same enum type, so when we need one type to represent elements of different types, we can define and use an enum!

For example, say we want to get values from a row in a table in which some of the columns in the row contain integers, some `b256` values, and some Booleans. We can define an enum whose variants will hold the different value types, and all the enum variants will be considered the same type: that of the enum. Then we can create a vector to hold that enum and so, ultimately, holds different types. We’ve demonstrated this below:

```sway
    enum TableCell {
        Int: u64,
        B256: b256,
        Boolean: bool,
    }

    let mut row = Vec::new();
    row.push(TableCell::Int(3));
    row.push(TableCell::B256(0x0101010101010101010101010101010101010101010101010101010101010101));
    row.push(TableCell::Boolean(true));
```

Now that we’ve discussed some of the most common ways to use vectors, be sure to review the API documentation for all the many useful methods defined on `Vec<T>` by the standard library. For now, these can be found in the [source code for `Vec<T>`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/vec.sw). For example, in addition to `push`, a `pop` method removes and returns the last element, a `remove` method removes and returns the element at some chosen index within the vector, an `insert` method inserts an element at some chosen index within the vector, etc.


---

### File: docs/sway/docs/book/src/debugging/debugging_with_cli.md

# Debugging with CLI

The `forc debug` CLI enables debugging a live transaction on a running Fuel Client node.

## An example project

First, we need a project to debug, so create a new project using

```bash
forc new --script dbg_example && cd dbg_example
```

And then add some content to `src/main.sw`, for example:

```sway
script;

use std::logging::log;

fn factorial(n: u64) -> u64 {
    let mut result = 1;
    let mut counter = 0;
    while counter < n {
        counter = counter + 1;
        result = result * counter;
    }
    return result;
}

fn main() {
    log::<u64>(factorial(5)); // 120
}
```

## Building and bytecode output

Now we are ready to build the project.

```bash
forc build
```

After this the resulting binary should be located at `out/debug/dbg_example.bin`. Because we are interested in the resulting bytecode, we can read that with:

```bash
forc parse-bytecode out/debug/dbg_example.bin
```

We can recognize the main loop by observing the control flow. Looking around halfword 58-60, we can see:

```text
  half-word   byte    op                                                 raw
          58   232    MOVI { dst: 0x11, val: 5 }                         72 44 00 05                                 
          59   236    LT { dst: 0x10, lhs: 0x10, rhs: 0x11 }             16 41 04 40                                 
          60   240    JNZF { cond_nz: 0x10, dynamic: 0x0, fixed: 81 }    76 40 00 51
```

Here we can see our `factorial(5)` being set up with `MOVI` setting the value 5, followed by the `LT` comparison and conditional jump `JNZF`. The multiplication for our factorial happens at halfword 147 with `MUL { dst: 0x10, lhs: 0x10, rhs: 0x11 }`. Finally, we can spot our log statement at halfword 139 with the `LOGD` instruction.

## Setting up the debugging

We can start up the debug infrastructure. On a new terminal session run `fuel-core run --db-type in-memory --debug`; we need to have that running because it actually executes the program. Now we can fire up the debugger itself: `forc-debug`. Now if everything is set up correctly, you should see the debugger prompt (`>>`). You can use `help` command to list available commands.

The debugger supports tab completion to help you discover files in your current working directory (and its subdirectories):

- Type `tx` and press tab to recursively search for valid transaction JSON files
- After selecting a transaction file, press tab again to search for ABI files
- You can keep pressing tab to cycle through the found files
- Of course, you can also manually type the full path to any transaction or ABI file, they don't have to be in your current directory

Now we would like to inspect the program while it's running. To do this, we first need to send the script to the executor, i.e. `fuel-core`. To do so, we need a *transaction specification*, `tx.json`. It looks something like this:

```json
{
  "Script": {
    "body": {
      "script_gas_limit": 1000000,
      "script": [
        26, 240, 48, 0, 116, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 96, 93, 255, 192, 1, 16, 255, 255, 0, 26, 236, 80, 0, 145, 0, 0, 184, 80, 67, 176, 80, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 37, 80, 71, 176, 40, 26, 233, 16, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 136, 26, 71, 208, 0, 114, 72, 0, 24, 40, 237, 20, 128, 80, 79, 176, 120, 114, 68, 0, 24, 40, 79, 180, 64, 80, 71, 176, 160, 114, 72, 0, 24, 40, 69, 52, 128, 80, 71, 176, 96, 114, 72, 0, 24, 40, 69, 52, 128, 80, 75, 176, 64, 26, 233, 16, 0, 26, 229, 32, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 144, 26, 71, 208, 0, 80, 75, 176, 24, 114, 76, 0, 16, 40, 73, 20, 192, 80, 71, 176, 144, 114, 76, 0, 16, 40, 69, 36, 192, 114, 72, 0, 16, 40, 65, 20, 128, 93, 69, 0, 1, 93, 65, 0, 0, 37, 65, 16, 0, 149, 0, 0, 63, 150, 8, 0, 0, 26, 236, 80, 0, 145, 0, 1, 88, 26, 87, 224, 0, 95, 236, 16, 42, 95, 236, 0, 41, 93, 67, 176, 41, 114, 68, 0, 5, 22, 65, 4, 64, 118, 64, 0, 81, 93, 67, 176, 42, 80, 71, 176, 200, 26, 233, 16, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 87, 26, 71, 208, 0, 114, 72, 0, 24, 40, 237, 20, 128, 80, 71, 176, 160, 114, 72, 0, 24, 40, 71, 180, 128, 80, 75, 176, 24, 114, 76, 0, 24, 40, 73, 20, 192, 80, 71, 176, 88, 114, 76, 0, 24, 40, 69, 36, 192, 93, 83, 176, 11, 93, 79, 176, 12, 93, 71, 176, 13, 114, 72, 0, 8, 16, 73, 20, 128, 21, 73, 36, 192, 118, 72, 0, 1, 116, 0, 0, 7, 114, 72, 0, 2, 27, 73, 52, 128, 114, 76, 0, 8, 16, 77, 36, 192, 38, 76, 0, 0, 40, 29, 68, 64, 26, 80, 112, 0, 16, 73, 68, 64, 95, 73, 0, 0, 114, 64, 0, 8, 16, 65, 20, 0, 80, 71, 176, 112, 95, 237, 64, 14, 95, 237, 48, 15, 95, 237, 0, 16, 80, 67, 176, 48, 114, 72, 0, 24, 40, 65, 20, 128, 80, 71, 176, 136, 114, 72, 0, 24, 40, 69, 4, 128, 80, 67, 177, 8, 114, 72, 0, 24, 40, 65, 20, 128, 80, 71, 177, 48, 114, 72, 0, 24, 40, 69, 4, 128, 80, 67, 177, 48, 80, 71, 176, 240, 114, 72, 0, 24, 40, 69, 4, 128, 80, 67, 176, 224, 26, 233, 16, 0, 26, 229, 0, 0, 32, 248, 51, 0, 88, 251, 224, 2, 80, 251, 224, 4, 116, 0, 0, 56, 26, 67, 208, 0, 80, 71, 176, 72, 114, 72, 0, 16, 40, 69, 4, 128, 80, 67, 177, 32, 114, 72, 0, 16, 40, 65, 20, 128, 80, 71, 176, 184, 114, 72, 0, 16, 40, 69, 4, 128, 93, 67, 240, 0, 93, 71, 176, 23, 93, 75, 176, 24, 52, 1, 4, 82, 26, 244, 0, 0, 116, 0, 0, 8, 93, 67, 176, 41, 16, 65, 0, 64, 95, 237, 0, 41, 93, 67, 176, 42, 93, 71, 176, 41, 27, 65, 4, 64, 95, 237, 0, 42, 117, 0, 0, 91, 146, 0, 1, 88, 26, 249, 80, 0, 152, 8, 0, 0, 151, 0, 0, 63, 74, 248, 0, 0, 149, 0, 0, 15, 150, 8, 0, 0, 26, 236, 80, 0, 145, 0, 0, 72, 26, 67, 160, 0, 26, 71, 224, 0, 114, 72, 4, 0, 38, 72, 0, 0, 26, 72, 112, 0, 80, 79, 176, 24, 95, 237, 32, 3, 114, 72, 4, 0, 95, 237, 32, 4, 95, 236, 0, 5, 114, 72, 0, 24, 40, 237, 52, 128, 80, 75, 176, 48, 114, 76, 0, 24, 40, 75, 180, 192, 114, 76, 0, 24, 40, 65, 36, 192, 26, 245, 0, 0, 146, 0, 0, 72, 26, 249, 16, 0, 152, 8, 0, 0, 151, 0, 0, 15, 74, 248, 0, 0, 149, 0, 0, 63, 150, 8, 0, 0, 26, 236, 80, 0, 145, 0, 0, 104, 26, 67, 160, 0, 26, 71, 144, 0, 26, 75, 224, 0, 80, 79, 176, 80, 114, 80, 0, 24, 40, 77, 5, 0, 114, 64, 0, 24, 40, 237, 52, 0, 80, 67, 176, 40, 114, 76, 0, 24, 40, 67, 180, 192, 93, 79, 176, 5, 80, 65, 0, 16, 80, 83, 176, 64, 95, 237, 48, 8, 80, 77, 64, 8, 114, 84, 0, 8, 40, 77, 5, 64, 80, 67, 176, 24, 114, 76, 0, 16, 40, 65, 68, 192, 114, 76, 0, 16, 40, 69, 4, 192, 26, 245, 16, 0, 146, 0, 0, 104, 26, 249, 32, 0, 152, 8, 0, 0, 151, 0, 0, 63, 74, 248, 0, 0, 71, 0, 0, 0, 21, 6, 230, 244, 76, 29, 98, 145
      ],
      "script_data": [],
      "receipts_root": "0000000000000000000000000000000000000000000000000000000000000000"
    },
    "policies": {
      "bits": "MaxFee",
      "values": [0, 0, 0, 0]
    },
    "inputs": [
      {
        "CoinSigned": {
          "utxo_id": {
            "tx_id": "c49d65de61cf04588a764b557d25cc6c6b4bc0d7429227e2a21e61c213b3a3e2",
            "output_index": 18
          },
          "owner": "f1e92c42b90934aa6372e30bc568a326f6e66a1a0288595e6e3fbd392a4f3e6e",
          "amount": 10599410012256088000,
          "asset_id": "2cafad611543e0265d89f1c2b60d9ebf5d56ad7e23d9827d6b522fd4d6e44bc3",
          "tx_pointer": {
            "block_height": 0,
            "tx_index": 0
          },
          "witness_index": 0,
          "maturity": 0,
          "predicate_gas_used": null,
          "predicate": null,
          "predicate_data": null
        }
      }
    ],
    "outputs": [],
    "witnesses": [
      {
        "data": [156, 254, 34, 102, 65, 96, 133, 170, 254, 105, 147, 35, 196, 199, 179, 133, 132, 240, 208, 149, 11, 46, 30, 96, 44, 91, 121, 195, 145, 184, 159, 235, 117, 82, 135, 41, 84, 154, 102, 61, 61, 16, 99, 123, 58, 173, 75, 226, 219, 139, 62, 33, 41, 176, 16, 18, 132, 178, 8, 125, 130, 169, 32, 108]
      }
    ]
  }
}
```

However, the key `script` should contain the actual bytecode to execute, i.e. the contents of `out/debug/dbg_example.bin` as a JSON array. The following command can be used to generate it:

```bash
python3 -c 'print(list(open("out/debug/dbg_example.bin", "rb").read()))'
```

So now we replace the script array with the result, and save it as `tx.json`.

## Using the debugger

Now we can actually execute the script with an ABI to decode the log values:

```text
>> start_tx tx.json out/debug/dbg_example-abi.json

Receipt: LogData { id: 0000000000000000000000000000000000000000000000000000000000000000, ra: 0, rb: 1515152261580153489, ptr: 67107840, len: 8, digest: d2b80ebb9ce633ad49a9ccfcc58ac7ad33a9ab4741529ae4247a3b07e8fa1c74, pc: 10924, is: 10368, data: Some(0000000000000078) }
Decoded log value: 120, from contract: 0000000000000000000000000000000000000000000000000000000000000000
Receipt: ReturnData { id: 0000000000000000000000000000000000000000000000000000000000000000, ptr: 67106816, len: 0, digest: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855, pc: 10564, is: 10368, data: Some() }
Receipt: ScriptResult { result: Success, gas_used: 1273 }
Terminated
```

Looking at the output, we can see our `factorial(5)` result as the decoded log value of 120. The ABI has helped us decode the raw bytes `(0000000000000078)` into a meaningful value. It also tells us that the execution terminated without hitting any breakpoints. That's unsurprising, because we haven't set up any. We can do so with `breakpoint` command:

```text
>> breakpoint 0

>> start_tx tx.json out/debug/dbg_example-abi.json

Receipt: ScriptResult { result: Success, gas_used: 0 }
Stopped on breakpoint at address 0 of contract 0x0000000000000000000000000000000000000000000000000000000000000000
```

Now we have stopped execution at the breakpoint on entry (address `0`). We can now inspect the initial state of the VM.

```text
>> register ggas

reg[0x9] = 1000000  # ggas

>> memory 0x10 0x8

 000010: db f3 63 c9 1c 7f ec 95
```

However, that's not too interesting either, so let's just execute until the end, and then reset the VM to remove the breakpoints.

```text
>> continue

Receipt: LogData { id: 0000000000000000000000000000000000000000000000000000000000000000, ra: 0, rb: 1515152261580153489, ptr: 67107840, len: 8, digest: d2b80ebb9ce633ad49a9ccfcc58ac7ad33a9ab4741529ae4247a3b07e8fa1c74, pc: 10924, is: 10368, data: Some(0000000000000078) }
Decoded log value: 120, from contract: 0000000000000000000000000000000000000000000000000000000000000000
Receipt: ReturnData { id: 0000000000000000000000000000000000000000000000000000000000000000, ptr: 67106816, len: 0, digest: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855, pc: 10564, is: 10368, data: Some() }
Terminated

>> reset
```

Next, we will setup a breakpoint to check the state on each iteration of the `while` loop. For instance, if we'd like to see what numbers get multiplied together, we could set up a breakpoint before the operation. Looking at our bytecode we can see the main multiplication for our factorial happens at:

```text
  half-word   byte   op                                        raw
        147   588    MUL { dst: 0x10, lhs: 0x10, rhs: 0x11 }   1b 41 04 40
```

We can set a breakpoint on its address, at halfword-offset `147`.

```text
>>> breakpoint 147

>> start_tx tx.json out/debug/dbg_example-abi.json

Receipt: ScriptResult { result: Success, gas_used: 82 }
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000
```

Now we can inspect the inputs to multiply. Looking at [the specification](https://github.com/FuelLabs/fuel-specs/blob/master/src/fuel-vm/instruction-set.md#mul-multiply) tells us that the instruction `MUL { dst: 0x10, lhs: 0x10, rhs: 0x11 }` means `reg[0x10] = reg[0x10] * reg[0x11]`. So inspecting the inputs:

```text
>> r 0x10 0x11
reg[0x10] = 1        # reg16
reg[0x11] = 1        # reg17
```

So on the first round the numbers are 1 and 1, so we can continue to the next iteration with the `c` command:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 1        # reg16
reg[0x11] = 2        # reg17
```

And the next one:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 2        # reg16
reg[0x11] = 3        # reg17
```

And fourth one:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 6        # reg16
reg[0x11] = 4        # reg17
```

And round 5:

```text
>> c
Stopped on breakpoint at address 588 of contract 0x0000000000000000000000000000000000000000000000000000000000000000

>> r 0x10 0x11
reg[0x10] = 24       # reg16
reg[0x11] = 5        # reg17
```

At this point we can look at the values

0x10 | 0x11
-----|------
1    | 1
1    | 2
2    | 3
6    | 4
24   | 5

From this we can clearly see that the left side, register `0x10` is the `result` variable which accumulates the factorial calculation (1, 1, 2, 6, 24), and register `0x11` is the `counter` which increments from 1 to 5. Now the counter equals the given factorial function argument `5`, and the loop terminates. So when we continue, the program finishes without encountering any more breakpoints:

```text
>> c

Receipt: LogData { id: 0000000000000000000000000000000000000000000000000000000000000000, ra: 0, rb: 1515152261580153489, ptr: 67107840, len: 8, digest: d2b80ebb9ce633ad49a9ccfcc58ac7ad33a9ab4741529ae4247a3b07e8fa1c74, pc: 10924, is: 10368, data: Some(0000000000000078) }
Decoded log value: 120, from contract: 0000000000000000000000000000000000000000000000000000000000000000
Receipt: ReturnData { id: 0000000000000000000000000000000000000000000000000000000000000000, ptr: 67106816, len: 0, digest: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855, pc: 10564, is: 10368, data: Some() }
Terminated
```


---

### File: docs/sway/docs/book/src/debugging/debugging_with_ide.md

# Debugging with IDE

The `forc debug` plugin also enables line-by-line debugging of Sway unit tests in VSCode.

## Installation

1. Install the Sway VSCode extension from the [marketplace](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin).
2. Ensure you have the forc-debug binary installed. `which forc-debug`.
It can be installed with `fuelup component add forc-debug`.
3. Create a `.vscode/launch.json` file with the following contents:

```json
{
    "version": "0.2.0",
    "configurations": [
        {
        "type": "sway",
        "request": "launch",
        "name": "Debug Sway",
        "program": "${file}"
    }]
}
```

## An example project

Given this example contract:

```sway
contract;

abi CallerContract {
    fn test_false() -> bool;
}

impl CallerContract for Contract {
    fn test_false() -> bool {
        false
    }
}

abi CalleeContract {
    fn test_true() -> bool;
}

#[test]
fn test_multi_contract_calls() {
    let caller = abi(CallerContract, CONTRACT_ID);
    let callee = abi(CalleeContract, callee::CONTRACT_ID);

    let should_be_false = caller.test_false();
    let should_be_true = callee.test_true();
    assert(!should_be_false);
    assert(should_be_true);
}
```

Within the sway file open in VSCode, you can set breakpoints on lines within the test or functions that it calls, and click Run -> Start Debugging to begin debugging the unit test.

This will build the sway project and run it in debug mode. The debugger will stop the VM execution when a breakpoint is hit.

The debug panel will show VM registers under the Variables tab, as well as the current VM opcode where execution is suspended. You can continue execution, or use the Step Over function to step forward, instruction by instruction.


---

### File: docs/sway/docs/book/src/debugging/index.md

# Debugging

Forc provides tools for debugging both live transactions as well as Sway unit tests.
Debugging can be done via CLI or using the VSCode IDE.

**Unit testing** refers to "in-language" test functions annotated with `#[test]`. Line-by-line
debugging is available within the VSCode IDE.

**Live transaction** refers to the testing sending a transaction to a running Fuel Client
node to exercise your Sway code. Instruction-by-instruction debugging is available in the `forc debug` CLI.

- [Debugging with CLI](./debugging_with_cli.md)
- [Debugging with IDE](./debugging_with_ide.md)

## `__dbg` intrinsic function

Sway also offers the `__dbg` intrinsic function to help debug all applications types: scripts, contracts and predicates.
When called, this intrinsic function will print the current file, line and column, together with a customizable print of the specified value.

```sway
script;
fn main() -> u64 {
    __dbg(1u64)
}
```

The application above will print:

```terminal
[src/main.sw:3:5] = 1
```

Structs can be customized by implementing the `Debug` trait.

```sway
script;
struct S { }
impl Debug for S {
    fn fmt(self, ref mut f: Formatter) {
        f.debug_struct("S2")
            .field("field1", 1)
            .field("field2", "Hello")
            .finish();
    }
}
fn main() -> u64 {
    let _ = __dbg(S {});
    __dbg(1u64)
}
```

This code is very similar to what the Sway compiler generates by default for all declared types.
And this is what is printed:

```terminal
[src/main.sw:12:13] = S2 { field1: 1, field2: "Hello" }
[src/main.sw:13:5] = 1
```


---

### File: docs/sway/docs/book/src/examples/counter.md

# Counter

The following is a simple example of a contract which implements a counter. Both the `initialize_counter()` and `increment_counter()` ABI methods return the currently set value.

```bash
forc template --template-name counter my_counter_project
```

```sway
contract;

abi TestContract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64;

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
}

impl TestContract for Contract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64 {
        storage.counter.write(value);
        value
    }

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64 {
        let incremented = storage.counter.read() + amount;
        storage.counter.write(incremented);
        incremented
    }
}

```

## Build and deploy

The following commands can be used to build and deploy the contract. For a detailed tutorial, refer to [Building and Deploying](https://docs.fuel.network/guides/contract-quickstart/#building-the-contract).

```bash
# Build the contract
forc build

# Deploy the contract
forc deploy --testnet
```


---

### File: docs/sway/docs/book/src/examples/fizzbuzz.md

# `FizzBuzz`

This example is not the traditional [`FizzBuzz`](https://en.wikipedia.org/wiki/Fizz_buzz#Programming); instead it is the smart contract version! A script can call the `fizzbuzz` ABI method of this contract with some `u64` value and receive back the result as an `enum`.

The format for custom structs and enums such as `FizzBuzzResult` will be automatically included in the ABI JSON so that off-chain code can handle the encoded form of the returned data.

```sway
contract;

enum FizzBuzzResult {
    Fizz: (),
    Buzz: (),
    FizzBuzz: (),
    Other: u64,
}

abi FizzBuzz {
    fn fizzbuzz(input: u64) -> FizzBuzzResult;
}

impl FizzBuzz for Contract {
    fn fizzbuzz(input: u64) -> FizzBuzzResult {
        if input % 15 == 0 {
            FizzBuzzResult::FizzBuzz
        } else if input % 3 == 0 {
            FizzBuzzResult::Fizz
        } else if input % 5 == 0 {
            FizzBuzzResult::Buzz
        } else {
            FizzBuzzResult::Other(input)
        }
    }
}

```


---

### File: docs/sway/docs/book/src/examples/index.md

# Example

Some basic example contracts to see how Sway and Forc work.

- [Counter](./counter.md)
- [`FizzBuzz`](./fizzbuzz.md)
- [Wallet Smart Contract](./wallet_smart_contract.md)
- [Liquidity Pool](./wallet_smart_contract.md)

Additional examples can be found in the [Sway Applications](https://github.com/FuelLabs/sway-applications/tree/master) repository.


---

### File: docs/sway/docs/book/src/examples/liquidity_pool.md

# Liquidity Pool Example

All contracts in Fuel can mint and burn their own native asset. Contracts can also receive and transfer any native asset including their own. Internal balances of all native assets pushed through calls or minted by the contract are tracked by the FuelVM and can be queried at any point using the `balance_of` function from the `std` library. Therefore, there is no need for any manual accounting of the contract's balances using persistent storage.

The `std` library provides handy methods for accessing Fuel's native asset operations.

In this example, we show a basic liquidity pool contract minting its own native asset LP asset.

```sway
contract;

use std::{
    asset::{
        mint_to,
        transfer,
    },
    call_frames::msg_asset_id,
    constants::DEFAULT_SUB_ID,
    context::msg_amount,
    hash::*,
};

abi LiquidityPool {
    fn deposit(recipient: Address);
    fn withdraw(recipient: Address);
}

const BASE_ASSET: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c);

impl LiquidityPool for Contract {
    fn deposit(recipient: Address) {
        assert(msg_asset_id() == BASE_ASSET);
        assert(msg_amount() > 0);

        // Mint two times the amount.
        let amount_to_mint = msg_amount() * 2;

        // Mint some LP assets based upon the amount of the base asset.
        mint_to(Identity::Address(recipient), DEFAULT_SUB_ID, amount_to_mint);
    }

    fn withdraw(recipient: Address) {
        let asset_id = AssetId::default();
        assert(msg_asset_id() == asset_id);
        assert(msg_amount() > 0);

        // Amount to withdraw.
        let amount_to_transfer = msg_amount() / 2;

        // Transfer base asset to recipient.
        transfer(Identity::Address(recipient), BASE_ASSET, amount_to_transfer);
    }
}

```


---

### File: docs/sway/docs/book/src/examples/sway_applications.md

# Sway Applications

The [Sway-Applications](https://github.com/FuelLabs/sway-applications) Repository contains end-to-end example applications that are written in Sway in order to demonstrate what can be built.

## Asset Management

- [Airdrop](https://github.com/FuelLabs/sway-applications/tree/master/airdrop) is an asset distribution program where users are able to claim assets given a valid merkle proof.
- [Escrow](https://github.com/FuelLabs/sway-applications/tree/master/escrow) is a third party that keeps an asset on behalf of multiple parties.
- [Non-Fungible Native Asset (NFT)](https://github.com/FuelLabs/sway-applications/tree/master/NFT) is an asset contract which provides unique collectibles, identified and differentiated by IDs, where assets contain metadata giving them distinctive characteristics.
- [Fractional Non-Fungible Token (F-NFT)](https://github.com/FuelLabs/sway-applications/tree/master/fractional-NFT) is a token contract which issues shares or partial ownership upon locking an NFT into a vault.
- [Timelock](https://github.com/FuelLabs/sway-applications/tree/master/timelock) is a contract which restricts the execution of a transaction to a specified time range.
- [Native Asset](https://github.com/FuelLabs/sway-applications/tree/master/native-asset) is a basic asset contract that enables the use of Native Assets on Fuel using existing standards and libraries.

## Decentralized Finance

- [English Auction](https://github.com/FuelLabs/sway-applications/tree/master/english-auction) is an auction where users bid up the price of an asset until the bidding period has ended or a reserve has been met.
- [Fundraiser](https://github.com/FuelLabs/sway-applications/tree/master/fundraiser) is a program allowing users to pledge towards a goal.
- [OTC Swap Predicate](https://github.com/FuelLabs/sway-applications/tree/master/OTC-swap-predicate) is a predicate that can be used to propose and execute an atomic swap between two parties without requiring any on-chain state.

## Governance

- [Decentralized Autonomous Organization (DAO)](https://github.com/FuelLabs/sway-applications/tree/master/DAO) is an organization where users get to vote on governance proposals using governance assets.
- [Multi-Signature Wallet](https://github.com/FuelLabs/sway-applications/tree/master/multisig-wallet) is a wallet that requires multiple signatures to execute a transaction.

## Games

- [TicTacToe](https://github.com/FuelLabs/sway-applications/tree/master/TicTacToe) is a game where two players compete to align three markers in a row.

## Other

- [Counter-Script](https://github.com/FuelLabs/sway-applications/tree/master/counter-script) is a script that calls a contract to increment a counter.
- [Name-Registry](https://github.com/FuelLabs/sway-applications/tree/master/name-registry) allows users to perform transactions with human readable names instead of addresses.
- [Oracle](https://github.com/FuelLabs/sway-applications/tree/master/oracle) is a smart contract that provides off-chain data to on-chain applications.


---

### File: docs/sway/docs/book/src/examples/wallet_smart_contract.md

# Wallet Smart Contract

The ABI declaration is a separate project from your ABI implementation. The project structure for the code should be organized as follows with the `wallet_abi` treated as an external library:

```sh
.
├── wallet_abi
│   ├── Forc.toml
│   └── src
│       └── main.sw
└── wallet_smart_contract
    ├── Forc.toml
    └── src
        └── main.sw
```

It's also important to specify the source of the dependency within the project's `Forc.toml` file when using external libraries. Inside the `wallet_smart_contract` project, it requires a declaration like this:

```sh
[dependencies]
wallet_abi = { path = "../wallet_abi/" }
```

## ABI Declaration

```sway
library;

// ANCHOR: abi
abi Wallet {
    // ANCHOR: receive_funds
    #[storage(read, write), payable]
    fn receive_funds();
    // ANCHOR_END: receive_funds

    // ANCHOR: send_funds
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
    // ANCHOR_END: send_funds
}
// ANCHOR: abi
```

## ABI Implementation

```sway
contract;

use std::{asset::transfer, call_frames::msg_asset_id, context::msg_amount};

// ANCHOR: abi_import
use wallet_abi::Wallet;
// ANCHOR_END: abi_import
const OWNER_ADDRESS = Address::from(0x8900c5bec4ca97d4febf9ceb4754a60d782abbf3cd815836c1872116f203f861);

storage {
    balance: u64 = 0,
}

// ANCHOR: abi_impl
impl Wallet for Contract {
    #[storage(read, write), payable]
    fn receive_funds() {
        if msg_asset_id() == AssetId::base() {
            // If we received the base asset then keep track of the balance.
            // Otherwise, we're receiving other native assets and don't care
            // about our balance of coins.
            storage.balance.write(storage.balance.read() + msg_amount());
        }
    }

    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address) {
        let sender = msg_sender().unwrap();
        match sender {
            Identity::Address(addr) => assert(addr == OWNER_ADDRESS),
            _ => revert(0),
        };

        let current_balance = storage.balance.read();
        assert(current_balance >= amount_to_send);

        storage.balance.write(current_balance - amount_to_send);

        // Note: `transfer()` is not a call and thus not an
        // interaction. Regardless, this code conforms to
        // checks-effects-interactions to avoid re-entrancy.
        transfer(
            Identity::Address(recipient_address),
            AssetId::base(),
            amount_to_send,
        );
    }
}
// ANCHOR_END: abi_impl
```


---

### File: docs/sway/docs/book/src/forc/commands/forc_add.md

# forc add

Adds one or more dependencies to a `Forc.toml` manifest.

## **Usage**

```bash
forc add [OPTIONS] <DEP_SPEC>...
```

## **Arguments**

* `<DEP_SPEC>`: List of dependencies in the format `name[@version]` (e.g., `custom_lib@0.1.0`, `custom_contract`)

## **Options**

* `--path <PATH>`: Add a local path dependency.
* `--git <URI>`: Add a Git-based dependency.

  * Can be combined with one of:

    * `--branch <branch>`
    * `--tag <tag>`
    * `--rev <rev>`
* `--ipfs <CID>`: Add a dependency sourced from IPFS.
* `--contract-dep`: Add to `[contract-dependencies]` instead of `[dependencies]`.
* `--salt <SALT>`: Salt to use for contract deployment (only applies to contract dependencies).
* `--package <SPEC>`: Apply change to a specific package in a workspace.
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
* `--dry-run`: Show what would be changed without writing to the file.
* `--offline`: Do not fetch any remote dependencies.
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for IPFS-sourced dependencies.


---

### File: docs/sway/docs/book/src/forc/commands/forc_addr2line.md

# forc addr2line


---

### File: docs/sway/docs/book/src/forc/commands/forc_build.md

# forc build


---

### File: docs/sway/docs/book/src/forc/commands/forc_check.md

# forc check


---

### File: docs/sway/docs/book/src/forc/commands/forc_clean.md

# forc clean


---

### File: docs/sway/docs/book/src/forc/commands/forc_completions.md

# forc completions


---

### File: docs/sway/docs/book/src/forc/commands/forc_contract-id.md

# forc contract-id


---

### File: docs/sway/docs/book/src/forc/commands/forc_init.md

# forc init


---

### File: docs/sway/docs/book/src/forc/commands/forc_new.md

# forc new


---

### File: docs/sway/docs/book/src/forc/commands/forc_parse-bytecode.md

# forc parse-bytecode


---

### File: docs/sway/docs/book/src/forc/commands/forc_plugins.md

# forc plugins


---

### File: docs/sway/docs/book/src/forc/commands/forc_predicate-root.md

# forc predicate-root


---

### File: docs/sway/docs/book/src/forc/commands/forc_remove.md

# forc remove

Removes one or more dependencies from a `Forc.toml` manifest.

## **Usage**

```bash
forc remove [OPTIONS] <DEP_SPEC>...
```

## **Arguments**

* `<DEP_SPEC>`: List of dependencies to remove by name (e.g., `custom_lib`, `custom_contract`)

## **Options**

* `--contract-dep`: Remove from `[contract-dependencies]` instead of `[dependencies]`.
* `--package <SPEC>`: Target a specific package in a workspace.
* `--manifest-path <PATH>`: Path to the `Forc.toml`.
* `--dry-run`: Preview what would be removed without making any changes.
* `--offline`: Prevent forc from fetching metadata or resolving versions remotely.
* `--ipfs-node <FUEL|PUBLIC|LOCAL|URL>`: IPFS node to use for reference.


---

### File: docs/sway/docs/book/src/forc/commands/forc_template.md

# forc template


---

### File: docs/sway/docs/book/src/forc/commands/forc_test.md

# forc test


---

### File: docs/sway/docs/book/src/forc/commands/forc_update.md

# forc update


---

### File: docs/sway/docs/book/src/forc/commands/index.md

<!-- markdownlint-disable MD041 -->
Here are a list of commands available to forc:


---

### File: docs/sway/docs/book/src/forc/dependencies.md

# Dependencies

Forc has a dependency management system which can pull packages using `git`, `ipfs`, `path`, or the community `registry`. This allows users to build and share Forc libraries.

## Adding Dependencies

You can add dependencies manually in your `Forc.toml`, or by using the `forc add` command.

### Using `forc add`

The `forc add` CLI supports various sources and optional flags:

```bash
forc add <dep> [--path <PATH>] [--git <URL> --tag <TAG>] [--ipfs <CID>] [--contract-dep]
```

#### Add Examples

* From a Git branch:

  ```bash
  forc add custom_lib --git https://github.com/FuelLabs/custom_lib --branch master
  ```

* From a local path:

  ```bash
  forc add custom_lib --path ../custom_lib
  ```

* From IPFS:

  ```bash
  forc add custom_lib --ipfs QmYwAPJzv5CZsnA...
  ```

* From registry (forc.pub):

  ```bash
  forc add custom_lib@0.0.1
  ```

* Add as a contract dependency:

  ```bash
  forc add my_contract --git https://github.com/example/contract --contract-dep
  ```

Optional:

* `--salt <HEX>` for custom contract salt.
* `--package <NAME>` to target a specific package in a workspace.
* `--manifest-path <PATH>` to specify a manifest file.

> ⚠️ **Note:**
> We do not currently support offline mode for projects that use **registry** sources.
> Also wildcard declarations `(ex: custom_lib = *)` to get the latest version available for that package or caret declarations `(ex: custom_lib = ^0.1)` to get `SemVer` compatible latest available option for a given dependency is not supported yet.

Once the package is added, running `forc build` will automatically fetch and resolve the dependencies.

### Manually Editing `Forc.toml`

If your `Forc.toml` doesn't already have a `[dependencies]` or `[contract-dependencies]` table, add one. Below, list the package name and its source.

#### Local Path

```toml
[dependencies]
custom_lib = { path = "../custom_lib" }
```

#### IPFS Source

```toml
[dependencies]
custom_lib = { ipfs = "QmYwAPJzv5CZsnA..." }
```

#### Registry Source (forc.pub)

```toml
[dependencies]
custom_lib = "0.0.1"
```

## Removing Dependencies

You can remove one or more dependencies using the `forc remove` command:

```bash
forc remove <dep> [--contract-dep] [--package <NAME>] [--manifest-path <PATH>]
```

### Remove Examples

* Remove from `[dependencies]`:

  ```bash
  forc remove custom_lib
  ```

* Remove from `[contract-dependencies]`:

  ```bash
  forc remove my_contract --contract-dep
  ```

* Target a specific package in a workspace:

  ```bash
  forc remove custom_lib --package my_project
  ```

## Updating Dependencies

To update dependencies in your Forc directory you can run:

```bash
forc update
```

For path and ipfs dependencies this will have no effect. For git dependencies with a branch reference, this will update the project to use the latest commit for the given branch.


---

### File: docs/sway/docs/book/src/forc/index.md

# Forc Reference

Forc stands for Fuel Orchestrator. Forc provides a variety of tools and commands for developers working with the Fuel ecosystem, such as scaffolding a new project, formatting, running scripts, deploying contracts, testing contracts, and more. If you're coming from a Rust background, forc is similar to cargo.

If you are new to Forc, see the [Forc Project](https://docs.fuel.network/docs/sway/introduction/forc_project/) introduction section.

For a comprehensive overview of the Forc CLI commands, see the [Commands](./commands/index.md) section.


---

### File: docs/sway/docs/book/src/forc/manifest_reference.md

# Manifest Reference

The `Forc.toml` (the _manifest_ file) is a compulsory file for each package and it is written in [TOML] format. `Forc.toml` consists of the following fields:

* [`[project]`](#the-project-section) — Defines a sway project.
  * `name` — The name of the project.
  * `version` — The version of the project.
  * `description` — A description of the project.
  * `authors` — The authors of the project.
  * `organization` — The organization of the project.
  * `license` — The project license.
  * `homepage` — URL of the project homepage.
  * `repository` — URL of the project source repository.
  * `documentation` — URL of the project documentation.
  * `categories` —  Categories of the project.
  * `keywords` —  Keywords the project.
  * `entry` — The entry point for the compiler to start parsing from.
    * For the recommended way of selecting an entry point of large libraries please take a look at: [Libraries](./../sway-program-types/libraries.md)
  * `implicit-std` -  Controls whether provided `std` version (with the current `forc` version) will get added as a dependency _implicitly_. _Unless you know what you are doing, leave this as default._
  * `forc-version` - The minimum forc version required for this project to work properly.
  * `metadata` - Metadata for the project; can be used by tools which would like to store package configuration in `Forc.toml`.

* [`[dependencies]`](#the-dependencies-section) — Defines the dependencies.
* `[network]` — Defines a network for forc to interact with.
  * `url` — URL of the network.

* [`[build-profile]`](#the-build-profile-section) - Defines the build profiles.

* [`[patch]`](#the-patch-section) - Defines the patches.

* [`[contract-dependencies]`](#the-contract-dependencies-section) - Defines the contract dependencies.

## The `[project]` section

An example `Forc.toml` is shown below. Under `[project]` the following fields are optional:

* `authors`
* `organization`
* `version`
* `description`
* `homepage`
* `repository`
* `documentation`
* `categories`
* `keywords`

Also for the following fields, a default value is provided so omitting them is allowed:

* `entry` - (default : `main.sw` )
* `implicit-std` - (default : `true` )

```toml
[project]
authors = ["user"]
entry = "main.sw"
description = "Wallet contract"
version = "1.0.0"
homepage = "https://example.com/"
repository = "https://example.com/"
documentation = "https://example.com/"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"
categories = ["example"]
keywords = ["example"]

[project.metadata]
indexing = { namespace = "counter-contract", schema_path = "out/release/counter-contract-abi.json" }
```

### Metadata Section in `Forc.toml`

The `[project.metadata]` section provides a dedicated space for external tools and plugins to store their configuration in `Forc.toml`. The metadata key names are arbitrary and do not need to match the tool's name.

#### Workspace vs Project Metadata

Metadata can be defined at two levels:

Workspace level - defined in the workspace\'s root `Forc.toml`:

```toml
[workspace.metadata]
my_tool = { shared_setting = "value" }
```

Project level - defined in individual project\'s `Forc.toml`:

```toml
[project.metadata.any_name_here]
option1 = "value"
option2 = "value"

[project.metadata.my_custom_config]
setting1 = "value"
setting2 = "value"
```

Example for an indexing tool:

```toml
[project.metadata.indexing]
namespace = "counter-contract"
schema_path = "out/release/counter-contract-abi.json"
```

When both workspace and project metadata exist:

* Project-level metadata should take precedence over workspace metadata
* Tools can choose to merge workspace and project settings
* Consider documenting your tool's metadata inheritance behavior

#### Guidelines for Plugin Developers

Best Practices

* Choose clear, descriptive metadata key names
* Document the exact metadata key name your tool expects
* Don't require `Forc.toml` if tool can function without it
* Consider using TOML format for dedicated config files
* Specify how your tool handles workspace vs project metadata

Implementation Notes

* The metadata section is optional
* Forc does not parse metadata contents
* Plugin developers handle their own configuration parsing
* Choose unique metadata keys to avoid conflicts with other tools

#### Example Use Cases

* Documentation generation settings
* Formatter configurations
* Debugger options
* Wallet integration
* Contract indexing
* Testing frameworks

This allows for a streamlined developer experience while maintaining clear separation between core Forc functionality and third-party tools.

#### External Tooling Examples

* [forc-index-ts](https://github.com/FuelLabs/example-forc-plugins/tree/master/forc-index-ts): A TypeScript CLI tool for parsing `Forc.toml` metadata to read contract ABI JSON file.
* [forc-index-rs](https://github.com/FuelLabs/example-forc-plugins/tree/master/forc-index-rs): A Rust CLI tool for parsing `Forc.toml` metadata to read contract ABI JSON file.

## The `[dependencies]` section

The following fields can be provided with a dependency:

* `version` - Desired version of the dependency
* `namespace` - If the specified registry source (by its version) also has a namespace associated with it (optional)
* `path` - The path of the dependency (if it is local)
* `git` - The URL of the git repo hosting the dependency
* `branch` - The desired branch to fetch from the git repo
* `tag` - The desired tag to fetch from the git repo
* `rev` - The desired rev (i.e. commit hash) reference

Please see [dependencies](./dependencies.md) for details

## The `[network]` section

For the following fields, a default value is provided so omitting them is allowed:

* `URL` - (default: _<http://127.0.0.1:4000>_)

## The `[build-profile.*]` section

The `[build-profile]` tables provide a way to customize compiler settings such as debug options.

The following fields can be provided for a build-profile:

* `print-ast` - Whether to print out the generated AST or not, defaults to false.
* `print-dca-graph` - Whether to print out the computed Dead Code Analysis (DCA) graph (in GraphViz DOT format), defaults to false.
* `print-dca-graph-url-format` - The URL format to be used in the generated DOT file, an example for VS Code would be: `vscode://file/{path}:{line}:{col}`.
* `print-ir` - Whether to print out the generated Sway IR (Intermediate Representation) or not, defaults to false.
* `print-asm` - Whether to print out the generated ASM (assembler), defaults to false.
* `terse` - Terse mode. Limited warning and error output, defaults to false.
* `time_phases` - Whether to output the time elapsed over each part of the compilation process, defaults to false.
* `include_tests` -  Whether or not to include test functions in parsing, type-checking, and code generation. This is set to true by invocations like `forc test`, but defaults to false.
* `error_on_warnings` - Whether to treat errors as warnings, defaults to false.

There are two default `[build-profile]` available with every manifest file. These are `debug` and `release` profiles. If you want to override these profiles, you can provide them explicitly in the manifest file like the following example:

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[build-profile.debug]
print-asm = { virtual = false, allocated = false, final = true }
print-ir = { initial = false, final = true, modified = false, passes = []}
terse = false

[build-profile.release]
print-asm = { virtual = true, allocated = false, final = true }
print-ir = { initial = true, final = false, modified = true, passes = ["dce", "sroa"]}
terse = true
```

Since `release` and `debug` are implicitly included in every manifest file, you can use them by just passing `--release` or by not passing anything (`debug` is default). For using a user defined build profile there is `--build-profile <profile name>` option available to the relevant commands. (For an example see [forc-build](../forc/commands/forc_build.md))

Note that providing the corresponding CLI options (like `--asm`) will override the selected build profile. For example if you pass both `--release` and `--asm all`, `release` build profile is overridden and resulting build profile would have a structure like the following:

```toml
print-ast = false
print-ir = { initial = false, final = false, modified = false, passes = []}
print-asm = { virtual = true, allocated = true, final = true }
terse = false
time-phases = false
include-tests = false
error-on-warnings = false
experimental-private-modules = false
```

## The `[patch]` section

The [patch] section of `Forc.toml` can be used to override dependencies with other copies. The example provided below patches `https://github.com/fuellabs/sway` with the `test` branch of the same repo.

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[dependencies]

[patch.'https://github.com/fuellabs/sway']
std = { git = "https://github.com/fuellabs/sway", branch = "test" }
```

In the example above, `std` is patched with the `test` branch from `std` repo. You can also patch git dependencies with dependencies defined with a path.

```toml
[patch.'https://github.com/fuellabs/sway']
std = { path = "/path/to/local_std_version" }
```

Just like `std` you can also patch dependencies you declared with a git repo.

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[dependencies]
foo = { git = "https://github.com/foo/foo", branch = "master" }

[patch.'https://github.com/foo']
foo = { git = "https://github.com/foo/foo", branch = "test" }
```

Note that each key after the `[patch]` is a URL of the source that is being patched.

## The `[contract-dependencies]` section

The `[contract-dependencies]` table can be used to declare contract dependencies for a Sway contract or script. Contract dependencies are the set of contracts that our contract or script may interact with. Declaring `[contract-dependencies]` makes it easier to refer to contracts in your Sway source code without having to manually update IDs each time a new version is deployed. Instead, we can use forc to pin and update contract dependencies just like we do for regular library dependencies.

Contracts declared under `[contract-dependencies]` are built and pinned just like regular `[dependencies]` however rather than importing each contract dependency's entire public namespace we instead import their respective contract IDs as `CONTRACT_ID` constants available via each contract dependency's namespace root. This means you can use a contract dependency's ID as if it were declared as a `pub const` in the root of the contract dependency package as demonstrated in the example below.

Entries under `[contract-dependencies]` can be declared in the same way that `[dependencies]` can be declared. That is, they can refer to the `path` or `git` source of another contract. Note that entries under `[contract-dependencies]` must refer to contracts and will otherwise produce an error.

Example `Forc.toml`:

```toml
[project]
authors = ["user"]
entry = "main.sw"
organization = "Fuel_Labs"
license = "Apache-2.0"
name = "wallet_contract"

[contract-dependencies]
foo = { path = "../foo" }
```

Example usage:

```sway
script;

fn main() {
  let foo_id = foo::CONTRACT_ID;
}
```

Because the ID of a contract is computed deterministically, rebuilding the same contract would always result in the same contract ID. Since two contracts with the same contract ID cannot be deployed on the blockchain, a "salt" factor is needed to modify the contract ID. For each contract dependency declared under `[contract-dependencies]`, `salt` can be specified. An example is shown below:

```toml
[contract-dependencies]
foo = { path = "../foo", salt = "0x1000000000000000000000000000000000000000000000000000000000000000" }
```

For contract dependencies that do not specify any value for `salt`, a default of all zeros for `salt` is implicitly applied.


---

### File: docs/sway/docs/book/src/forc/plugins/forc_client/forc_call.md

# forc call


---

### File: docs/sway/docs/book/src/forc/plugins/forc_client/forc_deploy.md

# forc deploy


---

### File: docs/sway/docs/book/src/forc/plugins/forc_client/forc_run.md

# forc run


---

### File: docs/sway/docs/book/src/forc/plugins/forc_client/forc_submit.md

# forc submit


---

### File: docs/sway/docs/book/src/forc/plugins/forc_client/index.md

# forc-client

The forc plugin for interacting with a Fuel node.

Since transactions are going to require some gas, you need to sign them with an account that has enough coins to pay for them.

We offer multiple ways to sign the transaction:

  1. Sign the transaction via your local wallet using `forc-client` which integrates with our CLI wallet, `forc-wallet`.
  2. Use the default signer to deploy to a local node
  3. Use `forc-wallet` to manually sign transactions, and copy the signed transaction back to `forc-client`.

The easiest and recommended way to interact with deployed networks such as our testnets is option 1, using `forc-client` to sign your transactions which reads your default `forc-wallet` vault. For interacting with local node, we recommend using the second option, which leads `forc-client` to sign transactions with the private key that comes pre-funded in local environments.

## Option 1: Sign transactions via forc-client using your local forc-wallet vault

If you've used `forc-wallet` before, you'll already have a secure, password-protected vault holding your private key written to your file-system. `forc-client` is compatible with `forc-wallet` such that it can read that vault by asking you your password and use your account to sign transactions.

Example:

```console
> forc deploy

    Building /Users/yourname/test-projects/test-contract
    Finished release [optimized + fuel] target(s) in 11.39s
  Confirming transactions [deploy impl-contract]
             Network: https://testnet.fuel.network
             Wallet: /Users/yourname/.fuel/wallets/.wallet
✔ Wallet password · ********
? Wallet account ›
❯ [0] fuel12pls73y9hnqdqthvduy2x44x48zt8s50pkerf32kq26f2afeqdwq6rj9ar - 0.002197245 ETH
  [1] fuel1vzrm6kw9s3tv85gl25lpptsxrdguyzfhq6c8rk07tr6ft5g45nwqqh0uty - 0.001963631 ETH
? Do you agree to sign 1 transaction? (y/n) › yes
     Finished deploying impl-contract https://app.fuel.network/contract/0x94b712901f04332682d14c998a5fc5a078ed15321438f46d58d0383200cde43d
     Deployed in block https://app.fuel.network/block/5958351
```

As it can be seen from the example, `forc-client` asks for your password to decrypt the `forc-wallet` vault, and list your accounts so that you can select the one you want to fund the transaction with.

## Option 2: Using default signer

If you are not interacting with a deployed network, such as testnets, your local `fuel-core` environment can be structured such that it funds an account by default. Using `--default-signer` flag with `forc-client` binaries (run, deploy) will instruct `forc-client` to sign transactions with this pre-funded account. This makes it a useful command while working against a local node.

Example:

```console
> forc deploy --default-signer

    Building /Users/test/test-projects/test-contract
    Finished release [optimized + fuel] target(s) in 11.40s
  Confirming transactions [deploy impl-contract]
             Network: http://127.0.0.1:4000
    Finished deploying impl-contract 0xf9fb08ef18ce226954270d6d4f67677d484b8782a5892b3d436572b405407544
    Deployed in block 00000001
```

## Option 3: Manually signing through forc-wallet (Deprecated)

This option is for creating the transaction first, signing it manually, and supplying the signed transaction back to forc-client. Since it requires multiple steps, it is more error-prone and not recommended for general use cases. Also this will be deprecated soon.

1. Construct the transaction by using either `forc deploy` or `forc run`. To do so simply run `forc deploy --manual-sign` or `forc run --manual-sign` with your desired parameters. For a list of parameters please refer to the [forc-deploy](./forc_deploy.md) or [forc-run](./forc_run.md) section of the book. Once you run either command you will be asked the address of the wallet you are going to be signing with. After the address is given the transaction will be generated and you will be given a transaction ID. At this point CLI will actively wait for you to insert the signature.
2. Take the transaction ID generated in the first step and sign it with `forc wallet sign --account <account_index> tx-id <transaction_id>`. This will generate a signature.
3. Take the signature generated in the second step and provide it to `forc-deploy` (or `forc-run`). Once the signature is provided, the signed transaction will be submitted.

## Other useful commands of `forc-wallet`

- You can see a list of existing accounts with `accounts` command.

```sh
forc wallet accounts
```

- If you want to retrieve the address for an account by its index you can use `account` command.

```sh
forc wallet account <account_index>
```

> If you want to sign the transaction generated by `forc-deploy` or `forc-run` with an account funded by default once you start your local node, you can pass `--default-signer` to them. Please note that this will only work against your local node.
>
> ```sh
> forc-deploy --default-signer
> ```
>
> ```sh
> forc-run --default-signer
> ```

By default `--default-signer` flag would sign your transactions with the following private-key:

```sh
0xde97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c
```

## Selecting a target network

By default, `local` is used for the target network. To interact with the latest testnet, use the `--testnet` flag. When this flag is passed, transactions created by `forc-deploy` will be sent to the latest `testnet`:

```sh
forc-deploy --testnet
```

The same can be done to target mainnet:

```sh
forc-deploy --mainnet
```

It is also possible to pass the exact node URL while using `forc-deploy` or `forc-run` which can be done using `--node-url` flag:

```sh
forc-deploy --node-url https://mainnet.fuel.network
```

Another alternative is the `--target` option, which provides useful aliases to all targets. For example if you want to deploy to `testnet` you can use:

```sh
forc-deploy --target testnet
```

Since deploying and running projects on the testnet cost gas, you will need coins to pay for them. You can get some using the [testnet faucet](https://faucet-testnet.fuel.network/).

## Delayed transactions

For delayed transactions, you can use the `--submit-only` flag. This flag allows you to submit the transaction without waiting for its finalization.

One use case for this is multisig transactions, where a deployment transaction may stay in a pending state while waiting for all signatures.

```sh
forc-deploy --submit-only
```

## Deployment Artifacts

forc-deploy saves the details of each deployment in the `out/deployments` folder within the project's root directory. Below is an example of a deployment artifact:

```json
{
  "transaction_id": "0xec27bb7a4c8a3b8af98070666cf4e6ea22ca4b9950a0862334a1830520012f5d",
  "salt": "0x9e35d1d5ef5724f29e649a3465033f5397d3ebb973c40a1d76bb35c253f0dec7",
  "network_endpoint": "http://127.0.0.1:4000",
  "chain_id": 0,
  "contract_id": "0x767eeaa7af2621e637f9785552620e175d4422b17d4cf0d76335c38808608a7b",
  "deployment_size": 68,
  "deployed_block_id": "0x915c6f372252be6bc54bd70df6362dae9bf750ba652bf5582d9b31c7023ca6cf"
}
```

## Proxy Contracts

`forc-deploy` supports deploying proxy contracts automatically if it is enabled in the `Forc.toml` of the contract.

```TOML
[project]
name = "test_contract"
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
implicit-std = false

[proxy]
enabled = true
```

If there is no `address` field present under the proxy table, like the example above, `forc` will automatically create a proxy contract based on the [SRC-14](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-14-simple-upgradeable-proxies.md) implementation from [sway-standards](https://github.com/FuelLabs/sway-standards). After generating and deploying the proxy contract, the target is set to the current contract, and the owner of the proxy is set to the account that is signing the transaction for deployment.

This means that if you simply enable proxy in the `Forc.toml`, forc will automatically deploy a proxy contract for you and you do not need to do anything manually aside from signing the deployment transactions for the proxy contract. After deploying the proxy contract, the address is added into the `address` field of the proxy table.

If you want to update the target of an [SRC-14](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-14-simple-upgradeable-proxies.md) compliant proxy contract rather than deploying a new one, simply add its `address` in the `address` field, like the following example:

```TOML
[project]
name = "test_contract"
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
implicit-std = false

[proxy]
enabled = true
address = "0xd8c4b07a0d1be57b228f4c18ba7bca0c8655eb6e9d695f14080f2cf4fc7cd946" # example proxy contract address
```

If an `address` is present, `forc` calls into that contract to update its `target` instead of deploying a new contract. Since a new proxy deployment adds its own `address` into the `Forc.toml` automatically, you can simply enable the proxy once and after the initial deployment, `forc` will keep updating the target accordingly for each new deployment of the same contract.

## Large Contracts

For contracts over the maximum contract size limit (currently `100kB`) defined by the network, `forc-deploy` will split the contract into chunks and deploy the contract with multiple transactions using the Rust SDK's [loader contract](https://github.com/FuelLabs/fuels-rs/blob/master/docs/src/deploying/large_contracts.md) functionality. Chunks that have already been deployed will be reused on subsequent deployments.

## Deploying Scripts and Predicates

`forc deploy` now supports deploying scripts and predicates in addition to contracts. These are deployed as blobs with generated loaders for efficiency.

Scripts and predicates are deployed automatically when you run `forc deploy` on a project that contains them. The deployment process differs slightly from contract deployment:

1. For scripts and predicates, the bytecode is uploaded as a blob.
2. A loader is generated that can load and execute the blob.
3. The loader bytecode is saved in the project's output directory.

After deployment, you'll find new files in your project's output directory:

- For scripts: `<script_name>-loader.bin`
- For predicates: `<predicate_name>-loader.bin` and `<predicate_name>-loader-root`

The loader files contain the bytecode necessary to load and execute your script or predicate from the deployed blob.

This new deployment method allows for more efficient storage and execution of scripts and predicates on the Fuel network.

Note: Contracts are still deployed directly, not as blobs given that the contract size is under the maximum contract size limit defined by network (currently `100kB`).


---

### File: docs/sway/docs/book/src/forc/plugins/forc_crypto.md

# forc crypto


---

### File: docs/sway/docs/book/src/forc/plugins/forc_debug.md

# forc debug


---

### File: docs/sway/docs/book/src/forc/plugins/forc_doc.md

# forc doc


---

### File: docs/sway/docs/book/src/forc/plugins/forc_explore.md

# forc explore


---

### File: docs/sway/docs/book/src/forc/plugins/forc_fmt.md

# forc fmt


---

### File: docs/sway/docs/book/src/forc/plugins/forc_lsp.md

# forc lsp


---

### File: docs/sway/docs/book/src/forc/plugins/forc_migrate.md

# forc migrate


---

### File: docs/sway/docs/book/src/forc/plugins/forc_node.md

# forc node


---

### File: docs/sway/docs/book/src/forc/plugins/forc_publish.md

# forc publish


---

### File: docs/sway/docs/book/src/forc/plugins/index.md

# Plugins

Plugins can be used to extend `forc` with new commands that go beyond the native commands mentioned in the previous chapter. While the Fuel ecosystem provides a few commonly useful plugins (`forc-fmt`, `forc-client`, `forc-lsp`, `forc-explore`), anyone can write their own!

Let's install a plugin, `forc-explore`, and see what's underneath the plugin:

```sh
cargo install forc-explore
```

Check that we have installed `forc-explore`:

```console
$ forc plugins
Installed Plugins:
forc-explore
```

`forc-explore` runs the Fuel Network Explorer, which you can run and check out for yourself:

```console
$ forc explore
Fuel Network Explorer 0.1.1
Running server on http://127.0.0.1:3030
Server::run{addr=127.0.0.1:3030}: listening on http://127.0.0.1:3030
```

You can visit <http://127.0.0.1:3030> to check out the network explorer!

Note that some plugin crates can also provide more than one command. For example, installing the `forc-client` plugin provides the `forc deploy` and `forc run` commands. This is achieved by specifying multiple `[[bin]]` targets within the `forc-client` manifest.

## Writing your own plugin

We encourage anyone to write and publish their own `forc` plugin to enhance their development experience.

Your plugin must be named in the format `forc-<MY_PLUGIN>` and you may use the above template as a starting point. You can use [clap](https://docs.rs/clap/latest/clap/) and add more subcommands, options and configurations to suit your plugin's needs.


---

### File: docs/sway/docs/book/src/forc/workspaces.md

# Workspaces

A *workspace* is a collection of one or more packages, namely *workspace members*, that are managed together.

The key points for workspaces are:

* Common `forc` commands available for a single package can also be used for a workspace, like `forc build` or `forc deploy`.
* All packages share a common `Forc.lock` file which resides in the root directory of the workspace.

Workspace manifests are declared within `Forc.toml` files and support the following fields:

* [`members`](#the-members-field) - Packages to include in the workspace.
* [`[patch]`](#the-patch-section) - Defines the patches.

An empty workspace can be created with `forc new --workspace` or `forc init --workspace`.

## The `members` field

The `members` field defines which packages are members of the workspace:

```toml
[workspace]
members = ["member1", "path/to/member2"]
```

The `members` field accepts entries to be given in relative path with respect to the workspace root.
Packages that are located within a workspace directory but are *not* contained within the `members` set are ignored.

## The `[patch]` section

The `[patch]` section can be used to override any dependency in the workspace dependency graph. The usage is the same with package level `[patch]` section and details can be seen [here](./manifest_reference.md#the-patch-section).

It is not allowed to declare patch table in member of a workspace if the workspace manifest file contains a patch table.

Example:

```toml
[workspace]
members = ["member1", "path/to/member2"]


[patch.'https://github.com/fuellabs/sway']
std = { git = "https://github.com/fuellabs/sway", branch = "test" }
```

In the above example each occurrence of `std` as a dependency in the workspace will be changed with `std` from `test` branch of sway repo.

## Some `forc` commands that support workspaces

* `forc build` - Builds an entire workspace.
* `forc deploy` - Builds and deploys all deployable members (i.e, contracts) of the workspace in the correct order.
* `forc run` - Builds and runs all scripts of the workspace.
* `forc check` - Checks all members of the workspace.
* `forc update` - Checks and updates workspace level `Forc.lock` file that is shared between workspace members.
* `forc clean` - Cleans all output artifacts for each member of the workspace.
* `forc fmt` - Formats all members of a workspace.


---

### File: docs/sway/docs/book/src/index.md

# The Sway Programming Language

Welcome to the Sway programming language book 🌴.

**Q: Hi! What is Sway?**

Sway is a domain-specific programming language for implementing smart contracts on blockchain platforms, most notably for the [Fuel Virtual Machine (Fuel VM)](https://docs.fuel.network/docs/specs/fuel-vm/).

Heavily inspired by [Rust](https://doc.rust-lang.org/book/)'s approach to systems programming, Sway aims to bring modern programming language features and tooling to smart contract development whilst retaining performance, fine grained control and making extensive use of static analysis to prevent common security issues.

**Q: What does "domain-specific" mean?**

Sway is specifically made to be used within a blockchain environment, which behaves very differently than traditional computers.
This domain specific design permits it to make the right decisions about trade-offs at every level of the stack, enabling you to write fast, secure and cost effective smart contracts with features suited to your specific needs.

**Q: Why not use Solidity?**

Solidity is a venerable pioneer but it suffers from being tied to a lot of the historical quirks of the EVM.
It lacks common features programmers have come to expect, has a relatively inexpressive type system, and it lacks a unified tooling ecosystem.

In Sway, we let you design smart contracts with a full modern box of tools.
You get a fully featured language with generics, algebraic types and trait based polymorphism.
You also get an integrated, unified and easy to use toolchain with code completion LSP server, formatter, documentation generation and everything you need to run and deploy your contracts so that nothing comes between you and implementing what you want.

Our expressive type system allows you to catch semantic mistakes, we provide good defaults and we do extensive static analysis checks (such as enforcing the [Checks, Effects, Interactions](./blockchain-development/calling_contracts.md#cei-pattern-violation-static-analysis) pattern) so that you can make sure you write secure and correct code at compile time.

**Q: Why not use Rust?**

Whilst Rust is a great systems programming language (and Sway itself is written in Rust), it isn't suited for smart contract development.

Rust shines because it can use zero-cost abstractions and its sophisticated borrow-checker memory model to achieve impressive runtime performance for complex programs without a garbage collector.

On a blockchain, cost of execution and deployment is the scarce resource.
Memory usage is low and execution time is short.
This makes complex memory management in general much too expensive to be worthwhile and Rust's borrow checker a burden with no upside.

General purpose programming languages in general are ill suited to this environment because their design has to assume execution on a general-purpose computing environment.

Sway attempts to bring all the other advantages of Rust, including its modern type system, approach to safety and good defaults to smart contract developers by providing familiar syntax and features adapted to the specific needs of the blockchain environment.

**Q: I don't know Rust or Solidity. Can I still learn Sway?**

Yes! If you are familiar with the basics of programming, blockchain, and using a terminal you can build with Sway.

**Q: What can I build with Sway?**

You can build smart contracts and their components and libraries for them.
You can learn more about the different program types and how they fit together in the [Program Types](./sway-program-types/index.md) section.

**Q: Do I need to install anything?**

If you want to develop with Sway in your local environment, you need to install [`fuelup`](https://docs.fuel.network/guides/installation/) and your editor of choice that supports LSP, such as [VSCode](https://code.visualstudio.com/).

If you don't want to install anything just yet, you can use the [Sway Playground](https://www.sway-playground.org/) to edit, compile, and deploy Sway code.

**Q: Where can I find example Sway code?**

You can find example applications built with Sway in the [Sway Applications repository](https://github.com/FuelLabs/sway-applications) on GitHub. You can also find projects building on Fuel in the [Fuel ecosystem home](https://app.fuel.network/ecosystem).

**Q: What is the standard library?**

The [standard library](./introduction/standard_library.md), also referred to as `std`, is a library that offers core functions and helpers for developing in Sway. The standard library has its own [reference documentation](https://fuellabs.github.io/sway/master/std/) that has detailed information about each module in `std`.

**Q: What are Sway standards?**

Similar to ERC standards for Ethereum and Solidity, Sway has its own SRC standards that help enable cross compatibility across different smart contracts. For more information on using a Sway Standard, you can check out the [Sway-Standards Repository](https://github.com/FuelLabs/sway-standards).

**Q: How can I make a token?**

Sway has multiple native assets. To mint a new native asset, check out the [native assets](./blockchain-development/native_assets.md) page.

**Q: How can I make an NFT?**

You can find an example of an NFT contract in Sway in the [Sway Applications repo](https://github.com/FuelLabs/sway-applications/tree/master/NFT).

**Q: How can I test Sway code?**

Sway provides [unit testing](./testing/unit-testing.md), so you can test your Sway code with Sway. You can also use the Fuel [Rust SDK](https://docs.fuel.network/docs/fuels-rs/testing/) or [TypeScript SDK](https://docs.fuel.network/docs/fuels-ts/testing/) to test your Sway programs.

**Q: How can I deploy a contract?**

You can use the `forc deploy` command to deploy a contract. For a detailed guide on how to deploy a contract, refer to the [quickstart guide](https://docs.fuel.network/docs/intro/quickstart-contract/).

**Q: Is there a way to convert Solidity code to Sway?**

Yes! You can use the Solidity to Sway transpiler built in to the [Sway Playground](https://www.sway-playground.org/) to convert Solidity code into Sway code. Note that the transpiler is still experimental, and may not work in every case.

**Q: How can I get help with Sway?**

If you run into an issue or have a question, post it on the [Fuel forum](https://forum.fuel.network/) so someone in the Fuel community can help.

**Q: Where should I get started?**

*Ready to build?* You can find step-by-step guides for how to build an application with Sway in the [Fuel Developer Guides](https://docs.fuel.network/guides/).

*Want to read?* Get started by reading the [Introduction](./introduction/index.md) and [Basics](./basics/index.md) sections of this book.


---

### File: docs/sway/docs/book/src/introduction/forc_project.md

# A Forc Project

To initialize a new project with Forc, use `forc new`:

```sh
forc new my-fuel-project
```

Here is the project that Forc has initialized:

<!-- This section should show the tree for a new forc project -->
<!-- tree:example:start -->
```console
$ cd my-fuel-project
$ tree .
├── Forc.toml
└── src
    └── main.sw
```
<!-- tree:example:end -->

<!-- This section should explain the `Forc.toml` file -->
<!-- forc_toml:example:start -->
`Forc.toml` is the _manifest file_ (similar to `Cargo.toml` for Cargo or `package.json` for Node), and defines project metadata such as the project name and dependencies.
<!-- forc_toml:example:end -->

For additional information on dependency management, see: [here](../forc/dependencies.md).

```toml
[project]
authors = ["User"]
entry = "main.sw"
license = "Apache-2.0"
name = "my-fuel-project"

[dependencies]
```

Here are the contents of the only Sway file in the project, and the main entry point, `src/main.sw`:

```sway
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

The project is a _contract_, one of four different project types. For additional information on different project types, see [here](../sway-program-types/index.md).

We now compile our project with `forc build`, passing the flag `--asm final` to view the generated assembly:

```console
$ forc build --asm final
...
.program:
ji   i4
noop
DATA_SECTION_OFFSET[0..32]
DATA_SECTION_OFFSET[32..64]
lw   $ds $is 1
add  $$ds $$ds $is
lw   $r0 $fp i73              ; load input function selector
lw   $r1 data_0               ; load fn selector for comparison
eq   $r2 $r0 $r1              ; function selector comparison
jnzi $r2 i12                  ; jump to selected function
movi $$tmp i123               ; special code for mismatched selector
rvrt $$tmp                    ; revert if no selectors matched
ret  $one
.data:
data_0 .word 559005003

  Compiled contract "my-fuel-project".
  Bytecode size is 60 bytes.
```


---

### File: docs/sway/docs/book/src/introduction/fuel_toolchain.md

# The Fuel Toolchain

The Fuel toolchain consists of several components.

## Forc (`forc`)

The "Fuel Orchestrator" [Forc](https://github.com/FuelLabs/sway/tree/master/forc) is our equivalent of Rust's [Cargo](https://doc.rust-lang.org/cargo/). It is the primary entry point for creating, building, testing, and deploying Sway projects.

## Sway Language Server (`forc-lsp`)

The Sway Language Server `forc-lsp` is provided to expose features to IDEs. [Installation instructions](../lsp/installation.md).

## Sway Formatter (`forc-fmt`)

A canonical formatter is provided with `forc-fmt`. [Installation instructions](./getting_started.md). It can be run manually with

```sh
forc fmt
```

The [Visual Studio Code plugin](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin) will
automatically format Sway files with `forc-fmt` on save, though you might have to explicitly set the Sway plugin as the
default formatter, like this:

```json
"[sway]": {
  "editor.defaultFormatter": "FuelLabs.sway-vscode-plugin"
}
```

## Fuel Core (`fuel-core`)

An implementation of the Fuel protocol, [Fuel Core](https://github.com/FuelLabs/fuel-core), is provided together with the _Sway toolchain_ to form the _Fuel toolchain_. [The Rust SDK](https://github.com/FuelLabs/fuels-rs) will automatically start and stop an instance of the node during tests, so there is no need to manually run a node unless using Forc directly without the SDK.


---

### File: docs/sway/docs/book/src/introduction/getting_started.md

# Getting Started

## Installing the `Fuel` toolchain

Please visit the Fuel [Installation Guide](https://docs.fuel.network/guides/installation) to install the Fuel toolchain binaries and prerequisites.

## Sway Quickstart

Check out the [Developer Quickstart Guide](https://docs.fuel.network/guides/quickstart/) for a step-by-step guide on building a fullstack dapp on Fuel. The guide will walk you through writing a smart contract, setting up a wallet, and building a frontend to interact with your contract.


---

### File: docs/sway/docs/book/src/introduction/index.md

# Introduction

To get started with Forc and Sway smart contract development, install the Fuel toolchain and Fuel full node and set up your first project.

- [Getting Started](./getting_started.md)
- [The Fuel Toolchain](./fuel_toolchain.md)
- [A Forc Project](./forc_project.md)
- [Standard Library](./standard_library.md)
- [Sway Language Standards](./sway_standards.md)


---

### File: docs/sway/docs/book/src/introduction/standard_library.md

# Standard Library

<!-- This section should explain what the std-lib is -->
<!-- std_lib:example:start -->
Similar to Rust, Sway comes with its own standard library.

The Sway Standard Library is the foundation of portable Sway software, a set of minimal shared abstractions for the broader Sway ecosystem. It offers core types, like `Result<T, E>` and `Option<T>`, library-defined operations on language primitives, native asset management, blockchain contextual operations, access control, storage management, and support for types from other VMs, among many other things.
<!-- std_lib:example:end -->

The entire Sway standard library is a Forc project called `std`, and is available directly [here](https://github.com/FuelLabs/sway/tree/master/sway-lib-std). Navigate to the appropriate tagged release if the latest `master` is not compatible. You can find the latest `std` documentation [here](https://fuellabs.github.io/sway/master/std/).

## Using the Standard Library

The standard library is made implicitly available to all Forc projects created using [`forc new`](../forc/commands/forc_new.md). In other words, it is not required to manually specify `std` as an explicit dependency. Forc will automatically use the version of `std` that matches its version.

Importing items from the standard library can be done using the `use` keyword, just as importing items from any Sway project. For example:

```sway
use std::storage::storage_vec::*;
```

This imports the `StorageVec` type into the current namespace.

## Standard Library Prelude

<!-- This section should explain what the std-lib prelude is -->
<!-- prelude:example:start -->
Sway comes with a variety of things in its standard library. However, if you had to manually import every single thing that you used, it would be very verbose. But importing a lot of things that a program never uses isn't good either. A balance needs to be struck.

The prelude is the list of things that Sway automatically imports into every Sway program. It's kept as small as possible, and is focused on things which are used in almost every single Sway program.

The current version of the prelude lives in [`std::prelude`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/prelude.sw), and re-exports the following:

- [`std::address::Address`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/address.sw), a wrapper around the `b256` type representing a wallet address.
- [`std::contract_id::ContractId`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/contract_id.sw), a wrapper around the `b256` type representing the ID of a contract.
- [`std::identity::Identity`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/identity.sw), an enum with two possible variants: `Address: Address` and `ContractId: ContractId`.
- [`std::vec::Vec`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/vec.sw), a growable, heap-allocated vector.
- [`std::storage::storage_key::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/storage/storage_key.sw), contains the API for accessing a `std::storage::StorageKey` which describes a location in storage.
- [`std::storage::storage_map::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/storage/storage_map.sw), a key-value mapping in contract storage.
- [`std::option::Option`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/option.sw), an enum which expresses the presence or absence of a value.
- [`std::result::Result`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/result.sw), an enum for functions that may succeed or fail.
- [`std::assert::assert`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/assert.sw), a function that reverts the VM if the condition provided to it is `false`.
- [`std::assert::assert_eq`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/assert.sw), a function that reverts the VM and logs its two inputs `v1` and `v2` if the condition `v1` == `v2` is `false`.
- [`std::assert::assert_ne`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/assert.sw), a function that reverts the VM and logs its two inputs `v1` and `v2` if the condition `v1` != `v2` is `false`.
- [`std::revert::require`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/revert.sw), a function that reverts the VM and logs a given value if the condition provided to it is `false`.
- [`std::revert::revert`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/revert.sw), a function that reverts the VM.
- [`std::logging::log`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/logging.sw), a function that logs arbitrary stack types.
- [`std::auth::msg_sender`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/auth.sw), a function that gets the `Identity` from which a call was made.
- [`std::primitives::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/primitives.sw), methods on primitive types.
- [`std::primitive_conversions::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/primitive_conversions.sw), methods for converting between primitive types.
- [`std::raw_ptr::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/raw_ptr.sw), functions for working with raw pointers.
- [`std::raw_slice::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/raw_slice.sw), functions for working with raw slices.
- [`std::ops::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/ops.sw), mathematical operations such as addition, subtraction, multiplication, and division.
- [`std::str::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/str.sw), methods for working with strings.
- [`std::codec::*`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/codec.sw), automatic serialization and deserialization of types.
<!-- prelude:example:end -->


---

### File: docs/sway/docs/book/src/introduction/sway_standards.md

# Sway Standards

Just like many other smart contract languages, usage standards have been developed to enable cross compatibility between smart contracts.

For more information on using a Sway Standard, please refer to the [Sway-Standards Repository](https://github.com/FuelLabs/sway-standards).

## Standards

### Native Asset Standards

- [SRC-20; Native Asset Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md) defines the implementation of a standard API for [Native Assets](../blockchain-development/native_assets.md) using the Sway Language.
- [SRC-3; Mint and Burn](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md) is used to enable mint and burn functionality for Native Assets.
- [SRC-7; Arbitrary Asset Metadata Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) is used to store metadata for [Native Assets](../blockchain-development/native_assets.md), usually as NFTs.
- [SRC-9; Metadata Keys Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-9-metadata-keys.md) is used to store standardized metadata keys for [Native Assets](../blockchain-development/native_assets.md) in combination with the SRC-7 standard.
- [SRC-6; Vault Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-6-vault.md) defines the implementation of a standard API for asset vaults developed in Sway.

### Predicate Standards

- [SRC-13; Soulbound Address Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-13-soulbound-address.md) defines a specific `Address` as a Soulbound Address for Soulbound Assets to become non-transferable.

### Access Control Standards

- [SRC-5; Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md) is used to restrict function calls to admin users in contracts.

### Contract Standards

- [SRC-12; Contract Factory](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-12-contract-factory.md) defines the implementation of a standard API for contract factories.

### Bridge Standards

- [SRC-8; Bridged Asset](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-8-bridged-asset.md) defines the metadata required for an asset bridged to the Fuel Network.
- [SRC-10; Native Bridge Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-10-native-bridge.md) defines the standard API for the Native Bridge between the Fuel Chain and the canonical base chain.

### Documentation Standards

- [SRC-2; Inline Documentation](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-2-inline-documentation.md) defines how to document your Sway files.

## Standards Support

Libraries have also been developed to support Sway Standards. These can be in [Sway-Libs](../reference/sway_libs.md).


---

### File: docs/sway/docs/book/src/lsp/features.md

# Features

## Code Actions

_Source:_ [code_actions](https://github.com/FuelLabs/sway/tree/master/sway-lsp/src/capabilities/code_actions)

Quickly generate boilerplate code and code comments for functions, structs, and ABIs.

## Completion

_Source:_ [completion.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/completion.rs)

Suggests code to follow partially written statements for functions and variables.

## Go to Definition

Jumps to the definition of a symbol from its usage.

## Find All References

Locates all occurrences of a symbol throughout the project.

## Hover

_Source:_ [hover](https://github.com/FuelLabs/sway/tree/master/sway-lsp/src/capabilities/hover)

Provides documentation, compiler diagnostics, and reference links when hovering over functions and variables.

## Inlay Hints

_Source:_ [inlay_hints.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/inlay_hints.rs)

Displays the implied type of a variable next to the variable name. Configurable in Settings.

## Rename

_Source:_ [rename.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/rename.rs)

Renames a symbol everywhere in the workspace.

## Diagnostics

_Source:_ [diagnostic.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/diagnostic.rs)

Displays compiler warnings and errors inline.

## Syntax Highlighting

_Source:_ [highlight.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/highlight.rs)

Highlights code based on type and context.

## Run

_Source:_ [runnable.rs](https://github.com/FuelLabs/sway/blob/master/sway-lsp/src/capabilities/runnable.rs)

Shows a button above a runnable function or test.


---

### File: docs/sway/docs/book/src/lsp/index.md

# Sway LSP

Welcome to the documentation for Sway LSP, the language server designed specifically for the Sway programming language. This documentation serves as a comprehensive guide to help you understand and utilize the powerful features provided by Sway LSP.

Sway LSP is built on the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) (LSP), a standardized protocol for enabling rich programming language support in editor and IDE environments. It acts as a bridge between your favorite code editor or integrated development environment and the Sway programming language, offering advanced semantic analysis and a wide range of features to enhance your development experience.

With Sway LSP, you can expect a seamless and efficient coding experience while working with the Sway programming language. It provides intelligent code completion, precise symbol navigation, type information, and other smart features that empower you to write clean and error-free code. By leveraging the power of Sway LSP, you can increase productivity, reduce debugging time, and write high-quality code with confidence.

In this documentation, you will find detailed information about how to set up Sway LSP in your preferred code editor or IDE, configure its settings to match your coding style, and take advantage of its various features. We will guide you through the installation process, provide examples of typical configuration setups, and walk you through the usage of each feature supported by Sway LSP.

Whether you are a beginner or an experienced Sway developer, this documentation aims to be your go-to resource for understanding and maximizing the capabilities of Sway LSP. So let's dive in and unlock the full potential of the Sway programming language with Sway LSP!

- [Installation](./installation.md)
- [Features](./features.md)
- [Troubleshooting](./troubleshooting.md)


---

### File: docs/sway/docs/book/src/lsp/installation.md

# Installation

The Sway language server is contained in the [`forc-lsp`](../forc/plugins/forc_lsp.md) binary, which is installed as part of the [Fuel toolchain](../introduction/fuel_toolchain.md). Once installed, it can be used with a variety of IDEs. It must be installed for any of the IDE plugins to work.

> **Note**: There is no need to manually run `forc-lsp` (the plugin will automatically start it), however both `forc` and `forc-lsp` must be in your `$PATH`. To check if `forc` is in your `$PATH`, type `forc --help` in your terminal.

## VSCode

This is the best supported editor at the moment.

You can install the latest release of the plugin from the [marketplace](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin).

Note that we only support the most recent version of VS Code.

## Code OSS (VSCode on Linux)

1. Install [code-marketplace](https://aur.archlinux.org/packages/code-marketplace) to get access to all of the extensions in the VSCode marketplace.
2. Install the [Sway](https://marketplace.visualstudio.com/items?itemName=FuelLabs.sway-vscode-plugin) extension.

## vim / neovim

Follow the documentation for [sway.vim](https://github.com/FuelLabs/sway.vim) to install.

## helix

[Install helix](https://docs.helix-editor.com/install.html) and Sway LSP will work out of the box.

Sway support is built into helix using [tree-sitter-sway](https://github.com/FuelLabs/tree-sitter-sway).

## Emacs

Coming soon! Feel free to [contribute](https://github.com/FuelLabs/sway/issues/3527).


---

### File: docs/sway/docs/book/src/lsp/troubleshooting.md

# Troubleshooting

First, confirm you are running the most recent version:

```sh
fuelup toolchain install latest
fuelup update
forc-lsp --version
```

Second, confirm that your `$PATH` resolves to the `forc-lsp` binary in `$HOME/.fuelup/bin`.

```sh
which forc-lsp
```

## Slow Performance

If you are experiencing slow performance, you can try the following:

Follow [the steps above](#troubleshooting) to ensure you are running the most recent version.

Then, make sure you only have the most recent version of the LSP server running.

```sh
pkill forc-lsp
```

### Large projects

Sway projects with ten or more Sway files are likely to have slower LSP performance. We are working on better support for large projects.

In the meantime, if it's too slow, you can disable the LSP server entirely with the `sway-lsp.diagnostic.disableLsp` setting. The extension will still provide basic syntax highlighting, command palettes, as well as the Sway debugger, but all other language features will be disabled.

## Server Logs

You can enable verbose logging of the LSP server.

In VSCode, this is under the setting:

```json
"sway-lsp.trace.server": "verbose"
```

Once enabled, you can find this in the output window under Sway Language Server.

For other editors, see [Installation](./installation.md) for links to documentation.


---

### File: docs/sway/docs/book/src/reference/attributes.md

# Attributes

Attributes are a form of metadata that can additionally instruct Sway compiler or other tools like `forc test`. Attributes can annotate different language elements, like, e.g., items, enum variants, struct fields, etc.

Below is the list of attributes supported by the Sway compiler, ordered alphabetically:

- [Allow](#allow)
- [Cfg](#cfg)
- [Deprecated](#deprecated)
- [Error](#error)
- [Error Type](#error-type)
- [Fallback](#fallback)
- [Inline](#inline)
- [Payable](#payable)
- [Storage](#payable)
- [Test](#test)

## Allow

The `#[allow(...)]` attribute disables compiler checks so that certain warnings will go unreported. The following warnings can be disabled:

- `#[allow(dead_code)]` disables warnings for dead code;
- `#[allow(deprecated)]` disables warnings for usage of deprecated elements, like, e.g., structs, functions, enum variants, etc.

## Cfg

The `#[cfg(...)]` attribute allows conditional compilation. The annotated code element will be compiled only if the condition in to the `cfg` attribute evaluates to true. The following conditions can be expressed:

- `#[cfg(target = "<target>")]` where `<target>` can be either "evm" or "fuel";
- `#[cfg(program_type = "<program_type>")]` where `<program_type>` can be either "predicate", "script", "contract", or "library";
- `#[cfg(experimental_<feature_flag> = true/false)]` where `<feature_flag>` is one of the known experimental feature flags.

## Deprecated

The `#[deprecated]` attribute marks an item as deprecated and makes the compiler emit a warning for every usage of the deprecated item. This warning can be disabled using `#[allow(deprecated)]`.

It is possible to improve the warning message with `#[deprecated(note = "Your deprecation message.")]`

## Error

The `#[error]` defines an error message for an error type enum variant:

```sway
#[error_type]
enum SomeErrors {
    #[error(m = "An unexpected error occurred.")]
    UnexpectedError: (),
}
```

## Error Type

The `#[error_type]` marks an enum as error type enum:

```sway
#[error_type]
enum SomeErrors {
    ...
}
```

All variants of an error type enum must be annotated with the [`#[error]` attribute](#error). Error type enums are meant to be use in `panic` expressions for rich error reporting.

## Fallback

The `#[fallback]` attribute makes the compiler use the marked function as the contract call fallback function. This means that, when a contract method is called, and the contract method selection fails, the fallback function will be called instead.

More details in [Calling Contracts](../blockchain-development/calling_contracts.md#fallback).

## Inline

The inline attribute *suggests* to the compiler if a copy of the annotated function should be placed in the caller, rather than generating code to call the function where it is defined.

The `#[inline(never)]` attribute *suggests* that an inline expansion should never be performed.

The `#[inline(always)]` attribute *suggests* that an inline expansion should always be performed.

> **Note**: `#[inline(..)]` in every form is a hint, with no *requirements* on the compiler to place a copy of the annotated function in the caller. The Sway compiler automatically inlines functions based on internal heuristics. Incorrectly inlining functions can make the program slower, so this attribute should be used with care.

## Payable

The lack of `#[payable]` implies the method is non-payable. When calling an ABI method that is non-payable, the compiler emits an error if the amount of coins forwarded with the call is not guaranteed to be zero. Note that this is strictly a compile-time check and does not incur any runtime cost.

## Storage

In Sway, functions are pure by default but can be opted into impurity via the `storage` function attribute. The `storage` attribute may take `read` and/or `write` arguments indicating which type of access the function requires.

The `#[storage(read)]` attribute indicates that a function requires read access to the storage.

The `#[storage(write)]` attribute indicates that a function requires write access to the storage.

More details in [Purity](../blockchain-development/purity.md).

## Test

The `#[test]` attribute marks a function to be executed as a test.

The `#[test(should_revert)]` attribute marks a function to be executed as a test that should revert.

More details in [Unit Testing](../testing/unit-testing.md).


---

### File: docs/sway/docs/book/src/reference/compiler_intrinsics.md

# Compiler Intrinsics

The Sway compiler supports a list of intrinsics that perform various low level operations that are useful for building libraries. Compiler intrinsics should rarely be used but are preferred over `asm` blocks because they are type-checked and are safer overall. Below is a list of all available compiler intrinsics:

---

```sway
__size_of_val<T>(val: T) -> u64
```

**Description:** Return the size of type `T` in bytes.

**Constraints:** None.

---

```sway
__size_of<T>() -> u64
```

**Description:** Return the size of type `T` in bytes.

**Constraints:** None.

---

```sway
__size_of_str_array<T>() -> u64
```

**Description:** Return the size of type `T` in bytes. This intrinsic differs from `__size_of` in the case of "string arrays" where the actual length in bytes of the string is returned without padding the byte size to the next word alignment. When `T` is not a "string array" `0` is returned.

**Constraints:** None.

---

```sway
__assert_is_str_array<T>()
```

**Description:** Throws a compile error if type `T` is not a "string array".

**Constraints:** None.

---

```sway
__to_str_array(s: str) -> str[N]
```

**Description:** Converts a "string slice" to "string array" at compile time. Parameter "s" must be a string literal.

**Constraints:** None.

---

```sway
__is_reference_type<T>() -> bool
```

**Description:** Returns `true` if `T` is a _reference type_ and `false` otherwise.

**Constraints:** None.

---

```sway
__is_str_array<T>() -> bool
```

**Description:** Returns `true` if `T` is a string array and `false` otherwise.

**Constraints:** None.

---

```sway
__eq<T>(lhs: T, rhs: T) -> bool
```

**Description:** Returns whether `lhs` and `rhs` are equal.

**Constraints:** `T` is `bool`, `u8`, `u16`, `u32`, `u64`, `u256`, `b256` or `raw_ptr`.

---

```sway
__gt<T>(lhs: T, rhs: T) -> bool
```

**Description:** Returns whether `lhs` is greater than `rhs`.

**Constraints:** `T` is `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__lt<T>(lhs: T, rhs: T) -> bool
```

**Description:** Returns whether `lhs` is less than `rhs`.

**Constraints:** `T` is `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__gtf<T>(index: u64, tx_field_id: u64) -> T
```

**Description:** Returns transaction field with ID `tx_field_id` at index `index`, if applicable. This is a wrapper around FuelVM's [`gtf` instruction](https://fuellabs.github.io/fuel-specs/master/vm/instruction_set#gtf-get-transaction-fields). The resulting field is cast to `T`.

**Constraints:** None.

---

```sway
__addr_of<T>(val: T) -> raw_ptr
```

**Description:** Returns the address in memory where `val` is stored.

**Constraints:** `T` is a reference type.

---

```sway
__state_load_word(key: b256) -> u64
```

**Description:** Reads and returns a single word from storage at key `key`.

**Constraints:** None.

---

```sway
__state_load_quad(key: b256, ptr: raw_ptr, slots: u64) -> bool
```

**Description:** Reads `slots` number of slots (`b256` each) from storage starting at key `key` and stores them in memory starting at address `ptr`. Returns a Boolean describing whether all the storage slots were previously set.

**Constraints:** None.

---

```sway
__state_store_word(key: b256, val: u64) -> bool
```

**Description:** Stores a single word `val` into storage at key `key`. Returns a Boolean describing whether the store slot was previously set.

**Constraints:** None.

---

```sway
__state_store_quad(key: b256, ptr: raw_ptr, slots: u64) -> bool
```

**Description:** Stores `slots` number of slots (`b256` each) starting at address `ptr` in memory into storage starting at key `key`. Returns a Boolean describing whether the first storage slot was previously set.

**Constraints:** None.

---

```sway
__log<T>(val: T) where T: AbiEncode
```

**Description:** Logs value `val`.

**Constraints:**

- `T` must implement AbiEncode

---

```sway
__add<T>(lhs: T, rhs: T) -> T
```

**Description:** Adds `lhs` and `rhs` and returns the result.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__sub<T>(lhs: T, rhs: T) -> T
```

**Description:** Subtracts `rhs` from `lhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__mul<T>(lhs: T, rhs: T) -> T
```

**Description:** Multiplies `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__div<T>(lhs: T, rhs: T) -> T
```

**Description:** Divides `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__and<T>(lhs: T, rhs: T) -> T
```

**Description:** Bitwise AND `lhs` and `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__or<T>(lhs: T, rhs: T) -> T
```

**Description:** Bitwise OR `lhs` and `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__xor<T>(lhs: T, rhs: T) -> T
```

**Description:** Bitwise XOR `lhs` and `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__mod<T>(lhs: T, rhs: T) -> T
```

**Description:** Modulo of `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`.

---

```sway
__rsh<T>(lhs: T, rhs: u64) -> T
```

**Description:** Logical right shift of `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__lsh<T>(lhs: T, rhs: u64) -> T
```

**Description:** Logical left shift of `lhs` by `rhs`.

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__revert(code: u64)
```

**Description:** Reverts with error code `code`.

**Constraints:** None.

---

```sway
__ptr_add(ptr: raw_ptr, offset: u64)
```

**Description:** Adds `offset` to the raw value of pointer `ptr`.

**Constraints:** None.

---

```sway
__ptr_sub(ptr: raw_ptr, offset: u64)
```

**Description:** Subtracts `offset` to the raw value of pointer `ptr`.

**Constraints:** None.

---

```sway
__smo<T>(recipient: b256, data: T, coins: u64)
```

**Description:** Sends a message `data` of arbitrary type `T` and `coins` amount of the base asset to address `recipient`.

**Constraints:** None.

---

```sway
__not(op: T) -> T
```

**Description:** Bitwise NOT of `op`

**Constraints:** `T` is an integer type, i.e. `u8`, `u16`, `u32`, `u64`, `u256`, `b256`.

---

```sway
__jmp_mem()
```

**Description:** Jumps to `MEM[$hp]`.

**Constraints:** None.

---

```sway
__slice<T>(item: &[T; N], start: u64, end: u64) -> &[T]
__slice<T>(item: &[T], start: u64, end: u64) -> &[T]
__slice<T>(item: &mut [T; N], start: u64, end: u64) -> &mut [T]
__slice<T>(item: &mut [T], start: u64, end: u64) -> &mut [T]
```

**Description:** Slices an array or another slice.

This intrinsic returns a reference to a slice containing the range of elements inside `item`.
The mutability of reference is defined by the first parameter mutability.

Runtime bound checks are not generated, and must be done manually when and where appropriated. Compile time bound checks are done when possible.

**Constraints:**

- `item` is an array or a slice;
- when `start` is a literal, it must be smaller than `item` length;
- when `end` is a literal, it must be smaller than or equal to `item` length;
- `end` must be greater than or equal to `start`

---

```sway
__elem_at<T>(item: &[T; N], index: u64) -> &T
__elem_at<T>(item: &[T], index: u64) -> &T
__elem_at<T>(item: &mut [T; N], index: u64) -> &mut T
__elem_at<T>(item: &mut [T], index: u64) -> &mut T
```

**Description:** Returns a reference to the indexed element. The mutability of reference is defined by the first parameter mutability.

Runtime bound checks are not generated, and must be done manually when and where appropriated. Compile time bound checks are done when possible.

**Constraints:**

- `item` is a reference to an array or a reference to a slice;
- when `index` is a literal, it must be smaller than `item` length;

---

```sway
__dbg<T>(value: T) -> T where T: Debug
```

**Description:** Automatically calls the `Debug` trait on the passed `value`, with file, line and column information. The passed value is returned without any modification, allowing `__dbg(...)` to be used inside of any expression.

The code generated by this intrinsic function varies with the compilation mode. For example:

```terminal
forc build            <- will print everything as expected
forc build --release  <- nothing will be printed
```

To enable code generation even on `Release` builds, the flag `force-dbg-in-release` needs to be enabled inside `forc.toml`.
Example:

```toml
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
license = "Apache-2.0"
entry = "main.sw"
name = "some-project"
force-dbg-in-release = true
```

It is strongly suggested to always remove this flag before publishing binaries as it will not have any effect when running
on real nodes and it only increases gas usage.

**Constraints:**

- `T` must implement Debug


---

### File: docs/sway/docs/book/src/reference/contributing_to_sway.md

# Contributing To Sway

Thanks for your interest in contributing to Sway! This document outlines the process for installing and setting up the Sway toolchain for development, as well as some conventions on contributing to Sway.

If you run into any difficulties getting started, you can always ask questions on our [Discourse](https://forum.fuel.network/).

## Building and setting up a development workspace

See the [introduction](../introduction/index.md) section for instructions on installing and setting up the Sway toolchain.

## Getting the repository

1. Visit the [Sway](https://github.com/FuelLabs/sway) repo and fork the project.
2. Then clone your forked copy to your local machine and get to work.

```sh
git clone https://github.com/FuelLabs/sway
cd sway
```

## Building and testing

The following steps will run the sway test suite and ensure that everything is set up correctly.

First, open a new terminal and start `fuel-core` with:

```sh
fuel-core
```

Then open a second terminal, `cd` into the `sway` repo and run:

```sh
cargo run --bin test
```

After the test suite runs, you should see:

```console
Tests passed.
_n_ tests run (0 skipped)
```

Congratulations! You've now got everything setup and are ready to start making contributions.

## Finding something to work on

There are many ways in which you may contribute to the Sway project, some of which involve coding knowledge and some which do not. A few examples include:

- Reporting bugs
- Adding documentation to the Sway book
- Adding new features or bug fixes for which there is already an open issue
- Making feature requests

Check out our [Help Wanted](https://github.com/FuelLabs/sway/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22), [Sway Book](https://github.com/FuelLabs/sway/issues?q=is%3Aopen+is%3Aissue+label%3A%22The+Sway+Book%22) or [Good First Issue](https://github.com/FuelLabs/sway/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) issues to find a suitable task.

If you are planning something big, for example, related to multiple components or changes current behaviors, make sure to open an issue to discuss with us before starting on the implementation.

## Contribution flow

This is a rough outline of what a contributor's workflow looks like:

- Make sure what you want to contribute is already tracked as an issue.
  - We may discuss the problem and solution in the issue.
- Create a Git branch from where you want to base your work. This is usually master.
- Write code, add test cases, and commit your work.
- Run tests and make sure all tests pass.
- If the PR contains any breaking changes, add the breaking label to your PR.
- Push your changes to a branch in your fork of the repository and submit a pull request.
  - Make sure to mention the issue, which is created at step 1, in the commit message.
- Your PR will be reviewed and some changes may be requested.
  - Once you've made changes, your PR must be re-reviewed and approved.
  - If the PR becomes out of date, you can use GitHub's 'update branch' button.
  - If there are conflicts, you can merge and resolve them locally. Then push to your PR branch.
    Any changes to the branch will require a re-review.
- Our CI system (Github Actions) automatically tests all authorized pull requests.
- Use Github to merge the PR once approved.

Thanks for your contributions!

### Linking issues

Pull requests should be linked to at least one issue in the same repo.

If the pull request resolves the relevant issues, and you want GitHub to close these issues automatically after it merged into the default branch, you can use the syntax (`KEYWORD #ISSUE-NUMBER`) like this:

```markdown
close #123
```

If the pull request links an issue but does not close it, you can use the keyword `ref` like this:

```markdown
ref #456
```

Multiple issues should use full syntax for each issue and separate by a comma, like:

```markdown
close #123, ref #456
```


---

### File: docs/sway/docs/book/src/reference/index.md

# Sway Reference

- [Compiler Intrinsics](./compiler_intrinsics.md)
- [Attributes](./attributes.md)
- [Style Guide](./style_guide.md)
- [Known Issues and Workarounds](./known_issues_and_workarounds.md)
- [Differences from Rust](./rust_differences.md)
- [Differences from Solidity](./solidity_differences.md)
- [Contributing to Sway](./contributing_to_sway.md)
- [Keywords](./keywords.md)


---

### File: docs/sway/docs/book/src/reference/keywords.md

# Keywords

The following list contains keywords that are reserved for current or
future use by the Sway language. As such, **they cannot be used as
identifiers**. Identifiers are names of functions, variables,
parameters, modules, constants, attributes, types or
traits, etc.

## Keywords Currently in Use

The following is an alphabetically sorted list of keywords currently in use, with their
functionality shortly described.

- `as` - rename items in `use` statements, e.g., `use type::type_name as alias_name;`
- [`abi`](../sway-program-types/smart_contracts.md#the-abi-declaration) - define a smart contract ABI in a syntactically similar way to traits
- [`asm`](../advanced/assembly.md) - define an assembly block
- [`break`](../basics/control_flow.md#break-and-continue) - exit a loop immediately
- `configurable` - define configurable constants
- [`const`](../basics/constants.md) - define constant
- [`continue`](../basics/control_flow.md#break-and-continue) - continue to the next loop iteration
- [`contract`](../sway-program-types/smart_contracts.md) - define contract program type
- `else` - used in conjunction with `if` conditions for control flow constructs
- [`enum`](../basics/structs_tuples_and_enums.md#enums) - define an enum
- `false` - Boolean false literal
- [`for`](../basics/control_flow.md#for) - loop based on iterators
- [`fn`](../basics/functions.md)- define a function
- [`if`](../basics/control_flow.md#if-expressions) - branch based on the result of a conditional expression
- `impl` - implement inherent or trait functionality
- `let` - bind a variable
- [`library`](../sway-program-types/libraries.md) - define library program type
- [`match`](../basics/control_flow.md#match-expressions) - exhaustively match a value to patterns
- `mod` - define a module
- `mut` - denote mutability
- `pub` - denote public visibility
- [`predicate`](../sway-program-types/predicates.md) - define predicate program type
- `ref` - bind by reference
- `return` - return early from a function
- [`script`](../sway-program-types/scripts.md) - define script program type
- `Self` - a type alias for the type we are defining or implementing
- `self` - method call target
- [`storage`](../blockchain-development/storage.md) - define a storage declaration
- `str`- string slice
- [`struct`](../basics/structs_tuples_and_enums.md#structs) - define a structure
- [`trait`](../advanced/traits.md#declaring-a-trait) - define a trait
- `true` - Boolean true literal
- [`type`](../advanced/advanced_types.md#creating-type-synonyms-with-type-aliases) - define a type alias or associated type
- `use` - bring symbols into scope
- `where` - specifies trait constraints for generic type arguments
- [`while`](../basics/control_flow.md#while) - loop conditionally based on the result of an expression

## Keywords Reserved for Possible Future Use

- `abstract`
- `async`
- `await`
- `become`
- `box`
- `do`
- `dyn`
- `extern`
- `for`
- `in`
- `loop`
- `macro`
- `move`
- `override`
- `priv`
- `static`
- `super`
- `try`
- `typeof`
- `unsafe`
- `unsized`
- `virtual`
- `yield`


---

### File: docs/sway/docs/book/src/reference/known_issues_and_workarounds.md

# Known Issues and Workarounds

## Known Issues

* [#870](https://github.com/FuelLabs/sway/issues/870): All `impl` blocks need to be defined before any of the functions they define can be called.  This includes sibling functions in the same `impl` declaration, i.e., functions in an `impl` can't call each other yet.

## Missing Features

* [#1182](https://github.com/FuelLabs/sway/issues/1182) Arrays in a `storage` block are not yet supported. See the [Manual Storage Management](../advanced/advanced_storage.md#manual-storage-management) section for details on how to use `store` and `get` from the standard library to manage storage slots directly. Note, however, that `StorageMap<K, V>` _does_ support arbitrary types for `K` and `V` without any limitations.

## General

* No compiler optimization passes have been implemented yet, therefore bytecode will be more expensive and larger than it would be in production. Note that eventually the optimizer will support zero-cost abstractions, avoiding the need for developers to go down to inline assembly to produce optimal code.


---

### File: docs/sway/docs/book/src/reference/rust_differences.md

# Differences From Rust

Sway shares a lot with Rust, especially its syntax. Because they are so similar, you may be surprised or caught off guard when they differ. This page serves to outline, from a high level, some of the syntactic _gotchas_ that you may encounter.

## Enum Variant Syntax

In Rust, enums generally take one of three forms: _unit_ variants, which have no inner data, _struct_ variants, which contain named fields, and _tuple_ variants, which contain within them a tuple of data. If you are unfamiliar with these terms, this is what they look like:

```rust,ignore
// note to those skimming the docs: this is Rust syntax! Not Sway! Don't copy/paste this into a Sway program.

enum Foo {
    UnitVariant,
    TupleVariant(u32, u64, bool),
    StructVariant {
        field_one: bool,
        field_two: bool
    }
}
```

In Sway, enums are simplified. Enums variants must all specify exactly one type. This type represents their interior data. This is actually isomorphic to what Rust offers, but with a different syntax. You can see the above enum but with Sway syntax below:

```sway
// This is equivalent Sway syntax for the above Rust enum.
enum Foo {
    UnitVariant: (),
    TupleVariant: (u32, u64, bool),
    StructVariant: MyStruct,
}

struct MyStruct {
    field_one: bool,
    field_two: bool,
}
```

## Memory Allocation

In Rust, the borrow checker implements Rust's [ownership system](https://doc.rust-lang.org/1.8.0/book/ownership.html)

In Sway, there is no borrow checker.  This means there is no concept of ownership, borrowing, or lifetimes.  Instead, objects are copied and moved similar to C++.  Also Sway does not have any destructors nor `Drop` traits.  This means allocated memory lives for the entire transaction and is not deallocated until the end of the transaction.  A transaction may allocate up to [64 MB](https://github.com/FuelLabs/fuel-vm/blob/a80f82ed7c793763de6a73ca72d946b311b0fd0b/fuel-vm/src/consts.rs#L26) of memory.


---

### File: docs/sway/docs/book/src/reference/solidity_differences.md

# Differences From Solidity

This page outlines some of the critical differences between Sway and Solidity, and between the FuelVM and the EVM.

## Underlying Virtual Machine

The underlying virtual machine targeted by Sway is the FuelVM, specified [here](https://github.com/FuelLabs/fuel-specs). Solidity targets the Ethereum Virtual Machine (EVM), specified [here](https://ethereum.github.io/yellowpaper/paper.pdf).

## Word Size

Words in the FuelVM are 64 bits (8 bytes), rather than the 256 bits (32 bytes) of the EVM. Therefore, all primitive integers smaller and including `u64` are stored in registers; `u256`, being bigger than the registers, and hashes (the `b256` type) are not stored in registers but rather in memory. They are therefore pointers to a 32-byte memory region containing their data.

## Unsigned Integers Only

Only unsigned integers are provided as primitives: `u8`, `u16`, `u32`, `u64`, and `u256`. Signed integer arithmetic is not available in the FuelVM. Signed integers and signed integer arithmetic can be implemented in high-level libraries if needed.

## Global Revert

Panics in the FuelVM (called "reverts" in Solidity and the EVM) are global, i.e. they cannot be caught. A panic will completely and unconditionally revert the stateful effects of a transaction, minus gas used.

## Default Safe Math

<!-- This section should explain safe math in Fuel vs EVM -->
<!-- safe_math:example:start -->
Math in the FuelVM is by default safe (i.e. any overflow or exception is a panic). Safety checks are performed natively in the VM implementation, rather than at the bytecode level like [Solidity's default safe math](https://docs.soliditylang.org/en/latest/080-breaking-changes.html#silent-changes-of-the-semantics).
<!-- safe_math:example:end -->

## No* Code Size Limit

There is no practical code size limit to Sway contracts. The physical limit is governed by the [`VM_MAX_RAM` VM parameter](https://fuellabs.github.io/fuel-specs/master/vm#parameters), which at the time of writing is 64 MiB.

## Account Types

Account types in the FuelVM have type-safe wrappers around primitive `b256` hashes to clearly distinguish their respective types. The wrapper `Address` mirrors that of an EOA (Externally Owned Account) and has the ability to hold UTXOs in the context of the EVM. The other wrapper, `ContractId`, reflects that of a deployed contract in the EVM but cannot hold UTXOs.


---

### File: docs/sway/docs/book/src/reference/style_guide.md

# Style Guide

## Capitalization

<!-- This section should explain the capitalization style guide -->
<!-- cap:example:start -->
In Sway, structs, traits, and enums are `CapitalCase`. Modules, variables, and functions are `snake_case`, constants are `SCREAMING_SNAKE_CASE`. The compiler will warn you if your capitalization is ever unidiomatic.
<!-- cap:example:end -->


---

### File: docs/sway/docs/book/src/reference/sway_libs.md

# Sway Libraries

The purpose of Sway Libraries is to contain libraries which users can import and use that are not part of the standard library.

These libraries contain helper functions and other tools valuable to blockchain development.

For more information on how to use a Sway-Libs library, please refer to the [Sway-Libs Book](https://fuellabs.github.io/sway-libs/book/getting_started/index.html).

## Assets Libraries

Asset Libraries are any libraries that use [Native Assets](../blockchain-development/native_assets.md) on the Fuel Network.

- [Asset Library](https://fuellabs.github.io/sway-libs/book/asset/index.html); provides helper functions for the [SRC-20](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-20-native-asset.md), [SRC-3](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-3-minting-and-burning.md), and [SRC-7](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-7-asset-metadata.md) standards.

## Access Control and Security Libraries

Access Control and Security Libraries are any libraries that are built and intended to provide additional safety when developing smart contracts.

- [Ownership Library](https://fuellabs.github.io/sway-libs/book/ownership/index.html); used to apply restrictions on functions such that only a **single** user may call them. This library provides helper functions for the [SRC-5; Ownership Standard](https://github.com/FuelLabs/sway-standards/blob/master/docs/src/src-5-ownership.md).
- [Admin Library](https://fuellabs.github.io/sway-libs/book/admin/index.html); used to apply restrictions on functions such that only a select few users may call them like a whitelist.
- [Pausable Library](https://fuellabs.github.io/sway-libs/book/pausable/index.html); allows contracts to implement an emergency stop mechanism.
- [Reentrancy Guard Library](https://fuellabs.github.io/sway-libs/book/reentrancy/index.html); used to detect and prevent reentrancy attacks.

## Cryptography Libraries

Cryptography Libraries are any libraries that provided cryptographic functionality beyond what the std-lib provides.

- [Bytecode Library](https://fuellabs.github.io/sway-libs/book/bytecode/index.html); used for on-chain verification and computation of bytecode roots for contracts and predicates.
- [Merkle Proof Library](https://fuellabs.github.io/sway-libs/book/merkle/index.html); used to verify Binary Merkle Trees computed off-chain.

## Math Libraries

Math Libraries are libraries which provide mathematic functions or number types that are outside of the std-lib's scope.

- [Signed Integers Library](https://fuellabs.github.io/sway-libs/book/signed_integers/index.html); an interface to implement signed integers.

## Data Structures Libraries

Data Structure Libraries are libraries which provide complex data structures which unlock additional functionality for Smart Contracts.

- [Queue Library](https://fuellabs.github.io/sway-libs/book/queue/index.html); a linear data structure that provides First-In-First-Out (FIFO) operations.


---

### File: docs/sway/docs/book/src/reference/undefined_behavior.md

# Behavior Considered Undefined

Sway code that contains any of the following behavior is considered undefined.
The compiler is allowed to treat undefined Sway code however it desires,
including removing it or replacing it with any other Sway code.

This is not an exhaustive list, it may grow or shrink, there is no formal model
of Sway's semantics so there may be more behavior considered undefined. We
reserve the right to make some of the listed behavior defined in the future.

* Invalid arithmetic operations (overflows, underflows, division by zero, etc.).
* Misuse of compiler intrinsics.
* Incorrect use of inline assembly.
* Reading and writing `raw_ptr` and `raw_slice`.
* Slicing and indexing out of bounds by directly using compiler intrinsics.
* Modifying collections while iterating over them using `Iterator`s.


---

### File: docs/sway/docs/book/src/sway-program-types/index.md

# Sway Program Types

<!-- This section should explain program types -->
<!-- programs:example:start -->
A Sway program itself has a type: it is either a _contract_, a _predicate_, a _script_, or a _library_. The first three of these things are all deployable to the blockchain. A _library_ is simply a project designed for code reuse and is never directly deployed to the chain.

Every Sway file _must_ begin with a declaration of what type of program it is. A project can have many libraries within it, but only one contract, script, or predicate. Scripts and predicates require `main` functions to serve as entry points, while contracts instead publish an ABI. This chapter will go into detail about all of these various types of programs and what purposes they serve.
<!-- programs:example:end -->

Contracts are used primarily for protocols or systems that operate within a fixed set of rules. A good example would be a staking contract or a decentralized exchange (also called a DEX).

Scripts are used for complex on-chain interactions that won't persist. An example of this may be using a DEX and Lender to create a leveraged position (borrow, swap, re-collateralize) which is a complex transaction that would usually take multiple steps.

Libraries are for code that is reusable and useful for handling common situations. A good example of this would be a library to handle fixed-point math or big number math.

- [Contracts](./smart_contracts.md)
- [Libraries](./libraries.md)
- [Scripts](./scripts.md)
- [Predicates](./predicates.md)


---

### File: docs/sway/docs/book/src/sway-program-types/libraries.md

# Libraries

<!-- This section should explain what a library is -->
<!-- library:example:start -->
Libraries in Sway are files used to define new common behavior.
<!-- library:example:end -->

The most prominent example of this is the [Sway Standard Library](../introduction/standard_library.md) that is made implicitly available to all Forc projects created using `forc new`.

## Writing Libraries

<!-- This section should explain how libraries are defined -->
<!-- def_lib:example:start -->
Libraries are defined using the `library` keyword at the beginning of a file, followed by a name so that they can be imported.
<!-- def_lib:example:end -->

```sway
library;

// library code
```

A good reference library to use when learning library design is the [Sway Standard Library](../introduction/standard_library.md). For example, the standard library offers an [implementation](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/option.sw) of `enum Option<T>` which is a generic type that represents either the existence of a value using the variant `Some(..)` or a value's absence using the variant `None`. The [Sway file implementing `Option<T>`](https://github.com/FuelLabs/sway/blob/master/sway-lib-std/src/option.sw) has the following structure:

- The `library` keyword:

```sway
library;
```

- A `use` statement that imports `revert` from another library _inside_ the standard library:

```sway
use ::revert::revert;
```

- The `enum` definition which starts with the keyword `pub` to indicate that this `Option<T>` is publicly available _outside_ the `option` library:

```sway
pub enum Option<T> {
    // variants
}
```

- An `impl` block that implements some methods for `Option<T>`:

```sway
impl<T> Option<T> {

    fn is_some(self) -> bool {
        // body of is_some
    }

    // other methods
}
```

Now that the library `option` is fully written, and because `Option<T>` is defined with the `pub` keyword, we are now able to import `Option<T>` using `use std::option::Option;` from any Sway project and have access to all of its variants and methods. That being said, `Option` is automatically available in the [standard library prelude](../introduction/standard_library.md#standard-library-prelude) so you never actually have to import it manually.

Libraries are composed of just a `Forc.toml` file and a `src` directory, unlike contracts which usually contain a `tests` directory and a `Cargo.toml` file as well. An example of a library's `Forc.toml`:

```toml
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "lib.sw"
license = "Apache-2.0"
name = "my_library"

[dependencies]
```

which denotes the authors, an entry file, the name by which it can be imported, and any dependencies.

For large libraries, it is recommended to have a `lib.sw` entry point re-export all other sub-libraries.

<!-- This section should explain the `mod` keyword -->
<!-- mod:example:start -->
The `mod` keyword registers a submodule, making its items (such as functions and structs) accessible from the parent library.
If used at the top level it will refer to a file in the `src` folder and in other cases in a folder named after the library in which it is defined.
<!-- mod:example:end -->

For example, the `lib.sw` of the standard library looks like:

```sway
library;

mod block;
mod storage;
mod constants;
mod vm;
// .. Other deps
```

with other libraries contained in the `src` folder, like the `vm` library (inside of `src/vm.sw`):

```sway
library;

mod evm;
// ...
```

and it's own sub-library `evm` located in `src/vm/evm.sw`:

```sway
library;

// ...
```

## Using Libraries

There are two types of Sway libraries, based on their location and how they can be imported.

### Internal Libraries

Internal libraries are located within the project's `src` directory alongside
`main.sw` or in the appropriate folders as shown below:

```bash
$ tree
.
├── Cargo.toml
├── Forc.toml
└── src
    ├── internal_lib.sw
    ├── main.sw
    └── internal_lib
        └── nested_lib.sw
```

As `internal_lib` is an internal library, it can be imported into `main.sw` as follows:

- Use the `mod` keyword followed by the library name to make the internal library a dependency
- Use the `use` keyword with a `::` separating the name of the library and the imported item(s)

```sway
mod internal_lib; // Assuming the library name in `internal_lib.sw` is `internal_lib`

use internal_lib::mint;

// `mint` from `internal_library` is now available in this file
```

### External Libraries

External libraries are located outside the main `src` directory as shown below:

```bash
$ tree
.
├── my_project
│   ├── Cargo.toml
│   ├── Forc.toml
│   └─── src
│       └── main.sw
│
└── external_lib
    ├── Cargo.toml
    ├── Forc.toml
    └─── src
        └── lib.sw
```

As `external_lib` is outside the `src` directory of `my_project`, it needs to be added as a dependency in the `Forc.toml` file of `my_project`, by adding the library path in the `dependencies` section as shown below, before it can be imported:

```toml
[dependencies]
external_library = { path = "../external_library" }
```

Once the library dependency is added to the `toml` file, you can import items from it as follows:

- Make sure the item you want imported are declared with the `pub` keyword (if applicable, for instance: `pub fn mint() {}`)
- Use the `use` keyword to selectively import items from the library

```sway
use external_library::mint;

// `mint` from `external_library` is now available in this file
```

Wildcard imports using `*` are supported, but it is generally recommended to use explicit imports where possible.

> **Note**: the standard library is implicitly available to all Forc projects, that is, you are not required to manually specify `std` as an explicit dependency in `Forc.toml`.

## Reference Sway Libraries

The repository [`sway-libs`](https://github.com/FuelLabs/sway-libs/) is a collection of external libraries that you can import and make use of in your Fuel applications. These libraries are meant to be implementations of common use-cases valuable for dapp development.

Some Sway Libraries to try out:

- [Binary Merkle Proof](https://docs.fuel.network/docs/sway-libs/merkle/)
- [Signed Integers](https://github.com/FuelLabs/sway-libs/tree/master/libs/src/signed_integers)
- [Ownership](https://github.com/FuelLabs/sway-libs/tree/master/libs/src/ownership)

### Example

You can import and use a Sway Library such as the [Ownership](https://github.com/FuelLabs/sway-libs/tree/master/libs/src/ownership) library just like any other external library.

```sway
use ownership::Ownership;
```

Once imported, you can use the following basic functionality of the library in your smart contract:

- Declaring an owner
- Changing ownership
- Renouncing ownership
- Ensuring a function may only be called by the owner


---

### File: docs/sway/docs/book/src/sway-program-types/predicates.md

# Predicates

From the perspective of Sway, predicates are programs that return a Boolean value and which represent ownership of some resource upon execution to true. They have no access to contract storage. Here is a trivial predicate, which always evaluates to true:

```sway
predicate;

// All predicates require a main function which returns a Boolean value.
fn main() -> bool {
    true
}
```

The address of this predicate is `0xd19a5fe4cb9baf41ad9813f1a6fef551107c8e8e3f499a6e32bccbb954a74764`. Any assets sent to this address can be unlocked or claimed by executing the predicate above as it always evaluates to true.

It does not need to be deployed to a blockchain because it only exists during a transaction. That being said, the predicate address is on-chain as the owner of one or more UTXOs.

## Transfer Coins to a Predicate

In Fuel, coins can be sent to a predicate's address(the bytecode root, calculated [here](https://github.com/FuelLabs/fuel-specs/blob/master/src/identifiers/predicate-id.md)).

## Spending Predicate Coins

The coin UTXOs become spendable not on the provision of a valid signature, but rather if the supplied predicate both has a root that matches their owner, and [evaluates](https://github.com/FuelLabs/fuel-specs/blob/master/src/fuel-vm/index.md#predicate-verification) to `true`.

If a predicate reverts, or tries to access impure VM opcodes, the evaluation is automatically `false`.

An analogy for predicates is rather than a traditional 12 or 24 word seed phrase that generates a private key and creates a valid signature, a predicate's code can be viewed as the private key. Anyone with the code may execute a predicate, but only when the predicate evaluates to true may the assets owned by that address be released.

## Spending Conditions

Predicates may introspect the transaction spending their coins (inputs, outputs, script bytecode, etc.) and may take runtime arguments, either or both of which may affect the evaluation of the predicate.

It is important to note that predicates cannot read or write memory. They may however check the inputs and outputs of a transaction. For example in the [OTC Predicate Swap Example](https://github.com/FuelLabs/sway-applications/tree/master/OTC-swap-predicate), a user may specify they would like to swap `asset1` for `asset2` and with amount of `5`. The user would then send `asset1` to the predicate. Only when the predicate can verify that the outputs include `5` coins of `asset2` being sent to the original user, may `asset1` be transferred out of the predicate.


---

### File: docs/sway/docs/book/src/sway-program-types/scripts.md

# Scripts

A script is runnable bytecode on the chain which executes once to perform some task. It does not represent ownership of any resources and it cannot be called by a contract. A script can return a single value of any type.

Scripts are state-aware in that while they have no persistent storage (because they only exist during the transaction) they can call contracts and act based upon the returned values and results.

This example script calls a contract:

```sway
script;

use wallet_abi::Wallet;

fn main() {
    let contract_address = 0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b;
    let caller = abi(Wallet, contract_address);
    let amount_to_send = 200;
    let recipient_address = Address::from(0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b);
    caller
        .send_funds {
            gas: 10000,
            coins: 0,
            asset_id: b256::zero(),
        }(amount_to_send, recipient_address);
}

```

Scripts, similar to predicates, rely on a `main()` function as an entry point. You can call other functions defined in a script from the `main()` function or call another contract via an [ABI cast](./smart_contracts.md#calling-a-smart-contract-from-a-script).

An example use case for a script would be a router that trades funds through multiple decentralized exchanges to get the price for the input asset, or a script to re-adjust a Collateralized Debt Position via a flash loan.

## Scripts and the SDKs

Unlike EVM transactions which can call a contract directly (but can only call a single contract), Fuel transactions execute a script, which may call zero or more contracts. The Rust and TypeScript SDKs provide functions to call contract methods as if they were calling contracts directly. Under the hood, the SDKs wrap all contract calls with scripts that contain minimal code to simply make the call and forward script data as call parameters.


---

### File: docs/sway/docs/book/src/sway-program-types/smart_contracts.md

# What is a Smart Contract?

<!-- This section should explain what is a smart contract -->
<!-- contract:example:start -->
A smart contract is no different than a script or predicate in that it is a piece of bytecode that is deployed to the blockchain via a [transaction](https://fuellabs.github.io/fuel-specs/master/protocol/tx_format). The main features of a smart contract that differentiate it from scripts or predicates are that it is _callable_ and _stateful_. Put another way, a smart contract is analogous to a deployed API with some database state.
<!-- contract:example:end -->

The interface of a smart contract, also just called a contract, must be defined strictly with an [ABI declaration](#the-abi-declaration). See [this contract](../examples/wallet_smart_contract.md) for an example.

## Syntax of a Smart Contract

As with any Sway program, the program starts with a declaration of what [program type](./index.md) it is. A contract must also either define or import an [ABI declaration](#the-abi-declaration) and implement it.

<!-- This section should explain best practices for ABIs -->
<!-- ABI:example:start -->
It is considered good practice to define your ABI in a separate library and import it into your contract. This allows callers of your contract to simply import the ABI directly and use it in their scripts to call your contract.
<!-- ABI:example:end -->

Let's take a look at an ABI declaration in a library:

```sway
library;

// ANCHOR: abi
abi Wallet {
    // ANCHOR: receive_funds
    #[storage(read, write), payable]
    fn receive_funds();
    // ANCHOR_END: receive_funds

    // ANCHOR: send_funds
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
    // ANCHOR_END: send_funds
}
// ANCHOR: abi
```

Let's focus on the ABI declaration and inspect it line-by-line.

### The ABI Declaration

```sway
library;

abi Wallet {
    // ANCHOR: receive_funds
    #[storage(read, write), payable]
    fn receive_funds();
    // ANCHOR_END: receive_funds

    // ANCHOR: send_funds
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
    // ANCHOR_END: send_funds
}
```

---

In the first line, `abi Wallet {`, we declare the name of this _Application Binary Interface_, or ABI. We are naming this ABI `Wallet`. To import this ABI into either a script for calling or a contract for implementing, you would use

```sway
use wallet_abi::Wallet;
```

---

In the second line,

```sway
    #[storage(read, write), payable]
    fn receive_funds();
```

we are declaring an ABI method called `receive_funds` which, when called, should receive funds into this wallet. Note that we are simply defining an interface here, so there is no _function body_ or implementation of the function. We only need to define the interface itself. In this way, ABI declarations are similar to [trait declarations](../advanced/traits.md). This particular ABI method does not take any parameters.

---

In the third line,

```sway
    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address);
```

we are declaring another ABI method, this time called `send_funds`. It takes two parameters: the amount to send, and the address to send the funds to.

>**Note**: The ABI methods `receive_funds` and `send_funds` also require the annotation `#[storage(read, write)]` because their implementations require reading and writing a storage variable that keeps track of the wallet balance, as we will see shortly. Refer to [Purity](
../blockchain-development/purity.md#Purity) for more information on storage annotations.

## Implementing an ABI for a Smart Contract

Now that we've discussed how to define the interface, let's discuss how to use it. We will start by implementing the above ABI for a specific contract.

Implementing an ABI for a contract is accomplished with `impl <ABI name> for Contract` syntax. The `for Contract` syntax can only be used to implement an ABI for a contract; implementing methods for a struct should use `impl Foo` syntax.

```sway
impl Wallet for Contract {
    #[storage(read, write), payable]
    fn receive_funds() {
        if msg_asset_id() == AssetId::base() {
            // If we received the base asset then keep track of the balance.
            // Otherwise, we're receiving other native assets and don't care
            // about our balance of coins.
            storage.balance.write(storage.balance.read() + msg_amount());
        }
    }

    #[storage(read, write)]
    fn send_funds(amount_to_send: u64, recipient_address: Address) {
        let sender = msg_sender().unwrap();
        match sender {
            Identity::Address(addr) => assert(addr == OWNER_ADDRESS),
            _ => revert(0),
        };

        let current_balance = storage.balance.read();
        assert(current_balance >= amount_to_send);

        storage.balance.write(current_balance - amount_to_send);

        // Note: `transfer()` is not a call and thus not an
        // interaction. Regardless, this code conforms to
        // checks-effects-interactions to avoid re-entrancy.
        transfer(
            Identity::Address(recipient_address),
            AssetId::base(),
            amount_to_send,
        );
    }
}
```

You may notice once again the similarities between [traits](../advanced/traits.md) and ABIs. And, indeed, as a bonus, you can define methods in addition to the interface surface of an ABI, just like a trait. These pre-implemented ABI methods automatically become available as part of the contract interface that implements the corresponding ABI.

Note that the above implementation of the ABI follows the [Checks, Effects, Interactions](https://docs.soliditylang.org/en/v0.6.11/security-considerations.html#re-entrancy) pattern.

## The `ContractId` type

Contracts have an associated `ContractId` type in Sway. The `ContractId` type allows for Sway programs to refer to contracts in the Sway language. Please refer to the [ContractId](../basics/blockchain_types.md#contractid-type) section of the book for more information on `ContractId`s.

## Calling a Smart Contract from a Script

>**Note**: In most cases, calling a contract should be done from the [Rust SDK](../testing/testing-with-rust.md) or the [TypeScript SDK](https://docs.fuel.network/docs/fuels-ts) which provide a more ergonomic UI for interacting with a contract. However, there are situations where manually writing a script to call a contract is required.

Now that we have defined our interface and implemented it for our contract, we need to know how to actually _call_ our contract. Let's take a look at a contract call:

```sway
script;

use wallet_abi::Wallet;

fn main() {
    let contract_address = 0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b;
    let caller = abi(Wallet, contract_address);
    let amount_to_send = 200;
    let recipient_address = Address::from(0x9299da6c73e6dc03eeabcce242bb347de3f5f56cd1c70926d76526d7ed199b8b);
    caller
        .send_funds {
            gas: 10000,
            coins: 0,
            asset_id: b256::zero(),
        }(amount_to_send, recipient_address);
}

```

The main new concept is the `abi cast`: `abi(AbiName, contract_address)`. This returns a `ContractCaller` type which can be used to call contracts. The methods of the ABI become the methods available on this contract caller: `send_funds` and `receive_funds`. We then directly call the contract ABI method as if it was just a regular method. You also have the option of specifying the following special parameters inside curly braces right before the main list of parameters:

1. `gas`: a `u64` that represents the gas being forwarded to the contract when it is called.
2. `coins`: a `u64` that represents how many coins are being forwarded with this call.
3. `asset_id`: a `b256` that represents the ID of the _asset type_ of the coins being forwarded.

Each special parameter is optional and assumes a default value when skipped:

1. The default value for `gas` is the context gas (i.e. the content of the special register `$cgas`). Refer to the [FuelVM specifications](https://fuellabs.github.io/fuel-specs/master/vm) for more information about context gas.
2. The default value for `coins` is 0.
3. The default value for `asset_id` is `b256::zero()`.


---

### File: docs/sway/docs/book/src/testing/index.md

# Testing

Sway aims to provide facilities for both unit testing and integration testing.

**Unit testing** refers to "in-language" test functions annotated with `#[test]`.

**Integration testing** refers to the testing of your Sway project's integration
within some wider application. You can add integration testing to your Sway+Rust
projects today using the cargo generate template and Rust SDK.

- [Unit Testing](./unit-testing.md)
- [Testing with Rust](./testing-with-rust.md)


---

### File: docs/sway/docs/book/src/testing/testing-with-rust.md

# Testing with Rust

A common use of Sway is for writing contracts or scripts that exist as part of a
wider Rust application. In order to test the interaction between our Sway code
and our Rust code we can add integration testing.

## Adding Rust Integration Testing

To add Rust integration testing to a Forc project we can use [the `sway-test-rs`
cargo generate
template](https://github.com/FuelLabs/sway/tree/master/templates/sway-test-rs).
This template makes it easier for Sway developers to add the boilerplate required when
setting up their Rust integration testing.

Let's add a Rust integration test to [the fresh project we created in the introduction](../introduction/forc_project.md).

### 1. Enter the project

To recap, here's what our empty project looks like:

```console
$ cd my-fuel-project
$ tree .
├── Forc.toml
└── src
    └── main.sw
```

### 2. Install `cargo generate`

We're going to add a Rust integration test harness using a cargo generate
template. Let's make sure we have the `cargo generate` command installed!

```console
cargo install cargo-generate
```

> _**Note**: You can learn more about cargo generate by visiting the
> [cargo-generate repository](https://github.com/cargo-generate/cargo-generate)._

### 3. Generate the test harness

Let's generate the default test harness with the following:

```console
cargo generate --init fuellabs/sway templates/sway-test-rs --name my-fuel-project --force
```

`--force` forces your `--name` input to retain your desired casing for the `{{project-name}}`
placeholder in the template. Otherwise, `cargo-generate` automatically converts it to `kebab-case`.
With `--force`, this means that both `my_fuel_project` and `my-fuel-project` are valid project names,
depending on your needs.

> _**Note**: `templates/sway-test-rs` can be replaced with `templates/sway-script-test-rs` or `templates/sway-predicate-test-rs` to generate a test
> harness for scripts and predicates respectively.

If all goes well, the output should look as follows:

```console
⚠️   Favorite `fuellabs/sway` not found in config, using it as a git repository: https://github.com/fuellabs/sway
🤷   Project Name : my-fuel-project
🔧   Destination: /home/user/path/to/my-fuel-project ...
🔧   Generating template ...
[1/3]   Done: Cargo.toml
[2/3]   Done: tests/harness.rs
[3/3]   Done: tests
🔧   Moving generated files into: `/home/user/path/to/my-fuel-project`...
✨   Done! New project created /home/user/path/to/my-fuel-project
```

Let's have a look at the result:

```console
$ tree .
├── Cargo.toml
├── Forc.toml
├── build.rs
├── src
│   └── main.sw
└── tests
    └── harness.rs
```

We have three new files!

- The `Cargo.toml` is the manifest for our new test harness and specifies the
  required dependencies including `fuels` the Fuel Rust SDK.
- The `tests/harness.rs` contains some boilerplate test code to get us started,
  though doesn't call any contract methods just yet.
- The `build.rs` is a build script that compiles the Sway project with `forc build`
  whenever `cargo test` is run.

### 4. Build the forc project

Before running the tests, we need to build our contract so that the necessary
ABI, storage and bytecode artifacts are available. We can do so with `forc build`:

```console
$ forc build
  Creating a new `Forc.lock` file. (Cause: lock file did not exist)
    Adding std git+https://github.com/fuellabs/sway?tag=v0.24.5#e695606d8884a18664f6231681333a784e623bc9
   Created new lock file at /home/user/path/to/my-fuel-project/Forc.lock
  Compiled library "std".
  Compiled contract "my-fuel-project".
  Bytecode size is 60 bytes.
```

At this point, our project should look like the following:

```console
$ tree
├── Cargo.toml
├── Forc.lock
├── Forc.toml
├── build.rs
├── out
│   └── debug
│       ├── my-fuel-project-abi.json
│       ├── my-fuel-project.bin
│       └── my-fuel-project-storage_slots.json
├── src
│   └── main.sw
└── tests
    └── harness.rs
```

We now have an `out` directory with our required JSON files!

> _**Note**: This step may no longer be required in the future as we plan to
> enable the integration testing to automatically build the artifacts as
> necessary so that files like the ABI JSON are always up to date._

### 5. Build and run the tests

Now we're ready to build and run the default integration test.

```console
$ cargo test
    Updating crates.io index
   Compiling version_check v0.9.4
   Compiling proc-macro2 v1.0.46
   Compiling quote v1.0.21
   ...
   Compiling fuels v0.24.0
   Compiling my-fuel-project v0.1.0 (/home/user/path/to/my-fuel-project)
    Finished test [unoptimized + debuginfo] target(s) in 1m 03s
     Running tests/harness.rs (target/debug/deps/integration_tests-373971ac377845f7)

running 1 test
test can_get_contract_id ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.36s
```

> _**Note**: The first time we run `cargo test`, cargo will spend some time
> fetching and building the dependencies for Fuel's Rust SDK. This might take a
> while, but only the first time!_

If all went well, we should see some output that looks like the above!

## Writing Tests

Now that we've learned how to setup Rust integration testing in our project,
let's try to write some of our own tests!

First, let's update our contract code with a simple counter example:

```sway
contract;

abi TestContract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64;

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64;
}

storage {
    counter: u64 = 0,
}

impl TestContract for Contract {
    #[storage(write)]
    fn initialize_counter(value: u64) -> u64 {
        storage.counter.write(value);
        value
    }

    #[storage(read, write)]
    fn increment_counter(amount: u64) -> u64 {
        let incremented = storage.counter.read() + amount;
        storage.counter.write(incremented);
        incremented
    }
}

```

To test our `initialize_counter` and `increment_counter` contract methods from
the Rust test harness, we could update our `tests/harness.rs` file with the
following:

<!--TODO add test here once examples are tested-->

```rust,ignore
use fuels::{prelude::*, types::ContractId};

// Load abi from json
abigen!(Contract(
    name = "MyContract",
    abi = "out/debug/my-fuel-project-abi.json"
));

async fn get_contract_instance() -> (MyContract<WalletUnlocked>, ContractId) {
    // Launch a local network and deploy the contract
    let mut wallets = launch_custom_provider_and_get_wallets(
        WalletsConfig::new(
            Some(1),             /* Single wallet */
            Some(1),             /* Single coin (UTXO) */
            Some(1_000_000_000), /* Amount per coin */
        ),
        None,
        None,
    )
    .await
    .unwrap();
    let wallet = wallets.pop().unwrap();

    let id = Contract::load_from(
        "./out/debug/my-fuel-project.bin",
        LoadConfiguration::default().set_storage_configuration(
            StorageConfiguration::load_from(
                "./out/debug/my-fuel-project-storage_slots.json",
            )
            .unwrap(),
        ),
    )
    .unwrap()
    .deploy(&wallet, TxPolicies::default())
    .await
    .unwrap();

    let instance = MyContract::new(id.clone(), wallet);

    (instance, id.into())
}

#[tokio::test]
async fn initialize_and_increment() {
    let (contract_instance, _id) = get_contract_instance().await;
    // Now you have an instance of your contract you can use to test each function

    let result = contract_instance
        .methods()
        .initialize_counter(42)
        .call()
        .await
        .unwrap();

    assert_eq!(42, result.value);

    // Call `increment_counter()` method in our deployed contract.
    let result = contract_instance
        .methods()
        .increment_counter(10)
        .call()
        .await
        .unwrap();

    assert_eq!(52, result.value);
}
```

Let's build our project once more and run the test:

```console
forc build
```

```console
$ cargo test
   Compiling my-fuel-project v0.1.0 (/home/mindtree/programming/sway/my-fuel-project)
    Finished test [unoptimized + debuginfo] target(s) in 11.61s
     Running tests/harness.rs (target/debug/deps/integration_tests-373971ac377845f7)

running 1 test
test initialize_and_increment ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.25s
```

When cargo runs our test, our test uses the SDK to spin up a local in-memory
Fuel network, deploy our contract to it, and call the contract methods via the
ABI.

You can add as many functions decorated with `#[tokio::test]` as you like, and
`cargo test` will automatically test each of them!


---

### File: docs/sway/docs/book/src/testing/testing_with_forc_call.md

# Forc Call

`forc-call` is a command-line tool for interacting with deployed Fuel contracts. It allows you to make contract calls, query contract state, and interact with any deployed contract on the Fuel network - all from your command line!

The `forc call` command is part of the Forc toolchain and is installed alongside other Forc tools.

## Getting Started

Here are a few examples of what you can do with `forc call`:

```sway
contract;

abi ContractABI {
  fn add(a: u64, b: u64) -> u64;
}

impl ContractABI for Contract {
  fn add(a: u64, b: u64) -> u64 {
    a + b
  }
}
```

### List callable functions of a contract given it's ABI file

```bash
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
  --abi ./out/debug/counter-contract-abi.json \
  --list-functions
```

Output:

```log
Available functions in contract: 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d

add(a: u64, b: u64) -> u64
  forc call \
    --abi ./out/debug/counter-contract-abi.json \
    0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
    add "0" "0"
```

### Call a simple addition function on a deployed contract (in dry-run mode)

```bash
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
  --abi ./out/debug/counter-contract-abi.json \
  add 1 2
```

### Directly send funds to an address

```bash
forc call 0x2c7Fd852EF2BaE281e90ccaDf18510701989469f7fc4b042F779b58a39919Eec --amount 2 --mode=live
```

### Query the owner of a deployed [DEX contract](https://github.com/mira-amm/mira-v1-core) on testnet

```bash
forc call \
  --testnet \
  --abi https://raw.githubusercontent.com/mira-amm/mira-v1-periphery/refs/heads/main/fixtures/mira-amm/mira_amm_contract-abi.json \
  0xd5a716d967a9137222219657d7877bd8c79c64e1edb5de9f2901c98ebe74da80 \
  owner
```

## Usage

Forc call has **3** usage modes:

### List functions

Syntax for `forc call` for listing supported functions from the ABI - with example command to perform call operation:

```bash
forc call --abi <ABI-PATH/URL> <CONTRACT_ID> --list-functions
```

Where the following arguments are required:

- `ABI-PATH/URL` is the path or URL to the contract's JSON ABI file
- `CONTRACT_ID` is the ID of the deployed contract you want to interact with

### Transfer assets

Syntax for `forc call` for transferring assets:

```bash
forc call <RECEIVER_ADDRESS> --amount <AMOUNT> --mode=live
```

Where the following arguments are required:

- `RECEIVER_ADDRESS` is address of the receiver (identity or contract).
- `AMOUNT` is the amount of assets to transfer.

Note: only live mode `--mode=live` is supported; transfers cannot be simulated.

### Call contracts

Syntax for `forc call` for contract calls:

```bash
forc call [OPTIONS] --abi <ABI-PATH/URL> <CONTRACT_ID> <SELECTOR> [ARGS]...
```

Where the following arguments are required:

- `CONTRACT_ID` is the ID of the deployed contract you want to interact with
- `ABI-PATH/URL` is the path or URL to the contract's JSON ABI file
- `SELECTOR` is the function name (selector) you want to call
- `ARGS` are the arguments to pass to the function

## Type Encoding

When passing arguments to contract functions, values are encoded according to their Sway types.
Here's how to format different types:

| Types                                         | Example input                                                        | Notes                                                                                          |
|-----------------------------------------------|----------------------------------------------------------------------|------------------------------------------------------------------------------------------------|
| bool                                          | `true` or `false`                                                    |                                                                                                |
| u8, u16, u32, u64, u128, u256                 | `42`                                                                 |                                                                                                |
| b256                                          | `0x0000000000000000000000000000000000000000000000000000000000000042` or `0000000000000000000000000000000000000000000000000000000000000042` | `0x` prefix is optional |
| bytes, RawSlice                               | `0x42` or `42`                                                       | `0x` prefix is optional                                                                                               |
| String, StringSlice, StringArray (Fixed-size) | `"abc"`                                                              |                                                                                                |
| Tuple                                         | `(42, true)`                                                         | The types in tuple can be different                                                                                               |
| Array (Fixed-size), Vector (Dynamic)          | `[42, 128]`                                                          | The types in array or vector must be the same; i.e. you cannot have `[42, true]`              |
| Struct                                        | `{42, 128}`                                                          | Since structs are packed encoded, the attribute names are not encoded; i.e. `{42, 128}`; this could represent the following `struct Polygon { x: u64, y: u64 }` |
| Enum                                          | `(Active: true)` or `(1: true)`       | Enums are key-val pairs with keys as being variant name (case-sensitive) or variant index (starting from 0) and values as being the variant value; this could represent the following `enum MyEnum { Inactive, Active(bool) }` |

## ABI Support

The ABI (Application Binary Interface) can be provided in two ways.

### Local file

```bash
forc call <CONTRACT_ID> --abi ./path/to/abi.json <FUNCTION> [ARGS...]
```

### Remote ABI file/URL

```bash
forc call <CONTRACT_ID> --abi https://example.com/abi.json <FUNCTION> [ARGS...]
```

## Network Configuration

```bash
forc call --node-url http://127.0.0.1:4000 ...
# or
forc call --target local ...
```

## Advanced Usage

### Using Wallets

```sh
# utilising the forc-wallet
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --wallet
```

```sh
# with an explicit signing key
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --signing-key <KEY>
```

### Asset Transfers

```sh
# Native asset transfer
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --amount 100 --live
```

```sh
# Custom asset transfer
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> \
    --amount 100 \
    --asset-id 0x1234... \
    --live
```

### Gas Configuration

```sh
# Set gas price
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --gas-price 1

# Forward gas to contract
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --gas-forwarded 1000

# Set maximum fee
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --max-fee 5000
```

### Transaction Tracing

When you need to debug contract interactions or understand the execution flow, `forc call` provides detailed transaction traces with verbosity level 3 or higher (`-vvv` or `-v=3`).

```sh
# Enable transaction tracing
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> -vvv
```

The transaction trace provides a hierarchical view of all contract calls, showing:

- Gas consumption for each call (`[gas_amount]`)
- Contract addresses being called
- Return values and data
- Emitted logs and events
- Nested contract calls with proper indentation
- Overall transaction result and gas usage

#### Example Transaction Trace Output

```bash
forc call 0x9275a76531bce733cfafdbcb6727ea533ebbdc358d685152169b3c4eaa47b965 \
  --abi ./demo/demo-caller-abi.json \
  call_increment_count -vvv
```

**Output:**

```log
Traces:
  [Script]
    ├─ [124116] 0x9275a76531bce733cfafdbcb6727ea533ebbdc358d685152169b3c4eaa47b965
    │    ├─ [111500] 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42
    │    │    └─ ← ()
    │    ├─ emit AsciiString { data: "incremented count" }
    │    ├─ [86284] 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42
    │    │    └─ ← 0x0000000000000002
    │    ├─ emit 2
    │    ├─ emit AsciiString { data: "done" }
    │    ├─ [72699] 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42
    │    │    └─ ← ()
    │    ├─ [48287] 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42
    │    │    └─ ← 0x0000000000000003
    │    └─ ← 0x0000000000000003
    └─ ← [Return] val: 1
  [ScriptResult] result: Success, gas_used: 89279

Transaction successfully executed.
Gas used: 160676
```

#### Understanding the Trace Format

- `[Script]` - The root transaction script
- `├─ [gas_amount] 0xcontract_address` - A contract call with gas consumption
- `│    └─ ← value` - Return value from the contract call
- `emit data` - Log/event emitted by the contract
- Indentation shows the call hierarchy (nested calls are indented further)
- `[ScriptResult]` - Final transaction result with gas used by the script
- `Gas used: <gas_used>` - Total gas used by the transaction

This tracing feature is particularly useful for:

- Debugging failed transactions
- Understanding gas consumption patterns
- Analyzing complex multi-contract interactions
- Verifying expected contract behavior

### Common Use Cases

#### Contract State Queries

```sh
# Read contract state
forc call <CONTRACT_ID> --abi <PATH> get_balance

# Query with parameters
forc call <CONTRACT_ID> --abi <PATH> get_user_info 0x1234...
```

#### Token Operations

```sh
# Check token balance
forc call <CONTRACT_ID> --abi <PATH> balance_of 0x1234...

# Transfer tokens
forc call <CONTRACT_ID> --abi <PATH> transfer 0x1234... 100 --live
```

#### Contract Administration

```sh
# Check contract owner
forc call <CONTRACT_ID> --abi <PATH> owner

# Update contract parameters
forc call <CONTRACT_ID> --abi <PATH> update_params 42 --live
```

## Tips and Tricks

- Use `--mode simulate` to estimate gas costs before making live transactions
- External contracts are automatically detected (via internal simulations), but can be manually specified with `--external-contracts`
- For complex parameter types (tuples, structs, enums), refer to the parameter types table above
- Always verify contract addresses and ABIs before making live calls
- Use environment variables for sensitive data like signing keys: `SIGNING_KEY=<key>`

## Troubleshooting

### Common issues and solutions

- **ABI Mismatch**:
  - Ensure the ABI matches the deployed contract
  - Verify function selectors match exactly

- **Parameter Type Errors**:
  - Check parameter formats in the types table
  - Ensure correct number of parameters

- **Network Issues**:
  - Verify node connection
  - Check network selection (testnet/mainnet)

- **Transaction Failures**:
  - Use simulation mode to debug
  - Check gas settings
  - Verify wallet has sufficient balance


---

### File: docs/sway/docs/book/src/testing/unit-testing.md

# Unit Testing

<!-- This section should explain unit testing in Sway -->
<!-- unit_test:example:start -->
Forc provides built-in support for building and executing tests for a package.

Tests are written as free functions with the `#[test]` attribute.
<!-- unit_test:example:end -->

For example:

```sway
#[test]
fn test_meaning_of_life() {
    assert(6 * 7 == 42);
}
```

Each test function is ran as if it were the entry point for a
[script](../sway-program-types/scripts.md). Tests "pass" if they return
successfully, and "fail" if they revert or vice versa while [testing failure](#testing-failure).

If the project has failing tests `forc test` will exit with exit status `101`.

## Building and Running Tests

We can build and execute all tests within a package with the following:

```console
forc test
```

The output should look similar to this:

```console
  Compiled library "std".
  Compiled library "lib_single_test".
  Bytecode size is 92 bytes.
   Running 1 tests
      test test_meaning_of_life ... ok (170.652µs)
   Result: OK. 1 passed. 0 failed. Finished in 1.564996ms.
```

Visit the [`forc test`](../forc/commands/forc_test.md) command reference to find
the options available for `forc test`.

## Testing Failure

<!-- This section should explain support for failing unit tests in Sway -->
<!-- unit_test_fail:example:start -->
Forc supports testing failing cases for test functions declared with `#[test(should_revert)]`.
<!-- unit_test_fail:example:end -->

For example:

```sway
#[test(should_revert)]
fn test_meaning_of_life() {
    assert_eq(6 * 6, 42);
}
```

It is also possible to specify an expected revert code, like the following example.

```sway
#[test(should_revert = "18446744073709486084")]
fn test_meaning_of_life() {
    assert_eq(6 * 6, 42);
}
```

Tests with `#[test(should_revert)]` are considered to be passing if they are reverting.

Available information about reverts is not shown by default in passing tests that have `should_revert`. To see revert information, use the `--reverts` flag, `forc test --reverts`:

```console
  test test_meaning_of_life ... ok (52.432µs, 508 gas)
       revert code: ffffffffffff0003
        └─ error message: Failing call to `std::assert::assert_eq`
```

## Calling Contracts

Unit tests can call contract functions. An example for such calls can be seen below.

```sway
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

To test the `test_function()`, a unit test like the following can be written.

```sway
#[test]
fn test_success() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == true);
}
```

It is also possible to test failure with contract calls as well.

```sway
#[test(should_revert)]
fn test_fail() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == false);
}
```

<!-- This section should explain how the `CONTRACT_ID` variable works in Sway unit tests -->
<!-- contract_id:example:start -->
> **Note:** When running `forc test`, your contract will be built twice: first *without* unit tests in order to determine the contract's ID, then a second time *with* unit tests with the `CONTRACT_ID` provided to their namespace. This `CONTRACT_ID` can be used with the `abi` cast to enable contract calls within unit tests.
<!-- contract_id:example:end -->

Unit tests can call methods of external contracts if those contracts are added as contract dependencies, i.e. in the [`contract-dependencies`](../forc/manifest_reference.md#the-contract-dependencies-section) section of the manifest file. An example of such calls is shown below:

```sway
contract;

abi CallerContract {
    fn test_false() -> bool;
}

impl CallerContract for Contract {
    fn test_false() -> bool {
        false
    }
}

abi CalleeContract {
    fn test_true() -> bool;
}

#[test]
fn test_multi_contract_calls() {
    let caller = abi(CallerContract, CONTRACT_ID);
    let callee = abi(CalleeContract, callee::CONTRACT_ID);

    let should_be_false = caller.test_false();
    let should_be_true = callee.test_true();
    assert(!should_be_false);
    assert(should_be_true);
}

```

Example `Forc.toml` for contract above:

```toml
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
name = "caller"

[dependencies]
std = { path = "../../../sway-lib-std/" }

[contract-dependencies]
callee = { path = "../callee" }

```

## Running Tests in Parallel or Serially

<!-- This section should explain how unit tests do not share storage -->
<!-- storage:example:start -->
By default, all unit tests in your project are run in parallel. Note that this does not lead to any data races in storage because each unit test has its own storage space that is not shared by any other unit test.
<!-- storage:example:end -->

By default, `forc test` will use all the available threads in your system. To request that a specific number of threads be used, the flag `--test-threads <val>` can be provided to `forc test`.

```console
forc test --test-threads 1
```

## Logs Inside Tests

<!-- This section should explain how log decoding works with Sway unit tests -->
<!-- unit_test_log::example::start -->
Forc has some capacity to help decode logs returned from the unit tests. You can use this feature to decode raw logs into a human readable format.

```sway
script;

fn main() {}

#[test]
fn test_fn() {
    let a = 10;
    log(a);
    let b = 30;
    log(b);
    assert_eq(a, 10);
    assert_eq(b, 30);
}
```

The above example shows a passing test that is logging two different variables, `a` and `b`, and their values are `10` and `30`, respectively. Logs are silenced by default in passing tests, and can be enabled using the `--logs` flag, `forc test --logs`:

```console
     Running 1 test, filtered 0 tests
      test test_fn ... ok (58.842µs, 0 gas)
Decoded log value: 10, log rb: 1515152261580153489
Decoded log value: 30, log rb: 1515152261580153489
```

The `--logs` flag prints decoded log values. If you want to see pretty-printed raw log receipts you can use the `--raw-logs --pretty` flags, `forc test --raw-logs --pretty`:

```console
      test test_fn ... ok (54.042µs, 0 gas)
Raw logs:
[
  {
    "LogData": {
      "data": "000000000000000a",
      "digest": "8d85f8467240628a94819b26bee26e3a9b2804334c63482deacec8d64ab4e1e7",
      "id": "0000000000000000000000000000000000000000000000000000000000000000",
      "is": 10368,
      "len": 8,
      "pc": 11212,
      "ptr": 67107840,
      "ra": 0,
      "rb": 1515152261580153489
    }
  },
  {
    "LogData": {
      "data": "000000000000001e",
      "digest": "48a97e421546f8d4cae1cf88c51a459a8c10a88442eed63643dd263cef880c1c",
      "id": "0000000000000000000000000000000000000000000000000000000000000000",
      "is": 10368,
      "len": 8,
      "pc": 11212,
      "ptr": 67106816,
      "ra": 0,
      "rb": 1515152261580153489
    }
  }
]
```

The `--logs` and `--raw-logs` flags can be combined to print both the decoded and raw logs.
<!-- unit_test_log::example::end -->


---

### File: docs/verified-addresses/docs/src/assets.md


# Verified Assets

## Using this section

You can find the current list of verified assets maintained by Fuel here: [verified-assets.json](https://verified-assets.fuel.network/assets.json)

Projects are welcome to use this information, but please note that it is provided at your own risk.

Additionally, you can download the latest asset information and icons in a single archive. This is useful if you want to locally cache the list or include it in a release pipeline for your tools and libraries: [verified-assets.zip](https://github.com/FuelLabs/verified-assets/)

For more information, please visit the verified assets repository [here](https://github.com/FuelLabs/verified-assets/).

## Ethereum Sepolia Testnet

| Name | Address | Decimals |
|------|---------|----------|
| `Ethereum` |  | `18` |
| `Fuel` | [`0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550`](https://sepolia.etherscan.io/address/0xd7fc4e8fb2c05567c313f4c9b9e07641a361a550) | `9` |
| `USDC` | [`0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238`](https://sepolia.etherscan.io/address/0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238) | `6` |
| `USDe` | [`0xc6387efad0f184a90b34f397c3d6fd63135ef790`](https://sepolia.etherscan.io/address/0xc6387efad0f184a90b34f397c3d6fd63135ef790) | `18` |
| `sUSDe` | [`0xb8f4f4eafc1d2a3c0a4d519bbf1114c311cc9b1b`](https://sepolia.etherscan.io/address/0xb8f4f4eafc1d2a3c0a4d519bbf1114c311cc9b1b) | `18` |
| `wstETH` | [`0xB82381A3fBD3FaFA77B3a7bE693342618240067b`](https://sepolia.etherscan.io/address/0xB82381A3fBD3FaFA77B3a7bE693342618240067b) | `18` |

## Ethereum Foundry

| Name | Address | Decimals |
|------|---------|----------|
| `Ethereum` |  | `18` |

## Ethereum L1

| Name | Address | Decimals |
|------|---------|----------|
| `Ethereum` |  | `18` |
| `Fuel` | [`0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c`](https://etherscan.io/address/0x675b68aa4d9c2d3bb3f0397048e62e6b7192079c) | `9` |
| `WETH` | [`0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`](https://etherscan.io/address/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) | `18` |
| `weETH` | [`0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee`](https://etherscan.io/address/0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee) | `18` |
| `rsETH` | [`0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7`](https://etherscan.io/address/0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7) | `18` |
| `rETH` | [`0xae78736cd615f374d3085123a210448e74fc6393`](https://etherscan.io/address/0xae78736cd615f374d3085123a210448e74fc6393) | `18` |
| `wbETH` | [`0xa2E3356610840701BDf5611a53974510Ae27E2e1`](https://etherscan.io/address/0xa2E3356610840701BDf5611a53974510Ae27E2e1) | `18` |
| `rstETH` | [`0x7a4EffD87C2f3C55CA251080b1343b605f327E3a`](https://etherscan.io/address/0x7a4EffD87C2f3C55CA251080b1343b605f327E3a) | `18` |
| `amphrETH` | [`0x5fD13359Ba15A84B76f7F87568309040176167cd`](https://etherscan.io/address/0x5fD13359Ba15A84B76f7F87568309040176167cd) | `18` |
| `Manta mBTC` | [`0x4041381e947CFD3D483d67a25C6aa9Dc924250c5`](https://etherscan.io/address/0x4041381e947CFD3D483d67a25C6aa9Dc924250c5) | `18` |
| `Manta mETH` | [`0x8CdF550C04Bc9B9F10938368349C9c8051A772b6`](https://etherscan.io/address/0x8CdF550C04Bc9B9F10938368349C9c8051A772b6) | `18` |
| `Manta mUSD` | [`0x3f24E1d7a973867fC2A03fE199E5502514E0e11E`](https://etherscan.io/address/0x3f24E1d7a973867fC2A03fE199E5502514E0e11E) | `18` |
| `pumpBTC` | [`0xf469fbd2abcd6b9de8e169d128226c0fc90a012e`](https://etherscan.io/address/0xf469fbd2abcd6b9de8e169d128226c0fc90a012e) | `8` |
| `FBTC` | [`0xc96de26018a54d51c097160568752c4e3bd6c364`](https://etherscan.io/address/0xc96de26018a54d51c097160568752c4e3bd6c364) | `8` |
| `SolvBTC` | [`0x7a56e1c57c7475ccf742a1832b028f0456652f97`](https://etherscan.io/address/0x7a56e1c57c7475ccf742a1832b028f0456652f97) | `18` |
| `SolvBTC.BBN` | [`0xd9d920aa40f578ab794426f5c90f6c731d159def`](https://etherscan.io/address/0xd9d920aa40f578ab794426f5c90f6c731d159def) | `18` |
| `Mantle mETH` | [`0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa`](https://etherscan.io/address/0xd5F7838F5C461fefF7FE49ea5ebaF7728bB0ADfa) | `18` |
| `sDAI` | [`0x83f20f44975d03b1b09e64809b757c47f942beea`](https://etherscan.io/address/0x83f20f44975d03b1b09e64809b757c47f942beea) | `18` |
| `USDT` | [`0xdAC17F958D2ee523a2206206994597C13D831ec7`](https://etherscan.io/address/0xdAC17F958D2ee523a2206206994597C13D831ec7) | `6` |
| `USDC` | [`0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) | `6` |
| `USDe` | [`0x4c9edd5852cd905f086c759e8383e09bff1e68b3`](https://etherscan.io/address/0x4c9edd5852cd905f086c759e8383e09bff1e68b3) | `18` |
| `sUSDe` | [`0x9d39a5de30e57443bff2a8307a4256c8797a3497`](https://etherscan.io/address/0x9d39a5de30e57443bff2a8307a4256c8797a3497) | `18` |
| `rsUSDe` | [`0x82f5104b23FF2FA54C2345F821dAc9369e9E0B26`](https://etherscan.io/address/0x82f5104b23FF2FA54C2345F821dAc9369e9E0B26) | `18` |
| `wstETH` | [`0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0`](https://etherscan.io/address/0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0) | `18` |
| `ezETH` | [`0xbf5495Efe5DB9ce00f80364C8B423567e58d2110`](https://etherscan.io/address/0xbf5495Efe5DB9ce00f80364C8B423567e58d2110) | `18` |
| `pzETH` | [`0x8c9532a60e0e7c6bbd2b2c1303f63ace1c3e9811`](https://etherscan.io/address/0x8c9532a60e0e7c6bbd2b2c1303f63ace1c3e9811) | `18` |
| `Re7LRT` | [`0x84631c0d0081FDe56DeB72F6DE77abBbF6A9f93a`](https://etherscan.io/address/0x84631c0d0081FDe56DeB72F6DE77abBbF6A9f93a) | `18` |
| `steakLRT` | [`0xBEEF69Ac7870777598A04B2bd4771c71212E6aBc`](https://etherscan.io/address/0xBEEF69Ac7870777598A04B2bd4771c71212E6aBc) | `18` |

## Fuel Devnet

| Name | Asset ID | Contract Address | Decimals |
|------|----------|------------------|----------|
| `Ethereum` | `0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07` |  | `9` |

## Fuel Testnet

| Name | Asset ID | Contract Address | Decimals |
|------|----------|------------------|----------|
| `Ethereum` | `0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07` |  | `9` |
| `FUEL` | `0x324d0c35a4299ef88138a656d5272c5a3a9ccde2630ae055dacaf9d13443d53b` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |
| `USDC` | `0xc26c91055de37528492e7e97d91c6f4abe34aae26f2c4d25cff6bfe45b5dc9a9` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `6` |
| `USDe` | `0x86a1beb50c844f5eff9afd21af514a13327c93f76edb89333af862f70040b107` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |
| `sUSDe` | `0xd2886b34454e2e0de47a82d8e6314b26e1e1312519247e8e2ef137672a909aeb` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |
| `wstETH` | `0xb42cd9ddf61898da1701adb3a003b0cf4ca6df7b5fe490ec2c295b1ca43b33c8` | `0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471` | `9` |

## Fuel Mainnet

| Name | Asset ID | Contract Address | Decimals |
|------|----------|------------------|----------|
| `Ethereum` | `0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07` |  | `9` |
| `FUEL` | `0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `stFUEL` | `0x5505d0f58bea82a052bc51d2f67ab82e9735f0a98ca5d064ecb964b8fd30c474` | `0x2181f1b8e00756672515807cab7de10c70a9b472a4a9b1b6ca921435b0a1f49b` | `9` |
| `WETH` | `0xa38a5a8beeb08d95744bc7f58528073f4052b254def59eba20c99c202b5acaa3` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `weETH` | `0x239ed6e12b7ce4089ee245244e3bf906999a6429c2a9a445a1e1faf56914a4ab` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rsETH` | `0xbae80f7fb8aa6b90d9b01ef726ec847cc4f59419c4d5f2ea88fec785d1b0e849` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rETH` | `0xf3f9a0ed0ce8eac5f89d6b83e41b3848212d5b5f56108c54a205bb228ca30c16` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `wbETH` | `0x7843c74bef935e837f2bcf67b5d64ecb46dd53ff86375530b0caf3699e8ffafe` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rstETH` | `0x962792286fbc9b1d5860b4551362a12249362c21594c77abf4b3fe2bbe8d977a` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `amphrETH` | `0x05fc623e57bd7bc1258efa8e4f62b05af5471d73df6f2c2dc11ecc81134c4f36` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Manta mBTC` | `0xaf3111a248ff7a3238cdeea845bb2d43cf3835f1f6b8c9d28360728b55b9ce5b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Manta mETH` | `0xafd219f513317b1750783c6581f55530d6cf189a5863fd18bd1b3ffcec1714b4` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Manta mUSD` | `0x89cb9401e55d49c3269654dd1cdfb0e80e57823a4a7db98ba8fc5953b120fef4` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `pumpBTC` | `0x0aa5eb2bb97ca915288b653a2529355d4dc66de2b37533213f0e4aeee3d3421f` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `8` |
| `FBTC` | `0xb5ecb0a1e08e2abbabf624ffea089df933376855f468ade35c6375b00c33996a` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `8` |
| `SolvBTC` | `0x1186afea9affb88809c210e13e2330b5258c2cef04bb8fff5eff372b7bd3f40f` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `SolvBTC.BBN` | `0x7a4f087c957d30218223c2baaaa365355c9ca81b6ea49004cfb1590a5399216f` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Mantle mETH` | `0x642a5db59ec323c2f846d4d4cf3e58d78aff64accf4f8f6455ba0aa3ef000a3b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `sDAI` | `0x9e46f919fbf978f3cad7cd34cca982d5613af63ff8aab6c379e4faa179552958` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `USDT` | `0xa0265fb5c32f6e8db3197af3c7eb05c48ae373605b8165b6f4a51c5b0ba4812e` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `6` |
| `USDC` | `0x286c479da40dc953bddc3bb4c453b608bba2e0ac483b077bd475174115395e6b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `6` |
| `USDe` | `0xb6133b2ef9f6153eb869125d23dcf20d1e735331b5e41b15a6a7a6cec70e8651` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `sUSDe` | `0xd05563025104fc36496c15c7021ad6b31034b0e89a356f4f818045d1f48808bc` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `rsUSDe` | `0x78d4522ec607f6e8efb66ea49439d1ee48623cf763f9688a8eada025def033d9` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `wstETH` | `0x1a7815cc9f75db5c24a5b0814bfb706bb9fe485333e98254015de8f48f84c67b` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `ezETH` | `0x91b3559edb2619cde8ffb2aa7b3c3be97efd794ea46700db7092abeee62281b0` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `pzETH` | `0x1493d4ec82124de8f9b625682de69dcccda79e882b89a55a8c737b12de67bd68` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `Re7LRT` | `0xf2fc648c23a5db24610a1cf696acc4f0f6d9a7d6028dd9944964ab23f6e35995` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `steakLRT` | `0x4fc8ac9f101df07e2c2dec4a53c8c42c439bdbe5e36ea2d863a61ff60afafc30` | `0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8` | `9` |
| `USDF` | `0x33a6d90877f12c7954cca6d65587c25e9214c7bed2231c188981c7114c1bdb78` |  | `9` |

## Binance Smart Chain

| Name | Address | Decimals |
|------|---------|----------|
| `Fuel` | [`0x5c8daEabc57E9249606D3bD6d1E097eF492eA3C5`](https://bscscan.com/address/0x5c8daEabc57E9249606D3bD6d1E097eF492eA3C5) | `9` |
| `USDT` | [`0x55d398326f99059ff775485246999027b3197955`](https://bscscan.com/address/0x55d398326f99059ff775485246999027b3197955) | `18` |
| `USDC` | [`0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d`](https://bscscan.com/address/0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d) | `18` |


---

### File: docs/verified-addresses/docs/src/contracts.md

# Verified Contracts

## Ethereum Mainnet

Contract Name | Contract Address
--- | ---
FuelChainState | [`0xf3D20Db1D16A4D0ad2f280A5e594FF3c7790f130`](https://etherscan.io/address/0xf3D20Db1D16A4D0ad2f280A5e594FF3c7790f130)
FuelERC20GatewayV4 | [`0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67`](https://etherscan.io/address/0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67)
FuelMessagePortal | [`0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf`](https://etherscan.io/address/0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf)
The Rig (Liquid Staking) | [`0x9bA9d8781Ac7ce5AdB8B8eC48aAb521d0Db5cd7E`](https://etherscan.io/address/0x9bA9d8781Ac7ce5AdB8B8eC48aAb521d0Db5cd7E)
Fuel Vesting | [`0xde8a1c2d142bc8f3bf3181a2e301a37471508fe1`](https://etherscan.io/address/0xde8a1c2d142bc8f3bf3181a2e301a37471508fe1)
Fuel Migrator | [`0x50Ed39b58f66338B84E67e6Ff9a2bf00725EdFE8`](https://etherscan.io/address/0x50Ed39b58f66338B84E67e6Ff9a2bf00725EdFE8)
Sequencer Interface | [`0xca0c6B264f0F9958Ec186eb2EAa208966187D866`](https://etherscan.io/address/0xca0c6B264f0F9958Ec186eb2EAa208966187D866)
Sequencer Proxy | [`0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3`](https://etherscan.io/address/0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3)
Fuel Stream X | [`0x481aeEB9bdFe08f050d22F0b352356691c4B0b59`](https://etherscan.io/address/0x481aeEB9bdFe08f050d22F0b352356691c4B0b59)
Reward Distributor | [`0xC20c2EA5fC5f26200f3339512f336c2ecE41FC18`](https://etherscan.io/address/0xC20c2EA5fC5f26200f3339512f336c2ecE41FC18)
Vault | [`0xd57d30D06969E5A98516e9f8D009C6F39EC169eE`](https://etherscan.io/address/0xd57d30D06969E5A98516e9f8D009C6F39EC169eE)

## Fuel Mainnet

Contract Name | Contract Address
--- | ---
FuelL2BridgeId | [`0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8`](https://app.fuel.network/contract/0x4ea6ccef1215d9479f1024dff70fc055ca538215d2c8c348beddffd54583d0e8/minted-assets)
The Rig (Liquid Staking) | [`0x2181f1b8e00756672515807cab7de10c70a9b472a4a9b1b6ca921435b0a1f49b`](https://app.fuel.network/contract/0x2181f1b8e00756672515807cab7de10c70a9b472a4a9b1b6ca921435b0a1f49b/minted-assets)
L2 Staking | [`0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c`](https://app.fuel.network/contract/0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c/assets)

## Ethereum Testnet

Contract Name | Contract Address
--- | ---
FuelChainState | [`0xf38F1e65adc58fc74BaaA132f645Aa5307F2d304`](https://sepolia.etherscan.io/address/0xf38F1e65adc58fc74BaaA132f645Aa5307F2d304)
FuelERC20GatewayV4 | [`0xd1d5a4379dccC46D5c8D1c6c2656ce705698e359`](https://sepolia.etherscan.io/address/0xd1d5a4379dccC46D5c8D1c6c2656ce705698e359)
FuelMessagePortal | [`0x01855B78C1f8868DE70e84507ec735983bf262dA`](https://sepolia.etherscan.io/address/0x01855B78C1f8868DE70e84507ec735983bf262dA)
The Rig (Liquid Staking) | [`0x2aDd14eA87ce50b48F16b1eF967bf2C90632BB44`](https://sepolia.etherscan.io/address/0x2aDd14eA87ce50b48F16b1eF967bf2C90632BB44)
Fuel Vesting | [`0x7E2DB7DabaB2A8294292ecAde3F1328B2BDfc730`](https://sepolia.etherscan.io/address/0x7E2DB7DabaB2A8294292ecAde3F1328B2BDfc730)
Fuel Migrator | [`0x41d047B393C12Db1a48766690C12134999228965`](https://sepolia.etherscan.io/address/0x41d047B393C12Db1a48766690C12134999228965)
Sequencer Interface | [`0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4`](https://sepolia.etherscan.io/address/0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4)
Sequencer Proxy | [`0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD`](https://sepolia.etherscan.io/address/0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD)
Fuel Stream X | [`0x130F143e0F6d87371ca510e11340C2F3cD407a2b`](https://sepolia.etherscan.io/address/0x130F143e0F6d87371ca510e11340C2F3cD407a2b)
Reward Distributor | [`0x7c8deB33b992629130CE160f766881A191d874ce`](https://sepolia.etherscan.io/address/0x7c8deB33b992629130CE160f766881A191d874ce)
Vault | [`0xDC337a28d62eC3295F896171FA82C39c2a8e7c0A`](https://sepolia.etherscan.io/address/0xDC337a28d62eC3295F896171FA82C39c2a8e7c0A)

## Fuel Testnet

Contract Name | Contract Address
--- | ---
FuelL2BridgeId | [`0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471`](https://app-testnet.fuel.network/contract/0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471/minted-assets)
The Rig (Liquid Staking) | [`0x31b83901d35a0df4ec2c1857a420cd0e92cdb77caa08dbc912cdeb90ffa48288`](https://app-testnet.fuel.network/contract/0x31b83901d35a0df4ec2c1857a420cd0e92cdb77caa08dbc912cdeb90ffa48288/minted-assets)
L2 Staking | [`0x1fc685e1c63bbec4784079e60d4124537388f5b96773f16dfad454fae1e4f32e`](https://app-testnet.fuel.network/contract/0x1fc685e1c63bbec4784079e60d4124537388f5b96773f16dfad454fae1e4f32e/assets)


---

### File: docs/verified-addresses/docs/src/index.md

# Verified Addresses

This section serves as a reference for all verified assets, contract addresses, and security council addresses across the Fuel ecosystem.

The addresses are sourced from the following repositories:

- [Asset Addresses](https://github.com/FuelLabs/verified-assets)
- [Contract Addresses](https://github.com/FuelLabs/fuel-bridge/tree/main/packages/solidity-contracts/deployments)

The chain IDs for Fuel Ignition (mainnet) and the testnet are as follows:

- Testnet: [`0`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition-test/chain_config.json#L41)
- Mainnet: [`9889`](https://github.com/FuelLabs/chain-configuration/blob/master/ignition/chain_config.json#L41)


---

### File: docs/verified-addresses/docs/src/security-council.md

# Fuel Bridge Security Council

## Threshold Requirement: 10/13

Entity Name | Address
--- | ---
Fuel Labs | [`0x958470a2ADe72b7a01A2e160F3286767b9623Ad7`](https://etherscan.io/address/0x958470a2ADe72b7a01A2e160F3286767b9623Ad7)
Fuel Labs | [`0x81ACA96D4Ae0932d2F3463a043392efcCB1F05b6`](https://etherscan.io/address/0x81ACA96D4Ae0932d2F3463a043392efcCB1F05b6)
Fuel Labs | [`0x796C3f536C6bf5CB7661C9A0570da0e1ECD303Dd`](https://etherscan.io/address/0x796C3f536C6bf5CB7661C9A0570da0e1ECD303Dd)
Stefan George | [`0x9F7dfAb2222A473284205cdDF08a677726d786A0`](https://etherscan.io/address/0x9F7dfAb2222A473284205cdDF08a677726d786A0)
Fuel Labs | [`0xC8Bd2Ead61e54C53C5A1836352c29F10383FBad2`](https://etherscan.io/address/0xC8Bd2Ead61e54C53C5A1836352c29F10383FBad2)
Razzle Dazzel Technologies | [`0x515Fa9b26E195a043582377F51F9A9bAD2D10c7d`](https://etherscan.io/address/0x515Fa9b26E195a043582377F51F9A9bAD2D10c7d)
Delphi Labs | [`0xd4c29D8ddC7D3E326030270f35d9FD4973AbBE09`](https://etherscan.io/address/0xd4c29D8ddC7D3E326030270f35d9FD4973AbBE09)
Chorus One | [`0x5F5e0C904153789a9E978c286180b4191950d886`](https://etherscan.io/address/0x5F5e0C904153789a9E978c286180b4191950d886)
Simply Staking | [`0x446f9d40cA491cf0788dacCAc4D16d5d8B4015Cc`](https://etherscan.io/address/0x446f9d40cA491cf0788dacCAc4D16d5d8B4015Cc)
Alpha Analytics | [`0xAA52e167e8Ad426054DCF0fd5BD5481348F4FfC8`](https://etherscan.io/address/0xAA52e167e8Ad426054DCF0fd5BD5481348F4FfC8)
Kintsugi Technologies | [`0x8a34B78Feb23b97b5ccDf83D9aDC7669C34D346F`](https://etherscan.io/address/0x8a34B78Feb23b97b5ccDf83D9aDC7669C34D346F)
CryptoCrew Validators | [`0x7cdbF64f57f0D623D924d2b4c17664c1Cd9f93d4`](https://etherscan.io/address/0x7cdbF64f57f0D623D924d2b4c17664c1Cd9f93d4)
