3

TL;DR, how can I get the address of the person calling an instruction inside my anchor program.

In my anchor program, I want to know the person who is calling my program.

Say I have an instruction that doesn't require a Signer but I have a list of blocked addresses I don't want to be able to call this instruction, how can I do this in anchor.

I think in Ethereum msg.sender. How can I do it in an anchor program?

#[derive(Accounts)]
pub struct Expire<'info> {
    #[account(mut)]
    pub dummy: AccountInfo<'info>,
    #[account(
        mut,
    )]
    pub token_account: Account<'info, TokenAccount>,
    #[account(mut)]
    pub mint: Box<Account<'info, Mint>>, 
    
    #[account(mut)]
    pub dummyDataAccount: Box<Account<'info, DummyDataAccount>>,

    pub system_program: Program<'info, System>,
    pub metadata_program: Program<'info, Metadata>,
}

In the above program, dummy can be a user's address or a PDA.

The payer is the dummyDataAccount

3 Answers 3

1

I think you can pass the list of blocked addresses, lets say _access_control, then check whether the payer address is in the list of addresses. Something along the lines of

if !_access_control.contains(&ctx.accounts.dummy.key){
        return Err(ProgramError::IllegalOwner.into());
    }

for dummy, or the dummy data account.

You can store the list in the contract, or u can pass it as an argument for the fn.

2
  • 1
    how do I know who is calling the instruction? Is the first account int he Accounts struct assumed to be the caller?
    – Jimii
    Nov 13, 2023 at 11:27
  • 2
    A transaction in solana has multiple signers, its difficult to find out who exactly invoked the transaction unless stated explicitly, and hence, anchor doesn't have an exact equivalent of msg.sender. The first account is not assumed as caller, but since it represents the user address or the pda address, its is generally taken as the caller, unless stated explicitly by using the #[account(mut, signer)]. You can also use the dummyDataAccount as its the payer, but it comes down to which account u would like to use as the address that needs to be used for further logic. Hope this helps :)!
    – toastx
    Nov 13, 2023 at 12:14
1

The answer is unfortunately simple: you can't! The fee payer for the transaction is not exposed to a program.

1

Your best bet is probably to add a Signer if you want this functionality. However, even if you have a Signer, a blocked wallet can always sign with another account and send the tx, you can't see which of the signers sent the tx.

Wallets are so cheap and easy to create that blocking users by wallet key is unlikely to be an effective mitigation anyways.

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.