Skip to content

Commit c7869a1

Browse files
authored
feat(cast): add support for raw transaction data with --data flag in send (#12712)
feat(cast): add support for raw transaction data with --data flag in send command, closes (#12660)
1 parent e201991 commit c7869a1

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

crates/cast/src/cmd/send.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ pub struct SendTxArgs {
3232
#[arg(allow_negative_numbers = true)]
3333
args: Vec<String>,
3434

35+
/// Raw hex-encoded data for the transaction. Used instead of \[SIG\] and \[ARGS\].
36+
#[arg(
37+
long,
38+
conflicts_with_all = &["sig", "args"]
39+
)]
40+
data: Option<String>,
41+
3542
#[command(flatten)]
3643
send_tx: SendTxOpts,
3744

@@ -75,10 +82,14 @@ pub enum SendTxSubcommands {
7582

7683
impl SendTxArgs {
7784
pub async fn run(self) -> eyre::Result<()> {
78-
let Self { to, mut sig, mut args, send_tx, tx, command, unlocked, path } = self;
85+
let Self { to, mut sig, mut args, data, send_tx, tx, command, unlocked, path } = self;
7986

8087
let blob_data = if let Some(path) = path { Some(std::fs::read(path)?) } else { None };
8188

89+
if let Some(data) = data {
90+
sig = Some(data);
91+
}
92+
8293
let code = if let Some(SendTxSubcommands::Create {
8394
code,
8495
sig: constructor_sig,

crates/cast/tests/cli/main.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4409,3 +4409,71 @@ casttest!(keccak_stdin_bytes_with_newline, |_prj, cmd| {
44094409
44104410
"#]]);
44114411
});
4412+
4413+
// Test cast send with raw --data flag using encoded calldata
4414+
forgetest_async!(cast_send_with_data, |prj, cmd| {
4415+
let (api, handle) = anvil::spawn(NodeConfig::test()).await;
4416+
4417+
foundry_test_utils::util::initialize(prj.root());
4418+
prj.initialize_default_contracts();
4419+
4420+
// Deploy counter contract
4421+
cmd.args([
4422+
"script",
4423+
"--private-key",
4424+
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
4425+
"--rpc-url",
4426+
&handle.http_endpoint(),
4427+
"--broadcast",
4428+
"CounterScript",
4429+
])
4430+
.assert_success();
4431+
4432+
// setNumber(111) encoded: selector 0x3fb5c1cb + uint256(111)
4433+
let calldata = "0x3fb5c1cb000000000000000000000000000000000000000000000000000000000000006f";
4434+
4435+
// Send tx using --data instead of sig+args
4436+
cmd.cast_fuse()
4437+
.args([
4438+
"send",
4439+
"0x5FbDB2315678afecb367f032d93F642f64180aa3",
4440+
"--data",
4441+
calldata,
4442+
"--private-key",
4443+
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
4444+
"--rpc-url",
4445+
&handle.http_endpoint(),
4446+
])
4447+
.assert_success();
4448+
4449+
// Verify via trace that setNumber(111) was called
4450+
let tx_hash = api
4451+
.transaction_by_block_number_and_index(BlockNumberOrTag::Latest, Index::from(0))
4452+
.await
4453+
.unwrap()
4454+
.unwrap()
4455+
.tx_hash();
4456+
4457+
cmd.cast_fuse()
4458+
.args([
4459+
"run",
4460+
format!("{tx_hash}").as_str(),
4461+
"-vvvvv",
4462+
"--rpc-url",
4463+
&handle.http_endpoint(),
4464+
])
4465+
.assert_success()
4466+
.stdout_eq(str![[r#"
4467+
Executing previous transactions from the block.
4468+
Traces:
4469+
[..] 0x5FbDB2315678afecb367f032d93F642f64180aa3::setNumber(111)
4470+
├─ storage changes:
4471+
│ @ 0: 0 → 111
4472+
└─ ← [Stop]
4473+
4474+
4475+
Transaction successfully executed.
4476+
[GAS]
4477+
4478+
"#]]);
4479+
});

0 commit comments

Comments
 (0)