# 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`).
