sway Documentation

Empowering everyone to build reliable and efficient smart contracts.

61,514 stars Rust Rust 1 file ยท ~12,325 tokens #compiler#fuel#language#sway
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy sway on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name sway --restart always fuellabs/sway:latest

1. Project Overview & Quickstart (FuelLabs/sway)

File: README.md

Sway





Sway is a language developed for the Fuel blockchain. It is heavily inspired by Rust and aims to bring modern language development and performance to the blockchain ecosystem.

Documentation

For user documentation, including installing release builds, see the latest released Sway Book: https://fuellabs.github.io/sway/latest/.

The documentation URLs describe different source versions:

  • latest redirects to the most recently published Sway release.
  • vX.Y.Z is documentation built from that exact Sway release tag.
  • master is built from the default branch and may describe unreleased behavior.

These labels are Sway documentation versions. They are not Fuelup channel names and do not identify the toolchain activated on a Fuel network. Check the compiler you are running with forc --version and consult the Fuelup channel documentation when selecting network-compatible tooling.

For Sway standard library documentation from the default branch, see https://fuellabs.github.io/sway/master/std/.

Also view the default-branch technical reference for the Sway programming language at https://fuellabs.github.io/sway/master/reference/.

The Stable Sway and Forc pages on docs.fuel.network are published by FuelLabs/docs-hub from an explicitly selected Sway release. That selection can differ from both the newest upstream release and the compiler in a named Fuelup network channel.

Building from Source

This section is for developing the Sway compiler and toolchain. For developing contracts and using Sway, see the above documentation section.

Dependencies

Sway is built in Rust. To begin, install the Rust toolchain following instructions at https://www.rust-lang.org/tools/install. Then configure your Rust toolchain to use Rust stable:

sh
rustup default stable

If not already done, add the Cargo bin directory to your PATH by adding the following line to ~/.profile and restarting the shell session.

sh
export PATH="${HOME}/.cargo/bin:${PATH}"

Building Forc

Clone the repository and build the Sway toolchain:

sh
git clone [email protected]:FuelLabs/sway.git
cd sway
cargo build

Confirm the Sway toolchain built successfully:

sh
cargo run --bin forc -- --help

All other scripts/commands

For all other scripts and commands use https://github.com/casey/just:

text
> just --list
Available recipes:
    [automation]
    update-contract-ids
    update-fuel-dependencies

    [benchmark]
    benchmark
    benchmark-tests
    collect-gas-usage

    [build]
    build-highlightjs
    build-prism
    generate-sway-lib-std

    [ci]
    ci-check
    install-ci-check

    [test]
    test-forc-fmt-check-panic

Contributing to Sway

We welcome contributions to Sway!

Please see the Contributing To Sway section of the Sway book for guidelines and instructions to help you get started.


File: 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., [email protected], custom_contract)

**Options**

  • --path : Add a local path dependency.

  • --git : Add a Git-based dependency.

    • Can be combined with one of:

      • --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 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.

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

File: README.md

Fuel Docs Hub

Running locally

Requirements

To begin, make sure you have installed the following dependencies:

Clone the Repository

sh
git clone --recursive https://github.com/FuelLabs/docs-hub
cd docs-hub

Install Dependencies

sh
pnpm install

Run Web App

Start a local development frontend. After running the below command you can open http://localhost:3000 in your browser to view the frontend.

sh
pnpm dev

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

AI

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


File: docs/intro/glossary.mdx

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.mdx

Quickstart

Get started with Fuel and discover the path that best suits your needs.


File: docs/intro/what-is-fuel.mdx

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/guides/examples/counter-dapp/frontend/README.md

React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

  • Configure the top-level parserOptions property like this:
js
export default {
  // other rules...
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    project: ['./tsconfig.json', './tsconfig.node.json', './tsconfig.app.json'],
    tsconfigRootDir: __dirname,
  },
}
  • Replace plugin:@typescript-eslint/recommended to plugin:@typescript-eslint/recommended-type-checked or plugin:@typescript-eslint/strict-type-checked
  • Optionally add plugin:@typescript-eslint/stylistic-type-checked
  • Install eslint-plugin-react and add plugin:react/recommended & plugin:react/jsx-runtime to the extends list

File: docs/guides/docs/contract-quickstart/index.mdx


Smart Contract Quickstart

Getting started with Fuel as a smart contract developer is as simple as:

  1. Installing fuelup
  2. Generating a counter contract
  3. Building the contract
  4. Setting up a local wallet
  5. Deploying the contract

Installation

Already have `fuelup` installed?

Generating a counter contract

Run the command below to generate a counter contract in Sway:

{/* TODO: Replace when forc template command is stable

sh
forc template --template-name counter counter-contract

*/}

{/TODO: Remove when forc template command is stable/}

<TestAction
id="create-contract-project"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/'
}}
/>

The contract will be in the src/main.sw file.

Building the contract

To build a contract, move inside the counter-contract folder:

sh
cd counter-contract

{/TODO: Remove when forc template command is stable/}

Copy and paste the code below into your src/main.sw file

<TestAction
id="copy-contract"
action={{
name: 'writeToFile',
filepath: 'guides-testing/counter-contract/src/main.sw'
}}
/>

Next, run the forc build command:

<TestAction
id="build-contract"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/counter-contract'
}}
/>

sh
forc build

Setting up a local wallet

You can get test funds using the faucet.

Deploying the contract

To deploy the contract to the testnet, you can run:

sh
forc deploy --testnet

Next Steps

Ready to learn more? Check out the following resources:


File: docs/guides/docs/counter-dapp/building-a-frontend.mdx


Building a Frontend to Interact With Your Contract

To build a frontend application for the counter contract, we'll do the following:

  1. Install the Fuel Browser Wallet.
  2. Initialize a React project.
  3. Install the fuels SDK dependency.
  4. Generate contract types.
  5. Write our frontend code.
  6. Run our project.

Install the Fuel Browser Wallet

{/install_wallet:example:start/}
Our frontend application will allow users to connect with a wallet, so you'll need to have a browser wallet installed.

Before going to the next steps, install the Fuel Wallet extension.

Once you've setup your wallet, click the "Faucet" button in the wallet to get some testnet tokens.
{/install_wallet:example:end/}

Initialize a React project

To split our project's contract from frontend code, let's initialize our frontend project: assuming that your terminal is open at your contract's folder /home/user/path/to/counter-contract let's go back up one directory.

sh
cd ..

Now, initialize a React project with TypeScript using Vite.

<TestAction
id="create-vite-project"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project'
}}
/>

sh
npm create vite@latest frontend -- --template react-ts

The output should be similar to this:

sh
Scaffolding project in Fuel/fuel-project/frontend...

Done. Now run:

  cd frontend
  npm install
  npm run dev

Installing

Move into the frontend folder and install the dependencies by running:

<TestAction
id="install-basic-deps"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project'
}}
/>

sh
cd frontend && npm install

You should now have two folders inside your fuel-project folder: counter-contract and frontend.

Install the `fuels` SDK dependency

The fuels package includes all the main tools you need to interact with your Sway programs and the Fuel network.
The @fuel-wallet packages include everything you need to interact with user wallets.

fuels requires Node version {props.nodeVersion}.

Install the following packages in your frontend folder:

<TestAction
id="install-deps"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project/frontend'
}}
/>

sh
npm install fuels @fuels/react @fuels/connectors @tanstack/react-query

Generate contract types

The fuels init command generates a fuels.config.ts file that is used by the SDK to generate contract types.
Use the contracts flag to define where your contract folder is located, and the output flag to define where you want the generated files to be created.

Run the command below in your frontend folder to generate the config file:

<TestAction
id="fuels_config"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project/frontend'
}}
/>

sh
npx fuels init --contracts ../counter-contract/ --output ./src/sway-api

Now that you have a fuels.config.ts file, you can use the fuels build command to rebuild your contract and generate types.
Running this command will interpret the output ABI JSON from your contract and generate the correct TypeScript definitions.
If you see the folder fuel-project/counter-contract/out you will be able to see the ABI JSON there.

Inside the fuel-project/frontend directory run:

<TestAction
id="typegen"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project/frontend'
}}
/>

sh
npx fuels build

A successful process should print and output like the following:

sh
Building..
Building Sway programs using source 'forc' binary
Generating types..
๐ŸŽ‰  Build completed successfully!

Now you should be able to find a new folder fuel-project/frontend/src/sway-api.

Modify the App

Inside the frontend/src folder let's add code that interacts with our contract.

Because we'll be using @fuels/react, first we need to wrap our app with the FuelProvider component.

Add the imports below to the top of your frontend/src/main.tsx file and setup a query client:

<TestAction
id="provider-import"
action={{
name: 'modifyFile',
filepath: 'guides-testing/fuel-project/frontend/src/main.tsx',
atLine: 5,
}}
/>

Next, modify your frontend/src/main.tsx file to wrap the App component with the FuelProvider and QueryClientProvider components.

<TestAction
id="fuel-wallet-provider"
action={{
name: 'modifyFile',
filepath: 'guides-testing/fuel-project/frontend/src/main.tsx',
atLine: 11,
removeLines: [11,12,13,14,15],
}}
/>

Next, change the file fuel-project/frontend/src/App.tsx to:

<TestAction
id="app-code"
action={{
name: 'writeToFile',
filepath: 'guides-testing/fuel-project/frontend/src/App.tsx'
}}
/>

Finally, replace the value of the CONTRACT_ID variable at the top of your App.tsx file with the address of the contract you just deployed.

<TestAction
id="app-contract-id"
action={{
name: 'modifyFile',
filepath: 'guides-testing/fuel-project/frontend/src/App.tsx',
atLine: 13,
removeLines: [13],
useSetData: ' "0x92073699bd78dac70756a9e0e8bca1c7121c7adc4b90570800f0916fe4ac33dd";'
}}
/>

Run your project

Inside the fuel-project/frontend directory run:

<TestAction
id="start-app"
action={{
name: 'runCommand',
preCommand: "pnpm pm2 start 'BROWSER=none ' --name 'react-dapp' --cwd ./guides-testing/fuel-project/frontend"
}}
/>

sh
npm run dev
sh
VITE v5.3.5  ready in 108 ms

  โžœ  Local:   http://localhost:5173/
  โžœ  Network: use --host to expose
  โžœ  press h + enter to show help

Click the "Connect" button and select the wallet you have installed to connect your wallet.

Once connected, if there are no funds in your wallet, you will see a link to get testnet funds.

If you have testnet ETH on Fuel, you should see the counter value and increment button:

You just built a fullstack dapp on Fuel! โ›ฝ

Here is the repo for this project.

If you run into any problems, a good first step is to compare your code to this repo and resolve any differences.

Tweet us @fuel_network letting us know you just built a dapp on Fuel, you might get invited to a private group of builders, be invited to the next Fuel dinner, get alpha on the project, or something ๐Ÿ‘€.

Updating The Contract

To develop and test faster, we recommend using the fuels dev command to start a local node and automatically redeploy and generate types for your contract on each change.

Once you're ready to redeploy your contract to the testnet, here are the steps you should take to get your frontend and contract back in sync:

  • In your frontend directory, re-run this command: npx fuels build.
  • In your contract directory, redeploy the contract.
  • In your frontend directory, update the contract ID in your App.tsx file.

Need Help?

Get help from the team by posting your question in the Fuel Forum.

<TestAction
id="wait-after-start-app"
action={{
name: 'wait',
timeout: 20000
}}
/>

<TestAction
id="go-to-frontend"
action={{
name: 'goToUrl',
url: "http://localhost:5173"
}}
/>

<TestAction
id="click-connect-button"
action={{
name: 'clickByRole',
role: "button",
elementName: "Connect"
}}
/>

<TestAction
id="click-fuel-wallet"
action={{
name: 'clickByLabel',
label: 'Connect to Fuel Wallet'
}}
/>

<TestAction
id="approve-connect"
action={{
name: 'walletApproveConnect',
}}
/>

<TestAction
id="wait-after-connect"
action={{
name: 'wait',
timeout: 5000
}}
/>

<TestAction
id="get-initial-count"
action={{
name: 'getByLocator-save',
locator: "h3 ~ div",
}}
/>

{/*
<TestAction
id="click-increment-button"
action={{
name: 'clickByRole',
role: "button",
elementName: "Increment"
}}
/>
<TestAction
id="approve-txn"
action={{
name: 'walletApprove',
}}
/>

<TestAction
id="wait-after-approve"
action={{
name: 'wait',
timeout: 15000
}}
/>

<TestAction
id="reload-after-approve"
action={{
name: 'reload',
}}
/>

<TestAction
id="wait-after-reload"
action={{
name: 'wait',
timeout: 7000
}}
/>

<TestAction
id="get-final-count"
action={{
name: 'getByLocator-save',
locator: "h3 ~ div",
}}
/>

<TestAction
id="check-count"
action={{
name: 'checkIfIsIncremented',
initialIndex: 0,
finalIndex: 1
}}
/> */}


File: docs/guides/docs/counter-dapp/building-a-smart-contract.mdx


Writing A Sway Smart Contract

Installation

{/install_help:example:start/}

Having problems? Visit the installation guide or post your question in our forum.
{/install_help:example:end/}

Already have `fuelup` installed?

{/already_installed:example:start/}
If you already have fuelup installed, run the commands below to make sure you are on the most up-to-date toolchain.

sh
fuelup self update
fuelup update
fuelup default latest

{/already_installed:example:end/}

Your First Sway Project

We'll build a simple counter contract with two functions: one to increment the counter, and one to return the value of the counter.

Start by creating a new, empty folder. We'll call it fuel-project.

<TestAction
id="create-project-folder"
action={{
name: 'runCommand',
commandFolder: 'guides-testing'
}}
/>

sh
mkdir fuel-project

Writing the Contract

Move inside of your fuel-project folder:

sh
cd fuel-project

Then create a contract project using forc:

<TestAction
id="create-contract"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project'
}}
/>

{/ANCHOR: new_forc_contract/}

sh
forc new counter-contract

{/ANCHOR_END: new_forc_contract/}

You will get this output:

sh
To compile, use `forc build`, and to run tests use `forc test`
----
Read the Docs:
- Sway Book: https://docs.fuel.network/docs/sway
- Forc Book: https://docs.fuel.network/docs/forc
- Rust SDK Book: https://docs.fuel.network/docs/fuels-rs
- TypeScript SDK: https://docs.fuel.network/docs/fuels-ts

Join the Community:
- Follow us @SwayLang: https://twitter.com/SwayLang
- Ask questions on Discourse: https://forum.fuel.network/

Report Bugs:
- Sway Issues: https://github.com/FuelLabs/sway/issues/new

{/This example should include a tree for a new forc project and explain the boilerplate files/}
{/forc_new:example:start/}
Here is the project that forc has initialized:

<TestAction
id="contract-tree"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project'
}}
/>

sh
tree counter-contract
sh
counter-contract
โ”œโ”€โ”€ Forc.toml
โ””โ”€โ”€ src
    โ””โ”€โ”€ main.sw

1 directory, 2 files

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_new:example:end/}

Open your project in a code editor and delete everything in src/main.sw apart from the first line.

Every Sway file must start with a declaration of what type of program the file contains; here, we've declared that this file is a contract.
You can learn more about Sway program types in the Sway Book.

<TestAction
id="program-type"
action={{
name: 'writeToFile',
filepath: 'guides-testing/fuel-project/counter-contract/src/main.sw'
}}
/>

Next, we'll define a storage value.
In our case, we have a single counter that we'll call counter of type u64 (a 64-bit unsigned integer) and initialize it to 0.

<TestAction
id="storage"
action={{
name: 'modifyFile',
filepath: 'guides-testing/fuel-project/counter-contract/src/main.sw'
}}
/>

ABI

ABI stands for Application Binary Interface.
An ABI defines an interface for a contract.
A contract must either define or import an ABI declaration.

It is considered best practice to define your ABI in a separate library and import it into your contract.
This allows callers of the contract to import and use the ABI more easily.

For simplicity, we will define the ABI directly in the contract file itself.

<TestAction
id="abi"
action={{
name: 'modifyFile',
filepath: 'guides-testing/fuel-project/counter-contract/src/main.sw'
}}
/>

Implement ABI

Below your ABI definition, you will write the implementation of the functions defined in your ABI.

<TestAction
id="impl"
action={{
name: 'modifyFile',
filepath: 'guides-testing/fuel-project/counter-contract/src/main.sw'
}}
/>

storage.counter.read() is an implicit return and is equivalent to return storage.counter.read();.

Here's what your code should look like so far:

File: ./counter-contract/src/main.sw

<TestAction
id="entire-contract"
action={{
name: 'compareToFile',
filepath: 'guides-testing/fuel-project/counter-contract/src/main.sw'
}}
/>

Build the Contract

Navigate to your contract folder:

sh
cd counter-contract

Then run the following command to build your contract:

<TestAction
id="build-contract"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project/counter-contract'
}}
/>

sh
forc build
sh
Compiled library "core".
  Compiled library "std".
  Compiled contract "counter-contract".
  Bytecode size: 84 bytes.

Let's have a look at the content of the counter-contract folder after building:

<TestAction
id="built-contract-tree"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project/counter-contract'
}}
/>

sh
tree .
sh
.
โ”œโ”€โ”€ Forc.lock
โ”œโ”€โ”€ Forc.toml
โ”œโ”€โ”€ out
โ”‚   โ””โ”€โ”€ debug
โ”‚       โ”œโ”€โ”€ counter-contract-abi.json
โ”‚       โ”œโ”€โ”€ counter-contract-storage_slots.json
โ”‚       โ””โ”€โ”€ counter-contract.bin
โ””โ”€โ”€ src
    โ””โ”€โ”€ main.sw

3 directories, 6 files

We now have an out directory that contains our build artifacts such as the JSON representation of our ABI and the contract bytecode.

Testing your Contract with Rust

Don't want to test with Rust? Skip this section and jump to Deploy the Contract.

We will start by adding a Rust integration test harness using a Cargo generate template.
If you don't already have Rust installed, you can install it by running this command:

Next, if you don't already have it installed, let's install cargo generate:

sh
cargo install cargo-generate --locked

Now, let's generate the default test harness with the following command:

<TestAction
id="cargo-generate-test"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project/counter-contract'
}}
/>

sh
cargo generate --init fuellabs/sway templates/sway-test-rs --name counter-contract
sh
โš ๏ธ   Favorite `fuellabs/sway` not found in config, using it as a git repository: https://github.com/fuellabs/sway.git
๐Ÿ”ง   Destination: /home/user/path/to/counter-contract ...
๐Ÿ”ง   project-name: counter-contract ...
๐Ÿ”ง   Generating template ...
๐Ÿ”ง   Moving generated files into: `/home/user/path/to/counter-contract`...
โœจ   Done! New project created /home/user/path/to/counter-contract

Let's have a look at the result:

<TestAction
id="cargo-test-tree"
action={{
name: 'runCommand',
commandFolder: 'guides-testing/fuel-project/counter-contract'
}}
/>

sh
tree .
sh
.
โ”œโ”€โ”€ Cargo.toml
โ”œโ”€โ”€ Forc.lock
โ”œโ”€โ”€ Forc.toml
โ”œโ”€โ”€ out
โ”‚   โ””โ”€โ”€ debug
โ”‚       โ”œโ”€โ”€ counter-contract-abi.json
โ”‚       โ”œโ”€โ”€ counter-contract-storage_slots.json
โ”‚       โ””โ”€โ”€ counter-contract.bin
โ”œโ”€โ”€ src
โ”‚   โ””โ”€โ”€ main.sw
โ””โ”€โ”€ tests
    โ””โ”€โ”€ harness.rs

4 directories, 8 files

Now that we have our default test harness, let's add a useful test to it.

At the bottom of test/harness.rs below the can_get_contract_id() test, add the test_increment test function below to verify that the value of the counter gets incremented:

<TestAction
id="test-harness"
action={{
name: 'modifyFile',
filepath: 'guides-testing/fuel-project/counter-contract/tests/harness.rs',
addSpacesBefore: 1,
}}
/>

Here is what your file should look like:

File: ./counter-contract/tests/harness.rs

<TestAction
id="final-test-harness"
action={{
name: 'compareToFile',
filepath: 'guides-testing/fuel-project/counter-contract/tests/harness.rs'
}}
/>

Run cargo test in the terminal:

sh
cargo test

If all goes well, the output should look as follows:

sh
...
  running 2 tests
  test can_get_contract_id ... ok
  test test_increment ... ok
  test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.25s

Deploy the Contract

It's now time to deploy . We will show how to do this using forc from the command line, but you can also do it using the Rust SDK or the TypeScript SDK.

In order to deploy a contract, you need to have a wallet to sign the transaction and coins to pay for gas. Fuelup will guide you in this process.

Setting up a local wallet

You can get test funds using the faucet.

Deploy To Testnet

Now, you can deploy the contract to the latest testnet with the forc deploy command.

sh
forc deploy --testnet

{/forc_wallet:example:start/}
The terminal will ask for the password of the wallet:

Please provide the password of your encrypted wallet vault at "~/.fuel/wallets/.wallet":

Once you have unlocked the wallet, the terminal will show a list of the accounts:

sh
Account 0 -- fuel18caanqmumttfnm8qp0eq7u9yluydxtqmzuaqtzdjlsww5t2jmg9skutn8n:
  Asset ID                                                           Amount
  0000000000000000000000000000000000000000000000000000000000000000 499999940

Just below the list, you'll see this prompt:

Please provide the index of account to use for signing:

Then you'll enter the number of the account of preference and press Y when prompted to accept the transaction.

Finally, you will get back the network endpoint where the contract was deployed, a Contract ID and the block where the transaction was signed.
{/forc_wallet:example:end/}

Save the Contract ID, as you'll need this later to connect the frontend.

sh
Contract counter-contract Deployed!

Network: https://testnet.fuel.network
Contract ID: 0x8342d413de2a678245d9ee39f020795800c7e6a4ac5ff7daae275f533dc05e08
Deployed in block 0x4ea52b6652836c499e44b7e42f7c22d1ed1f03cf90a1d94cd0113b9023dfa636

Congrats, you have completed your first smart contract on Fuel โ›ฝ

Here is the repo for this project. If you run into any problems, a good first step is to compare your code to this repo and resolve any differences.

Tweet us @fuel_network letting us know you just built a dapp on Fuel, you might get invited to a private group of builders, be invited to the next Fuel dinner, get alpha on the project, or something ๐Ÿ‘€.

Need Help?

Get help from the team by posting your question in the Fuel Forum.