1

I have a sign_up function :

pub fn sign_up(ctx: Context<SignUp> , user_name: String , phone: String , email: String) -> Result<()> {// Code is here }

and one of the arguments is user_name and i need to check the user_name that has been sent to be unique among all accounts that is being created with this function and that requires me to look at other users user_name as check whether the user_name is taken or not ? and other usernames are in the data accounts of other users .

Note : I have also other arguments i need to check out the validation.

What do you guys suggest me to do ?

I don't know if PDA will work for this .

4
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. Commented Aug 1, 2022 at 6:21
  • I have added some code what do expect ? Commented Aug 1, 2022 at 8:13
  • You should add the SignUp context accounts Commented Aug 2, 2022 at 7:33
  • 1
    U can create a PDA with the user_name. Since a PDA can be initialized only once, so if the user_name is not unique, then it will throw an error saying that the PDA is already initialized. Commented Aug 2, 2022 at 7:43

2 Answers 2

2

You can use a PDA for you user account like so:

#[derive(Accounts)]
#[instruction(name: String)]
pub struct SignUp<'info> {
    #[account(mut)]
    pub signer: Signer<'info>,

    #[account(
        init,
        payer = signer,
        space = UserState::LEN,
        seeds = [b"user".as_ref(), name.as_bytes()]
        bump,
        constraint = some_validation_function(name),
    )]
    pub user: Account<'info, UserState>,
    
    /// The rest of your context accounts
}

Using the name provided as a function argument (don't forget to update the program function accordingly) in the account seeds makes sure the acccount has a unique name. If you need more validation, you can use a constraint as shown above.

Later, you can work without passing the argument by using directly the name if you stored it in the user account:

#[derive(Accounts)]
pub struct OtherFunction<'info> {
    #[account(mut)]
    pub signer: Signer<'info>,

    #[account(
        mut,
        seeds = [b"user".as_ref(), user.name.as_bytes()]
        bump,
    )]
    pub user: Account<'info, UserState>,
    
    /// The rest of your context accounts
}
4
  • Thanks for the code and the answer and do you have any project source code related to this ? Commented Aug 4, 2022 at 5:57
  • Is name a property of UserState struct ? and if not how can i access properties of the user in seeds ? Commented Aug 6, 2022 at 8:46
  • 1
    In my example, name is a function parameter. You can also have a name variable in your account struct and access it to create a seeds buffer Commented Aug 6, 2022 at 10:58
  • I would appreciate if you can give me a code example . Commented Aug 6, 2022 at 12:02
4

Yes, PDAs are exactly what you should use. That enforces uniqueness and makes it such that only one possible address can be generated for a particular username. Other attempts to sign-up with the same username would then fail.

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.