I'm trying to understand PDAs and ultimately want to be able to have a game where two different players (each with their own wallet) can modify the game state individually (i.e. one signer). For this I've created a very simple example.
The first method initializes a boolean variable. The two accounts are passed in and set as
initializer
andplayer_two
.There is one other method,
update_boolean
, that allows the boolean variable to be changed if the updater is one of the accounts above.
When attempting to test initialization I get the following error:
failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x1
The program:
#[program]
pub mod boolean_test {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let boolean_account = &mut ctx.accounts.boolean_account;
boolean_account.initializer = *ctx.accounts.initializer.key;
boolean_account.other_player = *ctx.accounts.other_player.key;
boolean_account.boolean_value = false;
Ok(())
}
pub fn update_boolean(ctx: Context<UpdateBoolean>, new_value: bool) -> Result<()> {
let boolean_account = &mut ctx.accounts.boolean_account;
let signer = *ctx.accounts.updater.key;
require!(
signer == boolean_account.initializer || signer == boolean_account.other_player,
ErrorCode::Unauthorized
);
boolean_account.boolean_value = new_value;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init, payer = initializer, space = 8 + 32 + 32 + 1, seeds = [b"boolean", initializer.key.as_ref(), other_player.key.as_ref()], bump)]
pub boolean_account: Account<'info, BooleanAccount>,
#[account(mut)]
pub initializer: Signer<'info>,
/// CHECK: This is not dangerous because we don't read or write from this account
pub other_player: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct UpdateBoolean<'info> {
#[account(mut, seeds = [b"boolean", boolean_account.initializer.as_ref(), boolean_account.other_player.as_ref()], bump)]
pub boolean_account: Account<'info, BooleanAccount>,
pub updater: Signer<'info>,
}
#[account]
pub struct BooleanAccount {
pub initializer: Pubkey,
pub other_player: Pubkey,
pub boolean_value: bool,
}
#[error_code]
pub enum ErrorCode {
#[msg("You are not authorized to perform this action.")]
Unauthorized,
}
I'm suspecting I'm not assigning player_two
the proper permissions/Account type?