Skip to content

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:

ts
import { Provider, TESTNET_NETWORK_URL } from 'fuels';

const provider = await Provider.create(TESTNET_NETWORK_URL);
const { consensusParameters } = provider.getChain();
const contractSizeLimit = consensusParameters.contractParameters.contractMaxSize;
See code in context

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. This tool provided by the Fuels CLI 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 (read more on how to work with Sway) or by using the Fuels CLI 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:

ts
import { Provider, TESTNET_NETWORK_URL, Wallet } from 'fuels';
import { WALLET_PVT_KEY } from 'path/to/my/env/file';
import { TypegenFactory } from 'path/to/typegen/outputs';

const provider = await Provider.create(TESTNET_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const factory = new TypegenFactory(wallet);
See code in context

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, the transactionId and a waitForResult function.

ts
// Deploy the contract
const { waitForResult, contractId, transactionId } = await factory.deploy();
// Await it's deployment
const { contract, transactionResult } = await waitForResult();
See code in context

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.

3. Executing a Contract Call

Now that the contract is deployed, you can interact with it by submitting a contract call:

ts
// Call the contract
const { waitForResult: waitForCallResult } = await contract.functions.echo_u8(10).call();
// Await the result of the call
const { value } = await waitForCallResult();
See code in context

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 deployAsBlobTx method, also available on the ContractFactory should you want to use that directly.

ts
import { Provider, TESTNET_NETWORK_URL, Wallet, ContractFactory } from 'fuels';
import { WALLET_PVT_KEY } from 'path/to/my/env/file';
import { bytecode, abi } from 'path/to/typegen/outputs';

const provider = await Provider.create(TESTNET_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const factory = new ContractFactory(bytecode, abi, wallet);

// Deploy the contract as blobs
const { waitForResult, contractId, transactionId } = await factory.deployAsBlobTx({
  // Increasing chunk size multiplier to be 90% of the max chunk size
  chunkSizeMultiplier: 0.9,
});
// Await it's deployment
const { contract, transactionResult } = await waitForResult();
See code in context

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: Blob deployments contain multiple dependent transactions, so you will need to wait longer than usual for the contract to be fully deployed and can be interacted with.