How can I grant access to some particular wallet addresses to modify an account through an anchor program?
1 Answer
There are several ways you can achieve this. One of the best ways is to add constraints on the account directly.
Suppose you have an account, MyData like this:
#[account]
#[derive(Default)]
pub struct MyData {
data: u8
}
You can add another field to save the authorized address, let's call it owner:
#[account]
#[derive(Default)]
pub struct MyData {
data: u8,
owner: Pubkey
}
Then in the instruction where you allow the modification of the account, use has_one or address constraint like this:
#[derive(Accounts)]
pub struct EditsAccount<'info> {
#[account(mut,has_one=owner)]
pub my_data: Account<'info,MyData>,
pub owner: Signer<'info>
}
has_one constraint checks the field on the my_data struct with the same name and if the signer of the transaction doesn't match, the transaction will fail. So, the above instruction can only be signed by the address we whitelisted.
For multiple owners:
#[account]
#[derive(Default)]
pub struct MyData {
data: u8,
owners: [Pubkey;5]
}
Rather in the account validation, checks if the correct owner signs the transaction in the program logic:
pub fn edit(ctx: Context<DataEdit>,data: u8) -> Result<()> {
let my_data = &mut ctx.accounts.my_data;
let owner = &ctx.accounts.owner.key();
require!(my_data.owners.contains(owner),Errors::NotAnOwner);
my_data.data = data;
Ok(())
}
#[error_code]
pub enum Errors {
NotAnOwner
}
-
Thanks for this explanation but how can I put access for multiple wallets inside it? Suppose only 5 wallets can modify the data. Commented Sep 5, 2022 at 6:17
-
For multiple owners, I think using require statement would be a better option. Replace the owner field in MyData struct to the array of Pubkey. Fill this field with the preferred owners in the initialize instruction. Then in the edit instruction, check if the signer of the transaction exists in the owners array. I have edit the answer to add the code for multiple owners.– 0xShukCommented Sep 5, 2022 at 8:13