From 205adf701e94c3ada873fd7f14dc77437746776b Mon Sep 17 00:00:00 2001 From: Dhanraj30 Date: Mon, 17 Feb 2025 15:18:36 +0530 Subject: [PATCH 1/2] Add: a stellar contract info wasm-hash command --- .../src/commands/contract/info/wasm_hash.rs | 73 +++++++++++++++++++ cmd/soroban-cli/src/commands/contract/mod.rs | 8 ++ 2 files changed, 81 insertions(+) create mode 100644 cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs diff --git a/cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs b/cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs new file mode 100644 index 0000000000..488658c383 --- /dev/null +++ b/cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs @@ -0,0 +1,73 @@ +use clap::{arg, command, Command, ArgMatches}; +use soroban_rpc::client::Client; +use soroban_xdr::{ScAddress, ScVal, DecodeError}; +use stellar_xdr::XdrCodec; +use crate::config::Config; +use crate::error::Result; +use clap::Parser; +use stellar_xdr::curr as xdr; + +use crate::commands::{config::network, global}; +use crate::config::locator; +use crate::rpc; + +#[derive(Parser, Debug, Clone)] +#[group(skip)] +pub struct Cmd { + #[command(flatten)] + pub config_locator: locator::Args, + + #[command(flatten)] + pub network: network::Args, + + /// Contract ID to get the wasm hash for + #[arg(long = "contract-id")] + pub contract_id: stellar_strkey::Contract, +} + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + Config(#[from] locator::Error), + + #[error(transparent)] + Network(#[from] network::Error), + + #[error(transparent)] + Rpc(#[from] rpc::Error), +} + +impl Cmd { + pub async fn run(&self, _global_args: &global::Args) -> Result<(), Error> { + let network = self.network.get(&self.config_locator)?; + let client = network.get_client()?; + + // Get the contract instance ledger entry + let key = xdr::LedgerKey::ContractData(xdr::LedgerKeyContractData { + contract: self.contract_id.clone().into(), + key: xdr::ScVal::LedgerKeyContractInstance, + durability: xdr::ContractDataDurability::Persistent, + }); + + let entry = client.get_ledger_entry(&key).await?; + + // Extract the wasm hash from the contract instance + if let xdr::LedgerEntryData::ContractData(data) = entry.data { + if let xdr::ScVal::ContractInstance(instance) = data.val { + if let xdr::ContractExecutable::Wasm(hash) = instance.executable { + println!("{}", hex::encode(hash.0)); + return Ok(()); + } + } + } + + Err(rpc::Error::InvalidResponse("Contract instance not found".into()).into()) + } +} + +pub fn subcommand() -> Command { + command!("wasm-hash") + .about("Retrieve the wasm hash of a contract") + .arg(arg!(--network "The network to connect to")) + .arg(arg!(--contract-id "The contract ID")) +} \ No newline at end of file diff --git a/cmd/soroban-cli/src/commands/contract/mod.rs b/cmd/soroban-cli/src/commands/contract/mod.rs index dd642755ad..54069bb0e8 100644 --- a/cmd/soroban-cli/src/commands/contract/mod.rs +++ b/cmd/soroban-cli/src/commands/contract/mod.rs @@ -15,6 +15,7 @@ pub mod optimize; pub mod read; pub mod restore; pub mod upload; +pub mod wasm_hash; use crate::{commands::global, print::Print}; @@ -91,6 +92,9 @@ pub enum Cmd { /// /// If no keys are specificed the contract itself is restored. Restore(restore::Cmd), + + /// Get the wasm hash of a deployed contract + WasmHash(wasm_hash::Cmd), } #[derive(thiserror::Error, Debug)] @@ -142,6 +146,9 @@ pub enum Error { #[error(transparent)] Restore(#[from] restore::Error), + + #[error(transparent)] + WasmHash(#[from] wasm_hash::Error), } impl Cmd { @@ -169,6 +176,7 @@ impl Cmd { Cmd::Fetch(fetch) => fetch.run().await?, Cmd::Read(read) => read.run().await?, Cmd::Restore(restore) => restore.run().await?, + Cmd::WasmHash(cmd) => cmd.run(global_args).await?, } Ok(()) } From d359b6a42386ffd87a6176c8b769d9eaca00d430 Mon Sep 17 00:00:00 2001 From: Dhanraj30 Date: Tue, 18 Feb 2025 16:03:29 +0530 Subject: [PATCH 2/2] fix:requested changes --- cmd/soroban-cli/src/commands/contract/info.rs | 7 +++++++ cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs | 8 +------- cmd/soroban-cli/src/commands/contract/mod.rs | 7 +------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/cmd/soroban-cli/src/commands/contract/info.rs b/cmd/soroban-cli/src/commands/contract/info.rs index 6192c1c61e..08f121caeb 100644 --- a/cmd/soroban-cli/src/commands/contract/info.rs +++ b/cmd/soroban-cli/src/commands/contract/info.rs @@ -6,6 +6,7 @@ pub mod env_meta; pub mod interface; pub mod meta; pub mod shared; +pub mod wasm_hash; #[derive(Debug, clap::Subcommand)] pub enum Cmd { @@ -49,6 +50,9 @@ pub enum Cmd { /// /// Outputs no data when no data is present in the contract. EnvMeta(env_meta::Cmd), + + /// Get the wasm hash of a deployed contract + WasmHash(wasm_hash::Cmd), } #[derive(thiserror::Error, Debug)] @@ -59,6 +63,8 @@ pub enum Error { Meta(#[from] meta::Error), #[error(transparent)] EnvMeta(#[from] env_meta::Error), + #[error(transparent)] + WasmHash(#[from] wasm_hash::Error), } impl Cmd { @@ -67,6 +73,7 @@ impl Cmd { Cmd::Interface(interface) => interface.run(global_args).await?, Cmd::Meta(meta) => meta.run(global_args).await?, Cmd::EnvMeta(env_meta) => env_meta.run(global_args).await?, + Cmd::WasmHash(cmd) => cmd.run(global_args).await?, }; println!("{result}"); Ok(()) diff --git a/cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs b/cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs index 488658c383..e943ecbc48 100644 --- a/cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs +++ b/cmd/soroban-cli/src/commands/contract/info/wasm_hash.rs @@ -21,7 +21,7 @@ pub struct Cmd { pub network: network::Args, /// Contract ID to get the wasm hash for - #[arg(long = "contract-id")] + #[arg(long)] pub contract_id: stellar_strkey::Contract, } @@ -65,9 +65,3 @@ impl Cmd { } } -pub fn subcommand() -> Command { - command!("wasm-hash") - .about("Retrieve the wasm hash of a contract") - .arg(arg!(--network "The network to connect to")) - .arg(arg!(--contract-id "The contract ID")) -} \ No newline at end of file diff --git a/cmd/soroban-cli/src/commands/contract/mod.rs b/cmd/soroban-cli/src/commands/contract/mod.rs index 54069bb0e8..3e454b3ce8 100644 --- a/cmd/soroban-cli/src/commands/contract/mod.rs +++ b/cmd/soroban-cli/src/commands/contract/mod.rs @@ -15,7 +15,7 @@ pub mod optimize; pub mod read; pub mod restore; pub mod upload; -pub mod wasm_hash; + use crate::{commands::global, print::Print}; @@ -93,8 +93,6 @@ pub enum Cmd { /// If no keys are specificed the contract itself is restored. Restore(restore::Cmd), - /// Get the wasm hash of a deployed contract - WasmHash(wasm_hash::Cmd), } #[derive(thiserror::Error, Debug)] @@ -147,8 +145,6 @@ pub enum Error { #[error(transparent)] Restore(#[from] restore::Error), - #[error(transparent)] - WasmHash(#[from] wasm_hash::Error), } impl Cmd { @@ -176,7 +172,6 @@ impl Cmd { Cmd::Fetch(fetch) => fetch.run().await?, Cmd::Read(read) => read.run().await?, Cmd::Restore(restore) => restore.run().await?, - Cmd::WasmHash(cmd) => cmd.run(global_args).await?, } Ok(()) }