docs/book/src/testing/testing_with_forc_call.md
forc-call is a command-line tool for interacting with deployed Fuel contracts. It allows you to make contract calls, query contract state, and interact with any deployed contract on the Fuel network - all from your command line!
The forc call command is part of the Forc toolchain and is installed alongside other Forc tools.
Here are a few examples of what you can do with forc call:
contract;
abi ContractABI {
fn add(a: u64, b: u64) -> u64;
}
impl ContractABI for Contract {
fn add(a: u64, b: u64) -> u64 {
a + b
}
}
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
--abi ./out/debug/counter-contract-abi.json \
--list-functions
Output:
Available functions in contract: 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d
add(a: u64, b: u64) -> u64
forc call \
--abi ./out/debug/counter-contract-abi.json \
0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
add "0" "0"
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
--abi ./out/debug/counter-contract-abi.json \
--contract-abi 0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07:./token-abi.json \
--contract-abi 0x1234567890abcdef:https://example.com/pool-abi.json \
--list-functions
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
--abi ./out/debug/counter-contract-abi.json \
add 1 2
forc call 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d \
--abi ./out/debug/counter-contract-abi.json \
transfer 0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07 \
--label 0xe18de7c7c8c61a1c706dccb3533caa00ba5c11b5230da4428582abf1b6831b4d:MainContract \
--label 0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07:TokenContract \
-vvv
forc call 0x2c7Fd852EF2BaE281e90ccaDf18510701989469f7fc4b042F779b58a39919Eec --amount 2 --mode=live
forc call \
--testnet \
--abi https://raw.githubusercontent.com/mira-amm/mira-v1-periphery/refs/heads/main/fixtures/mira-amm/mira_amm_contract-abi.json \
0xd5a716d967a9137222219657d7877bd8c79c64e1edb5de9f2901c98ebe74da80 \
owner
Forc call has 3 usage modes:
Syntax for forc call for listing supported functions from the ABI - with example command to perform call operation:
forc call --abi <ABI-PATH/URL> <CONTRACT_ID> --list-functions
You can also list functions from multiple contracts by providing additional contract ABIs:
forc call --abi <MAIN-ABI-PATH/URL> <MAIN-CONTRACT_ID> \
--contract-abi <CONTRACT_ID>:<ABI-PATH/URL> \
--contract-abi <ANOTHER-CONTRACT_ID>:<ABI-PATH/URL> \
--list-functions
Where the following arguments are required:
ABI-PATH/URL is the path or URL to the contract's JSON ABI fileCONTRACT_ID is the ID of the deployed contract you want to interact with--contract-abi (optional) allows you to specify additional contracts and their ABIs to list functions from multiple contracts at onceSyntax for forc call for transferring assets:
forc call <RECEIVER_ADDRESS> --amount <AMOUNT> --mode=live
Where the following arguments are required:
RECEIVER_ADDRESS is address of the receiver (identity or contract).AMOUNT is the amount of assets to transfer.Note: only live mode --mode=live is supported; transfers cannot be simulated.
Syntax for forc call for contract calls:
forc call [OPTIONS] --abi <ABI-PATH/URL> <CONTRACT_ID> <SELECTOR> [ARGS]...
Where the following arguments are required:
CONTRACT_ID is the ID of the deployed contract you want to interact withABI-PATH/URL is the path or URL to the contract's JSON ABI fileSELECTOR is the function name (selector) you want to callARGS are the arguments to pass to the functionWhen passing arguments to contract functions, values are encoded according to their Sway types. Here's how to format different types:
| Types | Example input | Notes |
|---|---|---|
| bool | true or false | |
| u8, u16, u32, u64, u128, u256 | 42 | |
| b256 | 0x0000000000000000000000000000000000000000000000000000000000000042 or 0000000000000000000000000000000000000000000000000000000000000042 | 0x prefix is optional |
| bytes, RawSlice | 0x42 or 42 | 0x prefix is optional |
| String, StringSlice, StringArray (Fixed-size) | "abc" | |
| Tuple | (42, true) | The types in tuple can be different |
| Array (Fixed-size), Vector (Dynamic) | [42, 128] | The types in array or vector must be the same; i.e. you cannot have [42, true] |
| Struct | {42, 128} | Since structs are packed encoded, the attribute names are not encoded; i.e. {42, 128}; this could represent the following struct Polygon { x: u64, y: u64 } |
| Enum | (Active: true) or (1: true) | Enums are key-val pairs with keys as being variant name (case-sensitive) or variant index (starting from 0) and values as being the variant value; this could represent the following enum MyEnum { Inactive, Active(bool) } |
The ABI (Application Binary Interface) can be provided in two ways.
forc call <CONTRACT_ID> --abi ./path/to/abi.json <FUNCTION> [ARGS...]
forc call <CONTRACT_ID> --abi https://example.com/abi.json <FUNCTION> [ARGS...]
forc call --node-url http://127.0.0.1:4000 ...
# or
forc call --target local ...
# utilising the forc-wallet
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --wallet
# with an explicit signing key
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --signing-key <KEY>
If the contract ABI contains errorCodes and panickingCalls (generated by panic-aware builds), forc call will display rich revert information — panic message, panic value, and backtrace — inline in the trace output. Run with verbosity to see it:
forc call <CONTRACT_ID> \
--abi ./out/debug/my_contract-abi.json \
write_non_zero 0 -vv
Example (formatted):
[Script]
├─ [1017] <contract>::write_non_zero(0)
│ ├─ emit ZeroValue
│ └─ ← [Revert]
│ ├─ revert code: 8000000000001001
│ ├─ panic message: The provided value must be greater than zero.
│ ├─ panic value: ZeroValue
│ ├─ panicked: in my_contract::ensure_non_zero
│ │ └─ at src/main.sw:45:9
│ └─ backtrace: called in my_contract::set_non_zero_value
│ └─ at src/main.sw:38:5
│ called in <Contract as AbiErrorDemo>::write_non_zero
│ └─ at src/main.sw:26:9
[ScriptResult] result: Revert, gas_used: 784
If the ABI does not include those sections, only the raw revert code is displayed.
# Native asset transfer
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --amount 100 --live
# Custom asset transfer
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> \
--amount 100 \
--asset-id 0x1234... \
--live
# Set gas price
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --gas-price 1
# Forward gas to contract
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --gas-forwarded 1000
# Set maximum fee
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> --max-fee 5000
When you need to debug contract interactions or understand the execution flow, forc call provides detailed transaction traces with verbosity level 2 or higher (-vv or -v=2).
# Enable transaction tracing
forc call <CONTRACT_ID> --abi <PATH> <FUNCTION> -vv
The transaction trace provides a hierarchical view of all contract calls, showing:
[gas_amount])For better readability, you can label contract addresses in transaction traces using the --label flag:
# Add human-readable labels to contract addresses
forc call <CONTRACT_ID> \
--abi <PATH> \
<FUNCTION> \
--label <CONTRACT_ID>:MainContract \
--label <OTHER_CONTRACT_ID>:TokenContract \
-vv
Without labels:
├─ [8793] 0x2af09151f8276611ba65f14650970657bc42c1503d6502ffbb4d085ec37065dd::transfer(100, 0x123)
│ └─ ← ()
With labels:
├─ [8793] TokenContract::transfer(100, 0x123)
│ └─ ← ()
For complex multi-contract interactions, you can provide additional contract ABIs to improve function signature and return data decoding:
# Add additional contract ABIs for better trace decoding
forc call <CONTRACT_ID> \
--abi <MAIN_ABI_PATH> \
<FUNCTION> \
--contract-abi <OTHER_CONTRACT_ID>:./external-abi.json \
--contract-abi <THIRD_CONTRACT_ID>:https://example.com/abi.json \
-vv
This helps decode:
forc call 0x9275a76531bce733cfafdbcb6727ea533ebbdc358d685152169b3c4eaa47b965 \
--abi ./demo/demo-caller-abi.json \
call_increment_count \
--label 0x9275a76531bce733cfafdbcb6727ea533ebbdc358d685152169b3c4eaa47b965:DemoCaller \
--label 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42:Counter \
--contract-abi 0xb792b1e233a2c06bccec611711acc3bb61bdcb28f16abdde86d1478ee02f6e42:./counter-abi.json \
-vv
Output:
Traces:
[Script]
├─ [124116] DemoCaller::call_increment_count()
│ ├─ [111500] Counter::increment()
│ │ └─ ← ()
│ ├─ emit AsciiString { data: "incremented count" }
│ ├─ [86284] Counter::get_count()
│ │ └─ ← 0x0000000000000002
│ ├─ emit 2
│ ├─ emit AsciiString { data: "done" }
│ ├─ [72699] Counter::increment()
│ │ └─ ← ()
│ ├─ [48287] Counter::get_count()
│ │ └─ ← 0x0000000000000003
│ └─ ← 0x0000000000000003
└─ ← [Return] val: 1
[ScriptResult] result: Success, gas_used: 89279
Transaction successfully executed.
Gas used: 160676
[Script] - The root transaction script├─ [gas_amount] ContractLabel::function_name(args) - A contract call with gas consumption and decoded function info│ └─ ← value - Return value from the contract callemit data - Log/event emitted by the contract[ScriptResult] - Final transaction result with gas used by the scriptGas used: <gas_used> - Total gas used by the transactionThis tracing feature is particularly useful for:
# Read contract state
forc call <CONTRACT_ID> --abi <PATH> get_balance
# Query with parameters
forc call <CONTRACT_ID> --abi <PATH> get_user_info 0x1234...
# Update contract state
forc call <CONTRACT_ID> --abi <PATH> update_state 42 --live
# Transfer assets/tokens to an address
forc call <ADDRESS> --amount 100 --live
# Debug complex multi-contract interactions
forc call <MAIN_CONTRACT_ID> \
--abi <MAIN_ABI_PATH> \
complex_operation \
--label <MAIN_CONTRACT_ID>:MainContract \
--label <TOKEN_CONTRACT_ID>:TokenContract \
--label <POOL_CONTRACT_ID>:LiquidityPool \
--contract-abi <TOKEN_CONTRACT_ID>:./token-abi.json \
--contract-abi <POOL_CONTRACT_ID>:./pool-abi.json \
-vv
--label <contract_id>:<label> - Add human-readable labels for contract addresses in traces
0x prefix--label 0x123:MainContract--contract-abi <contract_id>:<abi_path> - Specify additional contract ABIs for better trace decoding
0x prefix--contract-abi 0x123:./abi.json or --contract-abi 0x456:https://example.com/abi.json-v, -vv, -vvv - Verbosity levels for trace output
-v: Show decoded logs-vv: Additionally show transaction traces-vvv: Additionally show receipts and script JSON--mode simulate to estimate gas costs before making live transactions--external-contractsSIGNING_KEY=<key>--label flags to replace long contract addresses with meaningful names in traces--contract-abi to decode function calls and return values from external contractsABI Mismatch:
Parameter Type Errors:
Network Issues:
Transaction Failures:
Trace Decoding Issues: