5

我正在尝试将以太坊 DeFi 合约移植到 Solana 的 Rust 程序中......我已经了解了如何在程序的帐户数据中保存结构或数组,但仍然不知道如何保存 HashMap<address in string, amount in u64>进入程序的帐户数据...然后如何读取此 HashMap 的值,例如检查每个地址的质押金额。请帮忙。谢谢!

我的 Solana Rust 程序:

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);
4

2 回答 2

4

Solana 不会像那样公开 HashMap。在 Solidity 中,通常有一个顶级 HashMap 来跟踪用户值的地址。

在 Solana 上,替换它的常见模式是使用 PDA(程序派生地址)。您可以散列用户 SOL 钱包以确保唯一的 PDA,然后使用链下曲柄对其进行迭代。

于 2021-07-21T23:23:50.170 回答
3

Solana 开发人员支持在 Discord 上回答:HashMap 目前无法在链上工作,因此您必须使用 BTreeMap。

至于实际保存它,您可以遍历键值对并序列化其中的每一个。

但总的来说,我们建议使用多个帐户,并为每个帐户使用程序派生地址:https ://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses

于 2021-07-21T20:59:12.220 回答