5

I am trying to port Ethereum DeFi contracts into Solana's Rust programs... I have learned about saving a struct or an array in programs' account data, but still do not know how to save a HashMap<address in string, amount in u64> into a program's account data... Then how to read this HashMap's values like checking each address' staked amount. Please help. Thank you!

My Solana Rust program:

pub fn get_init_hashmap() -> HashMap<&'static str, u64> {
  let mut staked_amount: HashMap<&str, u64> = HashMap::new();
  staked_amount.insert("9Ao3CgcFg3RB2...", 0);
  staked_amount.insert("8Uyuz5PUS47GB...", 0);
  staked_amount.insert("CRURHng6s7DGR...", 0);
  staked_amount
}
pub fn process_instruction(...) -> ProgramResult {
    msg!("about to decode account data");
    let acct_data_decoded = match HashMap::try_from_slice(&account.data.borrow_mut()) {
      Ok(data) => data,//to be of type `HashMap`
      Err(err) => {
        if err.kind() == InvalidData {
          msg!("InvalidData so initializing account data");
          get_init_hashmap()
        } else {
          panic!("Unknown error decoding account data {:?}", err)
        }
      }
    };
    msg!("acct_data_decoded: {:?}", acct_data_decoded);
Russo
  • 2,186
  • 2
  • 26
  • 42
  • What do you mean by saving the hash map in the program's account data? – sb27 Jul 20 '21 at 13:17
  • Your question is very unclear. Please tell us what exactly you want to achieve, e.g. storing data to disk, to memory, ... . If you can provide a [mcve] and maybe read [ask] :) – hellow Jul 20 '21 at 14:00
  • answered by Solana dev support on Discord – Russo Jul 21 '21 at 21:00

2 Answers2

6

Solana doesn't expose a HashMap like that. In Solidity, it is common to have a top-level HashMap that tracks addresses to user values.

On Solana a common pattern to replace it would be to use PDAs (Program derived addresses). You can Hash user SOL wallet to ensure unique PDAs and then iterate over them using an off-chain crank.

bartosz.lipinski
  • 2,627
  • 2
  • 21
  • 34
3

Answered by Solana dev support on Discord: HashMap doesnt work on-chain at the moment, so you'll have to use BTreeMap.

As for actually saving it, you can iterate through the key-value pairs and serializing each of those.

In general though, we suggest using mutiple accounts, and program-derived addresses for each account: https://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses

Russo
  • 2,186
  • 2
  • 26
  • 42
  • does HashMap still not work? – nxmohamad Dec 01 '21 at 07:35
  • see the above answer from bartosz.lipinski. Each Solana account can only hold 10MB of data, so HashMap will not be working when it is full, then it becomes useless... – Russo Dec 03 '21 at 03:39