PDAs, or program derived addresses, are one of the trickier #Solana concepts πŸ€”. They're also something that every Solana dev should understand.

In this thread, I'll go over what they are, and why they're useful πŸ‘‡
1/ First of all, if you don't know how Solana's account model works, check out this thread. It's only 5 tweets!

2/ Now, onto PDAs, or program derived addresses.

The name is pretty self-explanatoryβ€”a PDA is an address derived from a program.

The address points to a data account, which can hold state.
3/ A quick note about terminologyβ€”in this thread, I'll use "PDA" to mean "program derived address", and "PDA account" to mean "an account whose address is a PDA."

There's a difference between an account and an address. Addresses point to accounts, and accounts store data.
4/ How does a PDA get derived?

There's a function called findProgramAddress that spits out a PDA based on two inputs: a program ID and a list of seeds.

The program ID is the address of some Solana program. The list of seeds is used to differentiate that program's PDAs. Image
5/ There are two main use cases of PDAs:
- Storing a program's state
- Signing cross-program invocations (CPIs)

Let's start with the first one.
6/ Say you want to write a Solana program that lets anyone increment a counter. The only thing you want to store is the current count.

This is pretty straightforward. You just need an "increment" instruction that takes a single account and increments its "count" property. Image
7/ There's just one small problem... how do you know what account to pass to the "increment" instruction?

Another way to think about thisβ€”let's say we come across this program, and want to write a frontend that displays the count. How do we know which account to fetch?
8/ Here's one way to fix itβ€”just add a comment to the code!

Now, everyone knows what account to fetch in order to read the program's state.

Great, problem solved. Image
9/ This technically works, but there's a better solutionβ€”PDAs!

Instead of storing the count in some arbitrary account, we can store it in a PDA account.

Then, in code, we can define the PDA's seeds, making it so that anyone can derive the PDA.
10/ Anchor gives us a simple way to do this.

The code below just says "I'm expecting an account whose address is a PDA derived from the program ID and a seed of 'counter.'"

Then, any client or frontend can use findProgramAddress to derive the PDA. Image
11/ In this simple example, it may not seem necessary to use a PDA.

But what if we want to keep track of how many times each user has incremented the count?

PDAs are a great way to store this kind of mappingβ€”you just need a new PDA account for each user. Image
12/ Alright, we've covered the first use case!

To summarize, when you're writing a Solana program, it can be useful to store the program's state in PDA accounts.

This makes it easy for anyone reading or interacting with the code to derive the relevant account addresses.
13/ Let's move onto the next use case of PDAsβ€”cross-program invocations.

This use case is a little trickier. However, if you can understand this, you'll have gotten over the main hurdles of learning Solana dev!
14/ First, let's clear up some terminology.

A CPI is just when a program calls another program.

Put another wayβ€”typically, a user sends instructions to a program (e.g. hey program, swap tokenA for tokenB). A CPI is when a program sends an instruction to another program.
15/ In order to explain PDAs and CPIs, we're going to talk about the SPL Token Swap program.

Simply put, this program lets you swap some tokenA for some tokenB.

spl.solana.com/token-swap
16/ Btw, if you're not familiar with SPL tokens, you may want to read this thread first.

17/ Here's a general outline of how the swap program works.

First, you send an instruction to the swap program, telling it to swap tokenA for tokenB.
18/ Next, the swap program calls the token program (a CPI) and tells it to transfer tokenA from your tokenA account to the program's tokenA account
19/ Finally, the swap program calls the token program again (a CPI) and tells it to transfer tokenB from the program's tokenB account to your tokenB account.

That's it! You've swapped some amount of tokenA for some amount of tokenB.
20/ Let's examine that last step a little more closely...

In order to transfer tokens from one account to another, you must be the owner of the sending account.

This prevents me from transferring tokens from your token account to mine (it prevents me from stealing your tokens).
21/ That raises the questionβ€”who owns the program's tokenB account?

The answer: a PDA!

Specifically, a PDA derived from the swap program's address.
22/ Why is the owner a PDA?

In short, it gives the swap program, and ONLY the swap program, the authority to transfer tokens from the tokenB account.
23/ How does this work?

When the swap program tells the token program to transfer tokens from the tokenB account, the owner of the tokenB account must sign the instruction.

Otherwise, the instruction will fail.
24/ Usually, in order to sign for an account, you must use the account's private key.

However, by definition, a PDA doesn't have an associated private key.

Only the program that created the PDA can sign for it by including the PDA's seeds when invoking an instruction.
25/ Here's what this looks like in code (this is from the swap program).

This looks complicated, but the main thing to note is that the PDA's seeds (authority_signature_seeds in code) are passed to invoke_signed.

In effect, this signs the instruction for the PDA. Image
26/ Why can't another program also do this?

Well, because the code makes sure the following invariant is true. If another program tries, the PDA will be different (because the program ID is different) and the invariant will fail. Image
27/ Let's put it all together.

The owner of the program's tokenB account is a PDA derived from the swap program's address.

When the swap program calls the token program to transfer tokens from its tokenB account, it signs for the PDA. This authorizes the transfer.
28/ Whew, that was quite complicated πŸ˜΅β€πŸ’«. Here's a high level recap:
- A CPI is when one program calls another program
- A program can sign an instruction using a PDA's seeds
- The SPL token swap program is a good example of this
29/ Before we wrap up, let's quickly cover two more topics:
- How are PDA accounts created?
- Does the program that a PDA is derived from always own the PDA?
30/ Creating a normal account (an account associated with a keypair) can be done entirely with client-side code (using @solana/web3.js).

You just create an instruction with SystemProgram.createAccount, add it to a transaction, and send the transaction. Image
31/ Creating a PDA account can ONLY be done by a program. You cannot create a PDA account with just client-side code!

Specifically, if a PDA is derived from a certain program's ID, only that program can create the PDA account.

Here's what the Rust code looks like πŸ‘‡ Image
32/ Note that the client-side code we saw before doesn't create a PDA account, it just finds an address that is a valid PDA.

An account may or may not exist at that address. Image
33/ Why can only Solana programs create PDA accounts?

Because otherwise it would be possible for bad actors to create PDA accounts for any program, and fill them with arbitrary data.
34/ One last thing! It's important to know that the program a PDA is derived from is not necessarily the PDA account's owner.

The program a PDA is derived from can sign for the PDA account.

The program that owns a PDA account can modify its state.

35/ Alright, that's all I got πŸ˜› If you want to learn more about PDAs, check out @bfriel_'s great post.

36/ Also, if you want to play around with calculating PDAs, I built a simple tool for that.

β€’ β€’ β€’

Missing some Tweet in this thread? You can try to force a refresh
γ€€

Keep Current with pencilflip.sol πŸ„ (πŸ“œ,πŸ“œ)

pencilflip.sol πŸ„ (πŸ“œ,πŸ“œ) Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @pencilflip

12 Nov
gm πŸ„ Excited to share @TheMycoverse, the project @petrichorate and I are working on!

We're starting with a mushroom-inspired NFT collection (b/c mushrooms are awesome), but our larger goal is to help onboard more artists and creators into web3.
Right now, getting into web3 as an artist is hard πŸ˜΅β€πŸ’«.

Which blockchain should you choose? Which marketplace should you list on? How do you make an NFT collection? How do you airdrop NFTs to people? How do you market yourself?
We're building a community that cares about helping artists. With that community, we'll create tools and resources that make it easy for any artist or creator to get started with web3.
Read 4 tweets
10 Nov
How do NFT whitelists work on Ethereum? It's pretty simpleβ€”let's take a look at the @smilesssvrs smart contract to see how they did it πŸ‘‡

1/ The contract has a state variable called "_mintStatus."

This determines whether minting is only open to people on the whitelist (Acts 1-4), or is open to the public (Public 1-2).

Each status is associated with a minting limit. E.g. during Act 1, one person can mint 9 NFTs. Image
2/ Only the owner of the smart contract is allowed to change the status. Image
Read 10 tweets
25 Oct
Proof of Stake is used by #Solana and Ethereum 2.0. But what is Proof of Stake, and how does it work? A short thread πŸ‘‡
1/ "Proof of stake is a type of consensus mechanism used by blockchain networks to achieve distributed consensus."

In other words, Proof of Stake enables nodes in a blockchain network to agree on the state of the blockchain.
2/ For example, nodes should agree on:

- Which blocks are included in the blockchain
- Which transactions are included in each block
Read 12 tweets
24 Oct
#Solana accounts explained in 5 tweets πŸ‘‡
1/ There are 2 kinds of accounts in Solana.

Data accounts store data. Program accounts store executable programs.

Each account has an address (usually a public key) and an owner (address of a program account). There are a few more fields every account stores, see πŸ‘‡
2/ There are a few important ownership rules:

- Only a data account's owner can modify its data and subtract lamports.
- Anyone is allowed to give lamports to a data account.
- The owner of an account may assign a new owner if the account's data is zeroed out.
Read 7 tweets
23 Oct
I'm currently learning how to program on @solana, and have found it much more difficult than learning to program on Ethereum.

Luckily, there are lots of great resources out there. Here are the ones I've found most helpful! πŸ‘‡
1/ First, it's helpful to at least slightly understand Rust πŸ¦€ before diving into Solana dev.

Luckily, there's a great free book about it!

You don't need to read the whole thing, just enough to get the syntax down. You can always refer back to it later.

doc.rust-lang.org/book/
2/ Anchor (by @ProjectSerum) is a framework that will make your life much easier.

There are three parts to Anchor:
- A TypeScript library that's similar to web3.js
- Rust crates that make writing Solana programs easier
- A CLI for building/testing, similar to @HardhatHQ
Read 13 tweets
21 Oct
ERC721 is the "gold standard" for NFTs. But ERC1155 is another commonly used standardβ€”in fact, it's the one @opensea uses!

So what is ERC115, and how does it differ from ERC721. You guessed it... it's another thread πŸ‘‡

1/ First, if you haven't read my thread on ERC721, go check that out!

2/ Second, if you want to find out which token standard an NFT on OpenSea uses, just follow this video.
Read 12 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Thank you for your support!

Follow Us on Twitter!

:(