Program Derived Address (PDA)

Program Derived Addresses (PDAs) are addresses that are derived from a program's address and additional seed data. They are used to represent accounts that are associated with a specific program and a particular context or purpose within that program.

Here's how it works:

  • A PDA is derived by combining the program's address (usually the address of a smart contract) with additional data called seeds.

  • These seeds can be any arbitrary data chosen by the program or user, such as account addresses, strings, or numbers.

  • By using a deterministic algorithm, the combination of the program address and seeds generates a unique PDA.

  • PDAs are often used in Solana programs to organize and manage accounts associated with specific users, tokens, or other data within the program.

PDAs are crucial for most smart contracts, allowing players to store and maintain various types of data, like player data, inventory items and more. So if you are trying to interact with a custom smart contract, you will most likely need to work with them.

Deriving a PDA is a little bit tricky, but let's try to use an advanced example to clear it up. This one derives a PDA of a specific leaderboard from the SOAR program:

static func get_leaderboard_pda(game_account:Pubkey,leaderboard_id:int, pid:Pubkey) -> Pubkey:
	var name_bytes = "leaderboard".to_utf8_buffer()
	var game_bytes = game_account.get_bytes()
	var id_bytes := PackedByteArray()
	id_bytes.resize(8)
	id_bytes.encode_u64(0, leaderboard_id)
	return Pubkey.new_pda_bytes([name_bytes,game_bytes,id_bytes],pid)

Like usual, PDA requires the program ID (pid) to be provided, alongside 3 parameters:

  1. a static string leaderboard which can be stored in byte format using to_utf8_buffer()

  2. The game account, which is the owner of this leaderboard. Since it is a type Pubkey we can just call its native function get_bytes()

  3. Leaderboard ID, since a game may have multiple leaderboards. numbers are the trickiest to get working in byte format. First, you need to create an empty byte array and resize it to size of 8. Then, based on what type of number you need (in this example u64) you encode that number starting from byte 0

With all these elements in place, a Pubkey.new_pda_bytes and be called, which takes byte array as the first parameter, and then program id.

Last updated