9

I'm trying to build a crowdfunding dapp and I want to store/map the Pubkey to the amount donated. I also want to get the Top 10 donors. What would have been suitable for this kind of data is hashmap but it's not allowed in solana. I'm aware that I have to use PDA's instead. My question now is how do i fetch all the PDA account created and get the top 10 donors in my smart contracts. Thanks in anticipation.

2 Answers 2

6

While it is possible for now to use fetchProgramAccounts on the RPC side to get all the accounts owned by your program, and then to use that to figure out the top 10 donors, a better way would be to create a PDA managed by your program that stores the top 10 donors and their donation amounts in a list. Then, when someone new donates or someone updates their donation amount, you could simply check the top 10 and update it accordingly.

1
  • 4
    one caveat here being that all transactions referencing the "leader board" PDA will be serialized since they want to write lock the same state. it is probably the most elegant solution though and given the use case, probably not a huge deal
    – trent.sol
    Commented Jul 22, 2022 at 5:16
2

To answer the Pubkey => Donation mapping bit of your question(s) (this should have been two posts!), you'll want to craft your PDA seed scheme such that you get unique entries under you program's address space. It's not clear from what you've described how the map should behave if a user donate's multiple times, but there are only two options, so I'll address both:

  1. Donors may donate multiple times, each donation updating the last. Seeds should look something like [b"donation", &campaign_identifier.as_bytes(), &donor_pubkey.as_bytes()]. This will give each user one account per campaign, "collision" isn't a problem, since we'll just update the entry if it already exists.

  2. Donors may donate as many times as they like, each creating a new entry. Seeds should be something like [b"donation", &campaign_identifier.as_bytes(), &donor_pubkey.as_bytes(), &clock_sysvar.slot.as_bytes(), &donation_amount.as_bytes()]. This will only collided if the same user attempts to donate the same amount to the same campaign twice during the same slot, which is not likely desirable behavior, so fine to emit an error.

This may needs some adaptation to make it work with anchor. Sorry I'm just a dumb core dev...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.