Skip to content

Conversation

zees-dev
Copy link
Contributor

Description

This PR updates the forc call functionality to provide detailed call traces.
This is achieved via retrieving Vec<StorageReadReplayEvent> from transactions (dry-run and/or live mode) and executing these in a vm-interpreter.

Additional forc-call updates:

  • introduction of contract address labelling via --label <contract-addr>:<name>
  • introduction of providing additional contract abis via --contract-abi <contract-addr>:<abi-file-or-url>

Example

Assume the following 2 contracts - where demo-caller calls demo contract:

  • demo: 0xe84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295
  • demo-caller: 0xed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485
demo contract source
contract;

use std::{logging::log};

struct Adder {
    vals: (u64, u64),
}

abi Demo {
    #[storage(read)]
    fn get_count() -> u64;

    #[storage(read, write)]
    fn increment_count(adder: Adder);
}

storage {
    count: u64 = 0,
}

impl Demo for Contract {
    #[storage(read)]
    fn get_count() -> u64 {
        storage.count.read() + 1
    }

    #[storage(read, write)]
    fn increment_count(adder: Adder) {
        let new_count = storage.count.read() + adder.vals.0 + adder.vals.1;
        storage.count.write(new_count);
        log(new_count);
    }
}
demo-caller contract source
contract;

use std::contract_id::ContractId;

struct Adder {
    vals: (u64, u64),
}

abi Demo {
    #[storage(read)]
    fn get_count() -> u64;
    
    #[storage(read, write)]
    fn increment_count(adder: Adder);
}

abi DemoCaller {
    #[storage(read, write)]
    fn call_increment_count(adder: Adder) -> u64;
    
    #[storage(read)]
    fn check_current_count() -> u64;
}

const CONTRACT_ID = 0xe84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295;

impl DemoCaller for Contract {
    #[storage(read, write)]
    fn call_increment_count(adder: Adder) -> u64 {
        let demo = abi(Demo, CONTRACT_ID);
        demo.increment_count(adder);
        log("incremented count");
        log(demo.get_count());
        log("done");
        demo.increment_count(Adder { vals: (5, 2) });
        demo.get_count()
    }
    
    #[storage(read)]
    fn check_current_count() -> u64 {
        let demo = abi(Demo, CONTRACT_ID);
        demo.get_count()
    }
}

Previous functionality:

cargo run -p forc-client --bin forc-call -- \
  --abi ./demo/demo-caller/out/release/demo-caller-abi.json \
  ed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485 \
  call_increment_count "{(1,1)}" -vvv

Output:
Screenshot 2025-06-24 at 12 14 53 PM

Updated functionality:

cargo run -p forc-client --bin forc-call -- \
  --abi ./demo/demo-caller/out/release/demo-caller-abi.json \
  ed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485 \
  --contract-abi e84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295:./demo/demo/out/release/demo-abi.json \
  --label ed4437b191cc78a02df048f21a73df37f1627efdde7d7e4232468b9de9d83485:demo-caller \
  --label e84e278cb083a5b3ff871f1d3de26fdd13ae044070e1bbda18b60a13f98bb295:demo \
  call_increment_count "{(1,1)}" -vv

Output:
Screenshot 2025-06-24 at 12 15 25 PM

Other misc. improvements to forc-call

  • refactor of the forc-call verbosity levels and functions (arguably cleaner code)
  • re-write of the tracing to simply process receipts and indent via stack - instead of recursively constructing node-call tree
  • closes forc-call tracing detailed insights #7197

AI description

This pull request introduces significant enhancements to the forc call functionality, improving usability, debugging, and trace readability for multi-contract interactions.
The changes include support for labeled contract addresses, additional ABI files for better decoding, and updates to verbosity levels. Additionally, dependencies and internal parsing logic have been updated to support these features.

Enhancements to forc call functionality:

  • Support for labeled contract addresses:

    • Added the --label flag to allow users to assign human-readable labels to contract addresses in transaction traces, improving readability. [1] [2]
    • Updated documentation to include examples of using labels in traces. [1] [2]
  • Support for additional ABIs:

    • Introduced the --contract-abi flag to specify additional contract ABIs for decoding function signatures, parameters, and return values in multi-contract interactions. [1] [2]
    • Updated the parsing logic to handle additional ABIs and labels.
    • Documentation now includes examples and explanations for using additional ABIs. [1] [2]
  • Improved verbosity and tracing:

    • Adjusted verbosity levels to make transaction traces available at -vv instead of -vvv.
    • Enhanced trace output to include labeled contract addresses and decoded function information. [1] [2]

Dependency and internal updates:

  • Dependency additions:

    • Added fuel-core-storage as a dependency in Cargo.toml to support new features. [1] [2]
  • Parsing and execution logic:

    • Refactored forc-client to include reusable functions for parsing ABIs and labels.
    • Updated the call_function logic to handle additional ABIs and integrate with the new dry-run execution method. [1] [2]

Checklist

  • I have linked to any relevant issues.
  • [ x] I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • I have requested a review from the relevant team or maintainers.

@zees-dev zees-dev requested review from a team as code owners June 24, 2025 00:42
@zees-dev zees-dev self-assigned this Jun 24, 2025
@zees-dev zees-dev added enhancement New feature or request forc dev-experience Anything to do with the developer experience forc-call Everything related to the `forc-call` plugin in `forc-client` package team:tooling Tooling Team labels Jun 24, 2025
Copy link
Member

@JoshuaBatty JoshuaBatty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! LGTM

@JoshuaBatty JoshuaBatty requested a review from a team June 26, 2025 01:35
Copy link
Member

@kayagokalp kayagokalp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge one!

@zees-dev zees-dev merged commit 0ac606c into master Jun 30, 2025
43 checks passed
@zees-dev zees-dev deleted the forc-call/vm-execution-tracing branch June 30, 2025 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dev-experience Anything to do with the developer experience enhancement New feature or request forc forc-call Everything related to the `forc-call` plugin in `forc-client` package team:tooling Tooling Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

forc-call tracing detailed insights
3 participants