Not working

This commit is contained in:
Alex 2025-04-03 08:16:44 +02:00
parent 3318602fd2
commit 73fe72f829
3 changed files with 965 additions and 91 deletions

789
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,20 @@
[package] [package]
name = "solana_scanner" name = "solana_scanner"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2024"
[dependencies] [dependencies]
solana-client = "1.17" solana-client = "1.17"
solana-sdk = "1.17" solana-sdk = "1.17"
bs58 = "0.5.0" bs58 = "0.5.0"
solana-commitment-config = "2.2.1"
solana-transaction-status-client-types = "2.2.4"
solana-transaction-status = "1.18.26"
spl-token = "8.0.0"
base64 = "0.22.1"
bincode = "1.3.3"
hex = "0.4"
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2" libc = "0.2"

View File

@ -4,33 +4,30 @@ use bs58;
use solana_sdk::instruction::Instruction; use solana_sdk::instruction::Instruction;
use solana_sdk::message::Message; use solana_sdk::message::Message;
use solana_client::rpc_response::RpcConfirmedTransactionStatusWithSignature; use solana_client::rpc_response::RpcConfirmedTransactionStatusWithSignature;
use solana_client::rpc_response::EncodedConfirmedTransactionWithStatusMeta;
use solana_sdk::transaction::Transaction; use solana_sdk::transaction::Transaction;
use solana_transaction_status::UiTransactionEncoding;
use solana_sdk::signature::Signature;
use std::str::FromStr;
use spl_token::state::Mint;
use solana_transaction_status::EncodedTransaction::{Json, Binary};
use solana_transaction_status::UiMessage::{Parsed, Raw};
use base64::prelude::*;
use solana_sdk::message::VersionedMessage;
use solana_sdk::transaction::VersionedTransaction;
use hex;
fn base58_to_pubkey(address: &str) -> Result<Pubkey, Box<dyn std::error::Error>> {
let decoded = bs58::decode(address).into_vec()?;
if decoded.len() != 32 {
return Err("Address must be 32 bytes long".into());
}
let mut bytes = [0u8; 32];
bytes.copy_from_slice(&decoded);
Ok(Pubkey::new_from_array(bytes))
}
fn is_token_creation(instruction: &Instruction) -> bool { use solana_transaction_status_client_types::option_serializer;
// L'instruction de création de token a un discriminant de 0
if instruction.data.len() < 1 {
return false;
}
instruction.data[0] == 0
}
fn main() { fn main() {
let rpc_url = "https://api.mainnet-beta.solana.com"; let rpc_url = "https://api.mainnet-beta.solana.com";
let client = RpcClient::new(rpc_url.to_string()); let client = RpcClient::new(rpc_url.to_string());
// Adresse du programme Token (SPL Token Program) // Adresse du programme Token (SPL Token Program)
let token_program_address = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"; let token_program_address = "TSLvdd1pWpHVjahSpsvCXUbgwsL3JAcvokwaKt1eokM";
let buy_router_address = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
match base58_to_pubkey(token_program_address) { match base58_to_pubkey(token_program_address) {
Ok(token_program) => { Ok(token_program) => {
@ -42,41 +39,117 @@ fn main() {
match transactions { match transactions {
Ok(sigs) => { Ok(sigs) => {
println!("Nombre total de transactions trouvées : {}", sigs.len()); println!("Nombre total de transactions trouvées : {}", sigs.len());
for sig in sigs.iter().take(10) { // Limiter à 10 transactions pour commencer for sig in sigs.iter().take(1000) { // Limiter à 10 transactions pour commencer
// Récupérer les détails de la transaction // Convertir la signature en Signature
match client.get_transaction(&sig.signature, solana_client::rpc_config::RpcTransactionConfig { let signature = Signature::from_str(&sig.signature).unwrap();
encoding: Some(solana_client::rpc_config::RpcTransactionEncoding::Base64),
commitment: Some(solana_client::rpc_config::RpcTransactionLogsConfig {
commitment: Some(solana_client::rpc_config::CommitmentConfig::confirmed()), let config = solana_client::rpc_config::RpcTransactionConfig {
max_supported_transaction_version: Some(0), encoding: Some(UiTransactionEncoding::Base64),
}), commitment: Some(solana_sdk::commitment_config::CommitmentConfig::confirmed()),
max_supported_transaction_version: Some(0), max_supported_transaction_version: Some(0),
}) { };
// Récupérer les détails de la transaction
match client.get_transaction_with_config(&signature, config) {
Ok(tx) => { Ok(tx) => {
println!(tx.transaction.meta); if let Some(meta) = tx.transaction.meta {
if let solana_transaction_status::option_serializer::OptionSerializer::Some(inner_instructions) = meta.inner_instructions {
//Vérifier si c'est une création de token
let is_token_creation = inner_instructions.iter().any(|inner| {
inner.instructions.iter().any(|ix| {
//println!("ix: {:?}", ix);
match ix {
solana_transaction_status::UiInstruction::Compiled(instruction) => {
is_token_creation(instruction)
},
_ => false
}
})
});
//if let Some(meta) = tx.transaction.meta { // if is_token_creation {
//println!(meta); // println!("Création de token trouvée :");
// Vérifier si c'est une création de token // println!(" Signature: {}", sig.signature);
//let is_token_creation = meta.inner_instructions.iter().any(|inner| { // println!(" Slot: {}", sig.slot);
// inner.instructions.iter().any(|ix| { // println!(" Block time: {:?}", sig.block_time);
//if let Ok(instruction) = ix.try_into() { // println!(" Status: {:?}", meta.err);
//is_token_creation(&instruction) // println!("---");
//} else { // }
// false
//}
// })
//});
//if is_token_creation { //println!("tx.transaction.transaction: {:?}", tx.transaction.transaction);
//println!("Création de token trouvée :");
//println!(" Signature: {}", sig.signature); match tx.transaction.transaction {
//println!(" Slot: {}", sig.slot); Binary(data, encoding) => {
//println!(" Block time: {:?}", sig.block_time); let decoded = BASE64_STANDARD.decode(data).unwrap();
//println!(" Status: {:?}", meta.err);
//println!("---"); // Try to deserialize as a VersionedTransaction
//} if let Ok(versioned_tx) = bincode::deserialize::<VersionedTransaction>(&decoded) {
// }
// dbg!(&versioned_tx);
// Try to deserialize the message
if let Ok(message) = bincode::deserialize::<VersionedMessage>(&versioned_tx.message.serialize()) {
let account_keys = versioned_tx.message.static_account_keys();
println!("\nAccount Keys in Transaction:");
println!(" Payer (account_keys[0]): {}", account_keys[0]);
println!(" Mint Account (account_keys[1]): {}", account_keys[1]);
println!(" Rent Account (account_keys[2]): {}", account_keys[2]);
println!(" Mint Authority (account_keys[3]): {}", account_keys[3]);
println!(" Token Program (account_keys[4]): {}", account_keys[4]);
// println!("Instructions: {:?}", message.compiled_instructions);
match get_token_info(&client, account_keys[1].to_string().as_str()) {
Ok(token_info) => {
display_token_info(&token_info);
}
Err(e) => {
println!("Erreur lors de la récupération des informations du token : {:?}", e);
}
}
}
}
// If not a versioned transaction, try as a legacy transaction
if let Ok(legacy_tx) = bincode::deserialize::<Transaction>(&decoded) {
// dbg!(&legacy_tx);
}
println!("--------------------------------");
// match json_transaction.message {
// Parsed(msg) => {
// println!("binary msg: {:?}", msg);
// // println!("Token trouvé : {}", &msg);
// // println!("Supply total : {}", &msg.supply);
// // println!("Decimals : {}", &msg.decimals);
// },
// Raw(msg) => {
// println!("Raw msg: {:?}", msg);
// // println!("Token trouvé : {}", &msg);
// // println!("Supply total : {}", &msg.supply);
// // println!("Decimals : {}", &msg.decimals);
// }
// }
},
_ => {}
}
}
}
} }
Err(err) => eprintln!("Erreur lors de la récupération de la transaction : {:?}", err), Err(err) => eprintln!("Erreur lors de la récupération de la transaction : {:?}", err),
} }
@ -89,3 +162,89 @@ fn main() {
} }
} }
fn base58_to_pubkey(address: &str) -> Result<Pubkey, Box<dyn std::error::Error>> {
let decoded = bs58::decode(address).into_vec()?;
if decoded.len() != 32 {
return Err("Address must be 32 bytes long".into());
}
let mut bytes = [0u8; 32];
bytes.copy_from_slice(&decoded);
Ok(Pubkey::new_from_array(bytes))
}
fn is_token_creation(instruction: &solana_transaction_status::UiCompiledInstruction) -> bool {
// L'instruction de création de token a un discriminant de 0
if instruction.data.len() < 1 {
return false;
}
// instruction.data == "0".to_string()
println!("instruction: {:?}", instruction);
true
//instruction.data[0] == 0
}
#[derive(Debug)]
struct TokenInfo {
mint_address: String,
transaction_signature: String,
slot: u64,
block_time: Option<i64>,
decimals: u8,
mint_authority: Option<String>,
freeze_authority: Option<String>,
supply: u64,
}
fn get_token_info(client: &RpcClient, mint_address: &str) -> Result<TokenInfo, Box<dyn std::error::Error>> {
let mint_pubkey = Pubkey::from_str(mint_address)?;
// Get the account data
let account = client.get_account(&mint_pubkey)?;
// Afficher les données brutes en hexadécimal pour le débogage
println!("Données brutes en hex: {}", hex::encode(&account.data));
// Décoder les données en utilisant Mint::unpack
let mint = Mint::unpack(&account.data)?;
// Afficher les informations décodées
println!("\nInformations du token décodées:");
println!("Decimals: {}", mint.decimals);
println!("Supply: {}", mint.supply);
println!("Mint Authority: {:?}", mint.mint_authority);
println!("Freeze Authority: {:?}", mint.freeze_authority);
Ok(TokenInfo {
mint_address: mint_address.to_string(),
transaction_signature: "".to_string(),
slot: 0,
block_time: None,
decimals: mint.decimals,
mint_authority: mint.mint_authority.map(|pk| pk.to_string()),
freeze_authority: mint.freeze_authority.map(|pk| pk.to_string()),
supply: mint.supply,
})
}
fn display_token_info(token: &TokenInfo) {
println!("\nToken Information:");
println!(" Mint Address: {}", token.mint_address);
println!(" Decimals: {}", token.decimals);
println!(" Supply: {}", token.supply);
match &token.mint_authority {
Some(auth) => println!(" Mint Authority: {}", auth),
None => println!(" Mint Authority: None (immutable)"),
}
match &token.freeze_authority {
Some(auth) => println!(" Freeze Authority: {}", auth),
None => println!(" Freeze Authority: None (unfrozen)"),
}
println!(" Transaction: {}", token.transaction_signature);
println!(" Slot: {}", token.slot);
if let Some(time) = token.block_time {
println!(" Block Time: {}", time);
}
println!("---");
}