Checking blockhash freshness on-chain now that RecentBlockhashes sysvar is deprecated: hand-parse the SlotHashes sysvar account, or use durable nonces
Problem: you verify a secp256k1/secp256r1 signature inside a Solana program and want replay/freshness protection by including a blockhash in the signed message and checking on-chain that it is recent. The RecentBlockhashes sysvar that used to serve this is deprecated.
Two workable designs.
1. SlotHashes sysvar (SysvarS1otHashes111111111111111111111111111). It stores the most recent slot→hash pairs (512 entries in the current runtime). You cannot call Sysvar::get() on it or from_account_info — it is far too large to deserialize within the compute budget — so pass the account and walk the bytes yourself:
require_keys_eq!(*slot_hashes.key, sysvar::slot_hashes::id());
let data = slot_hashes.try_borrow_data()?;
let len = u64::from_le_bytes(data[0..8].try_into().unwrap());
let mut pos = 8; // entries are newest-first
for _ in 0..len {
let slot = u64::from_le_bytes(data[pos..pos+8].try_into().unwrap());
let hash = &data[pos+8..pos+40]; // 32-byte hash
pos += 40;
}Stop as soon as you find a match (or exceed your freshness window) rather than scanning all entries — each iteration costs compute. Off chain, read the same data with fetchSysvarSlotHashes(rpc) from @solana/sysvars.
2. Durable nonces. A nonce account gives strictly stronger guarantees: the program/runtime advances the nonce so a given signed payload can be used exactly once, with no time window at all. The cost is explicit lifecycle management of the nonce account.
Trade-off to be aware of: SlotHashes only bounds *recency* (the practical window is comparable to the ~150-slot blockhash validity), it does not prevent the same signature being replayed twice inside that window — you still need your own nonce/used-signature marker if that matters. Always validate the sysvar account's key; accepting an arbitrary account here lets a caller forge "recent" hashes.
Source: adapted from a Stack Exchange answer by Aseneca (question by jychab), https://solana.stackexchange.com/questions/21159/how-to-fetch-recent-blockhash-on-chain-since-recent-blockhash-sysvar-is-deprecat — CC BY-SA 4.0