Skip to content

feat: add --hex-file <file_path> option to blockstack-cli contract-call #6195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from

Conversation

fdefelici
Copy link
Contributor

@fdefelici fdefelici commented Jun 12, 2025

Description

This change, add --hex-file <file_path> option to blockstack-cli contract-call that allows to allow a serialized Clarity value by file.

This is useful in case the value is great enough to not fit in the command-line.

It can be used like this:

blockstack-cli contract-call \
    ... \
    --hex-file /path/to/value.hex

Applicable issues

Additional info (benefits, drawbacks, caveats)

Checklist

  • Test coverage for new or modified code paths
  • Changelog is updated
  • Required documentation changes (e.g., docs/rpc/openapi.yaml and rpc-endpoints.md for v2 endpoints, event-dispatcher.md for new events)
  • New clarity functions have corresponding PR in clarity-benchmarking repo
  • New integration test(s) added to bitcoin-tests.yml

@fdefelici fdefelici self-assigned this Jun 12, 2025
@fdefelici fdefelici requested review from a team as code owners June 12, 2025 11:59
@fdefelici fdefelici changed the title feat: add -xf <file_path> option to blockstack-cli contract-call feat: add --hex-file <file_path> option to blockstack-cli contract-call Jun 12, 2025
@aldur aldur moved this to Status: In Review in Stacks Core Eng Jun 12, 2025
@aldur aldur added this to the 3.1.0.0.13 milestone Jun 12, 2025
kantai
kantai previously approved these changes Jun 12, 2025
Copy link
Contributor

@BowTiedRadone BowTiedRadone left a comment

Choose a reason for hiding this comment

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

Tested locally using a 1.5MB hex file (which was not possible before this feature because of shell limitations), and seems to work fine. What I used to test:

# Call the contract with the file containing the hex-encoded argument.
./stacks-core/target/release-lite/blockstack-cli \
  contract-call \
  <private-key> \
  10000000 \
  1 \
  <stx-addr> \
  contract-name \
  function-name \
  --hex-file ./hex-args.txt

@aldur aldur requested review from BowTiedRadone and kantai June 17, 2025 15:20
Copy link
Contributor

@BowTiedRadone BowTiedRadone left a comment

Choose a reason for hiding this comment

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

This PR looks good! I only left a minor test-related suggestion.

Comment on lines 1245 to 1294
#[test]
fn test_contract_call_with_serialized_arg_from_file_fails_due_to_content() {
//Scenerio 01: Bad hex string but (good except for the \n)
let mut file = NamedTempFile::new().expect("Cannot create tempfile!");
write!(file, "0000000000000000000000000000000001\n").expect("Cannot Write to temp file");
let file_path = file.path().to_str().unwrap();

let cc_args = [
"contract-call",
"043ff5004e3d695060fa48ac94c96049b8c14ef441c50a184a6a3875d2a000f3",
"1",
"0",
"SPJT598WY1RJN792HRKRHRQYFB7RJ5ZCG6J6GEZ4",
"foo-contract",
"transfer-fookens",
"--hex-file",
&file_path,
];

let result = main_handler(to_string_vec(&cc_args));
assert!(result.is_err(), "Result should be err!");

let expected_msg = "Failed to deserialize: Deserialization error: Bad hex string";
assert_eq!(expected_msg, result.unwrap_err().to_string());

//Scenerio 02: short buffer
let mut file = NamedTempFile::new().expect("Cannot create tempfile!");
write!(file, "0101").expect("Cannot Write to temp file");
let file_path = file.path().to_str().unwrap();

let cc_args = [
"contract-call",
"043ff5004e3d695060fa48ac94c96049b8c14ef441c50a184a6a3875d2a000f3",
"1",
"0",
"SPJT598WY1RJN792HRKRHRQYFB7RJ5ZCG6J6GEZ4",
"foo-contract",
"transfer-fookens",
"--hex-file",
&file_path,
];

let result = main_handler(to_string_vec(&cc_args));
assert!(result.is_err(), "Result should be err!");

let expected_msg =
"Failed to deserialize: Serialization error caused by IO: failed to fill whole buffer";
assert_eq!(expected_msg, result.unwrap_err().to_string());
}

Copy link
Contributor

Choose a reason for hiding this comment

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

The only thing I'd suggest (sorry for nitpicking) is to break this test into two, or at least not use the same failed assertion message in the two assert!(result.is_err(), "Result should be err!");.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem at all! I was trying to follow the codebase style, but I’ve gone ahead and split the test into two.: ecbc255

Copy link
Contributor

@BowTiedRadone BowTiedRadone left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Status: In Review
Development

Successfully merging this pull request may close these issues.

4 participants