I am trying to get a deeper understanding of PDAs and am thinking of examples. Is ATA a good one?
3 Answers
Yes, you can think of an Associated Token Account (ATA) as a good example of a Program Derived Address (PDA). A PDA is a type of cryptocurrency address that is derived from a smart contract program, rather than being generated randomly like a traditional address. An ATA is a specific type of PDA that is used in the Solana blockchain to represent an account that holds a specific type of token. Because ATAs are derived from the smart contract program that manages the token, they are a good example of a PDA.
Yes it is the fractional nature of Solana that it creates a separate address for every data. If its some user data(PDA) or some token data(ATA).
PDAs are addresses associated and authorized by contracts itself to store states as solana smart contracts are stateless. Solana smart contracts dont store any state in itself rather it points toward a PDA.
For Understanding you can say that ATA is like PDA but they are used for different purposes. ATA is unique to every token for every user. You can consider an ATA as glass and tokens as water. If I want to give you water you must have glass in which I can pour water from my glass of water.
-
This is a good answer but this sentence "For Understanding you can say that ATA is like PDA but they are used for different purposes." is not correct. An ATA is a type of PDA. The program for this PDA is the associated token account program, the seeds are the mint (the specific token) and the user's public key.– mikemaccana ♦Commented Apr 2 at 15:46
Echoing the above answers but adding a bit of context in case it's helpful.
If you look for solana-program-library in github and then browser around the associated-token-account rust program, you can find the following function
fn get_associated_token_address_and_bump_seed_internal(
wallet_address: &Pubkey,
token_mint_address: &Pubkey,
program_id: &Pubkey,
token_program_id: &Pubkey,
) -> (Pubkey, u8) {
Pubkey::find_program_address(
&[
&wallet_address.to_bytes(),
&token_program_id.to_bytes(),
&token_mint_address.to_bytes(),
],
program_id,
)
}
This tells you that the associated token address is:
- owned by the program_id you specify as the third argument
- has the following seeds: wallet, token_program_id, mint address
The program_id and the seeds uniquely define a PDA address.
When you see Pubkey::find_program_address
, you should be thinking "a-ha! this is a PDA". That function could really be named calculate_pda.
Typescript equivalent would be
PublicKey.findProgramAddressSync
or
PublicKey.findProgramAddress