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:
- Sign the transaction via your local wallet using
forc-client
which integrates with our CLI wallet,forc-wallet
. - Use the default signer to deploy to a local node
- Use
forc-wallet
to manually sign transactions, and copy the signed transaction back toforc-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:
> 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:
> 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.
- Construct the transaction by using either
forc deploy
orforc run
. To do so simply runforc deploy --manual-sign
orforc run --manual-sign
with your desired parameters. For a list of parameters please refer to the forc-deploy or forc-run 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. - 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. - Take the signature generated in the second step and provide it to
forc-deploy
(orforc-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.
forc wallet accounts
- If you want to retrieve the address for an account by its index you can use
account
command.
forc wallet account <account_index>
If you want to sign the transaction generated by
forc-deploy
orforc-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.forc-deploy --default-signer
forc-run --default-signer
By default --default-signer
flag would sign your transactions with the following private-key:
0xde97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c
Interacting with the testnet
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
.
forc-deploy --testnet
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.
forc-deploy --node-url https://beta-3.fuel.network
Another alternative is the --target
option, which provides useful aliases to all targets. For example if you want to deploy to beta-5
you can use:
forc-deploy --target beta-5
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.
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.
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:
{
"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.
[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 implementation from 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 compliant proxy contract rather than deploying a new one, simply add its address
in the address
field, like the following example:
[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 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 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:
- For scripts and predicates, the bytecode is uploaded as a blob.
- A loader is generated that can load and execute the blob.
- 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.