2026-06-04 15:06:51 +00:00
|
|
|
use blockchain::common::cli_prompts::{prompt_hidden_nonempty, prompt_wallet_path};
|
2026-05-24 17:56:57 +00:00
|
|
|
use blockchain::common::network_startup::get_connections;
|
|
|
|
|
use blockchain::encode;
|
|
|
|
|
use blockchain::env;
|
2026-06-29 16:05:30 +00:00
|
|
|
use blockchain::json;
|
2026-05-24 17:56:57 +00:00
|
|
|
use blockchain::records::memory::response_channels::generate_uid;
|
|
|
|
|
use blockchain::standalone_tools::connections::handshake;
|
|
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
|
async fn main() {
|
|
|
|
|
// Command 33 asks a peer for one loan contract by its 32-byte hash.
|
|
|
|
|
let hashmap_key = generate_uid();
|
|
|
|
|
let rpc_command = 33;
|
|
|
|
|
|
|
|
|
|
// The hash is passed as text here and encoded into binary request bytes later.
|
|
|
|
|
let args: Vec<String> = env::args().collect();
|
|
|
|
|
if args.len() != 2 {
|
|
|
|
|
println!("Usage: ./contract_lookup_by_hash <contract_hash>");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let contract_hash = match args[1].parse::<String>() {
|
|
|
|
|
Ok(hash) => hash,
|
|
|
|
|
Err(_) => {
|
|
|
|
|
println!("Please enter a contract hash");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-06-04 15:06:51 +00:00
|
|
|
let wallet_path = prompt_wallet_path().await;
|
2026-05-24 17:56:57 +00:00
|
|
|
|
|
|
|
|
let encryption_key = prompt_hidden_nonempty(
|
|
|
|
|
"What is your wallet decryption key? ",
|
|
|
|
|
"Wallet key cannot be empty. Please try again.",
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
|
|
|
|
|
|
// Try each configured peer until one returns a response.
|
|
|
|
|
let connections = get_connections().await;
|
|
|
|
|
let mut connected = false;
|
|
|
|
|
|
|
|
|
|
for conn in connections {
|
|
|
|
|
if connected {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let socket_address = conn.parse().expect("Failed to parse the socket address");
|
|
|
|
|
let result = handshake::connect_and_handshake(
|
|
|
|
|
socket_address,
|
|
|
|
|
contract_hash.clone(),
|
|
|
|
|
rpc_command,
|
2026-06-04 15:06:51 +00:00
|
|
|
handshake::HandshakeWallet::WalletKey {
|
|
|
|
|
encryption_key: encryption_key.clone(),
|
|
|
|
|
wallet_path: wallet_path.clone(),
|
|
|
|
|
},
|
2026-05-24 17:56:57 +00:00
|
|
|
hashmap_key,
|
|
|
|
|
)
|
|
|
|
|
.await;
|
|
|
|
|
|
|
|
|
|
match result {
|
|
|
|
|
Ok(response) => {
|
|
|
|
|
// Contract lookup replies are usually text; fallback to hex if the peer sends raw bytes.
|
|
|
|
|
let response_text = String::from_utf8_lossy(&response);
|
|
|
|
|
let trimmed = response_text.trim();
|
|
|
|
|
if !trimmed.is_empty() {
|
|
|
|
|
println!("{trimmed}");
|
|
|
|
|
connected = true;
|
|
|
|
|
} else if !response.is_empty() {
|
2026-06-29 16:05:30 +00:00
|
|
|
println!(
|
|
|
|
|
"{}",
|
|
|
|
|
serde_json::to_string_pretty(&json!({ "hex": encode(response) })).unwrap()
|
|
|
|
|
);
|
2026-05-24 17:56:57 +00:00
|
|
|
connected = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Err(_) => {
|
|
|
|
|
connected = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !connected {
|
|
|
|
|
eprintln!("failed to connect");
|
|
|
|
|
}
|
|
|
|
|
}
|