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
Once you've written a contract in Sway and compiled it with forc build
(read here for more on how to work with Sway), you'll have in your hands two important artifacts: the compiled binary file and the JSON ABI file.
Below is how you can deploy your contracts using the SDK. For more details about each component in this process, read The abigen macro, The FuelVM binary file, and The JSON ABI file.
The deploy functions
There are two intended ways to deploy a contract
deploy
deploy_with_parameters
If you are only interested in a single instance of your contract, then use deploy
// 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!
abigen!(Contract(
name = "MyContract",
// This path is relative to the workspace (repository) root
abi = "packages/fuels/tests/contracts/contract_test/out/debug/contract_test-abi.json"
));
// This helper will launch a local node and provide a test wallet linked to it
let wallet = launch_provider_and_get_wallet().await;
// Optional: Configure deployment parameters or use `TxParameters::default()`
let gas_price = 0;
let gas_limit = 1_000_000;
let maturity = 0;
// This will deploy your contract binary onto the chain so that its ID can
// be used to initialize the instance
let contract_id = Contract::deploy(
// This path is relative to the current crate (examples/contracts)
"../../packages/fuels/tests/contracts/contract_test/out/debug/contract_test.bin",
&wallet,
TxParameters::new(Some(gas_price), Some(gas_limit), Some(maturity)),
StorageConfiguration::default(),
)
.await?;
println!("Contract deployed @ {contract_id}");
You can then use the contract methods very simply:
// This is an instance of your contract which you can use to make calls to your functions
let contract_instance = MyContract::new(contract_id, 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);
Alternatively, if you want multiple instances of the same contract then use deploy_with_parameters
and set the salt parameter.
use fuels::prelude::*;
use rand::prelude::{Rng, SeedableRng, StdRng};
abigen!(Contract(
name = "MyContract",
abi = "packages/fuels/tests/contracts/contract_test/out/debug/contract_test-abi.json"
));
let wallet = launch_provider_and_get_wallet().await;
let contract_id_1 = Contract::deploy(
"../../packages/fuels/tests/contracts/contract_test/out/debug/contract_test.bin",
&wallet,
TxParameters::default(),
StorageConfiguration::default(),
)
.await?;
println!("Contract deployed @ {contract_id_1}");
let rng = &mut StdRng::seed_from_u64(2322u64);
let salt: [u8; 32] = rng.gen();
let contract_id_2 = Contract::deploy_with_parameters(
"../../packages/fuels/tests/contracts/contract_test/out/debug/contract_test.bin",
&wallet,
TxParameters::default(),
StorageConfiguration::default(),
Configurables::default(),
Salt::from(salt),
)
.await?;
println!("Contract deployed @ {contract_id_2}");
assert_ne!(contract_id_1, contract_id_2);