Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
Ch 4: PDA (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
urani-engineering-helper authored Mar 27, 2024
1 parent b8b1f57 commit 2112535
Show file tree
Hide file tree
Showing 16 changed files with 3,284 additions and 82 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<br>

### Our development resources, aiming to onboarding engineers to Solana development. From geeks to geeks.
### Our development resources aim to onboard engineers to Solana development. From geeks to geeks.

<br>

Expand Down
18 changes: 12 additions & 6 deletions chapters/01_intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,18 +148,24 @@ Programs are special types of accounts that are marked as "executable".

* Programs can own accounts and change the data of the accounts they own. Unlike other blockchains, they can also be upgraded by their owner.

* Programs are stateless, as the primary data stored in a program account is the compiled SBF code.
* The instructions's `program_id` specifies which program will process the instructions.

* Programs on Solana don't store data or state between transactions: these are stored in accounts.

* Programs can be:
- **Native Programs**: programs built directly into the core of the Solana blockchain.
- **Chain Programs**: written by users and deployed directly to the blockchain for anyone to interact and execute. The Solana Labs also keep a library of them, the [Solana Program Library](https://spl.solana.com/).

- **Native Programs**: programs built directly into the core of the Solana blockchain. Upgrades are controlled via the releases to the different clusters. Examples include:
* System Program: create new accounts, transfer tokens
* BPG Loader Program: Deploys, upgrades, and executes programs on-chain
* Vote program: Create and manage accounts that track validator voting state and rewards

- **Chain Programs**: written by users and deployed directly to the blockchain for anyone to interact and execute.
* The Solana Labs also keep a library of them, the [Solana Program Library](https://spl.solana.com/), a collection of on-chain programs targeting the Sealevel parallel runtime.

* The instructions's `program_id` specifies which program will process the instructions.

* Programs on Solana don't store data or state between transactions: these are stored in accounts.

<br>

<br>


#### Memory on Solana
Expand Down
120 changes: 45 additions & 75 deletions chapters/04_program_derived_addresses.md
Original file line number Diff line number Diff line change
@@ -1,138 +1,108 @@
# 🛹 In-Depth Solana Programs, SPL, CPI [IN CONSTRUCTION]
# 🛹 Program Derived Addresses

<br>

### Solana Programs

<br>

* Referred to as "smart contracts" on other blockchains, Solana programs are the executable code that interprets the instructions sent inside of each transaction on the blockchain.
* They can be deployed directly into the core of the network as Native Programs, or published by anyone as On Chain Programs.
* Both types of programs run on top of the Sealevel runtime, which is Solana's parallel processing model for high transactions speeds of the blockchain.
* Programs can be seen as a type of account that is marked as executable. They can own other accounts and can only change the data or debit accounts they own.
* Programs are considered stateless since the primary data stored in a program account is the compiled SBF code.
* When a Solana program is deployed onto the network, it's marked as "executable" by the BPF loader program. This allows the Solana runtime to execute t
* Unlike other blockchains, Solana programs can be upgraded after they are deployed to the network. Native programs can only be upgraded as part of cluster updates when new software releases are made. On-chain programs can be upgraded by the account marked as the "Upgrade Authority" (usually the Solana account/address that deployed the program).
### tl; dr


<br>

---

### The Solana Program Library (SPL)

<br>

* A collection of on-chain programs targeting the Sealevel parallel runtime.
* These programs are tested against Solana's implementation of Sealevel, solana-runtime, and deployed to its mainnet.
* PDAs are addresses with special properties. They are not public keys (so they don't have an associated public key).

<br>
* PDAs provide a mechanism to build hashmap-like structures on-chain, allowing programs to sign instructions.

* PDAs simplify the programming model and make programs more secure.

---

### On-chain Programs

<br>

* These programs are deployed directly to the blockchain for anyone to interact with or execute.
* They are not baked directly into the Solana cluster's core code.
* The Solana Labs maintains a small subset of them (SPL), but anyone can create or publish them, and the program's account owner can also update them.

<br>

---
----

### Native Programs
### PDA Creation

<br>

* Programs that are built directly into the core of the Solana blockchain.
* They are also called by other programs/users, but they can only be upgraded as part of the core blockchain and cluster updates.
* These native program upgrades are controlled via the releases to the different clusters.
* Examples include:
* System Program: create new accounts, transfer tokens
* BPG Loader Program: Deploys, upgrades, and executes programs on-chain
* Vote program: Create and manage accounts that track validator voting state and rewards
* PDA are created by hashing a number of seeds the user can choose with the `program_id`.

* Seeds can be anything: pubkey, strings, an array of numbers, etc.

<br>
* There is a 50% chance that this hash can result in a public key, so a bump has to be searched:

<br>

---

### Cross-program Invocation (aka CPI)
```rust
// pseudo code
fn find_pda(seeds, program_id) {
for bump in 0..256 {
let potential_pda = hash(seeds, bump, program_id);
if is_pubkey(potential_pda) {
continue;
}
return (potential_pda, bump);
}
panic!("Could not find pda after 256 tries.");
}
```

<br>

* The Solana runtime allows programs to call each other via "cross-program invocation".
* Calling between programs is achieved by one program invoking instruction from the other. The invoking program is halted until the invoked program finishes processing the instruction.
* The runtime uses the privileges granted to the caller program to determine what privileges can be extended to the callee. Privileges refer to signers and writable accounts.
* Cross-program invocations allow programs to invoke other programs directly, but the depth is constrained to 4.
* Reentrancy is limited to direct self-recursion, capped at a fixed depth.
* The first bump that results in a PDA is called a "canonical bump," and they are the recommended one for usage.

<br>

---

### Program Derived Addresses

<br>

* Allow programmatically generated signatures to be used when calling between programs.
* Using a program-derived address, a program may be given authority over an account and later transfer that authority to another.
### Hashmap-like Structures with PDAs

<br>

---
* PDAs are hashed from a bump, a program_id, and several seeds. These seeds can be used to build hashmap-like structures on-chain.

### Memory on Solana
* With PDA, you can create structs that encode the information about a relationship between the user and some data account, so that PDA serves as the address:

<br>

* Memory inside a Solana cluster can be thought of as a monolithic heap of data. Programs have access to their part of the heap.
* While a program may read any part of the global heap, if it tries to write to a part of the heap that is not its own, the Solana runtime makes the transaction fail.
* All state lives in this heap. Your SOL accounts, smart contracts, and memory are used by smart contracts.
* Each memory region has a program that manages it ("owner"). The term of a memory region is "account". Some programs own thousands of independent accounts.
* Accounts that store programs are owned by the `BPFLoader`. This is a program that can be used to deploy and upgrade other programs. The `BPFLoader` is owned by the `Native Loader`, and that is where the recursion ends.
```rust
pub struct UserStats {
level: u16,
name: String,
bump: u8
}
```

<br>


----

### Rent
### CPI Signing with PDAs

<br>

* Because validators don't have infinite storage and providing storage costs money, accounts need to pay rent for their existence. The rent is subtracted from their lamps regularly.

* In some cases, it's possible to reduce the number of accounts needed by making a PDA storing state also sign a CPI instead of defining a separate PDA for that.

* This means that programs can be given control over assets, which they then manage according to the rules defined in the code.

<br>

---

### The System Program
### Demos

<br>

* The System Program is a smart contract with some additional privileges.
* All normal SOL accounts are owned by the System Program. One of the system program's responsibilities is handling transfers between the accounts it owns.
* The system program has a transfer endpoint to provide transfer functionality.

* Learn how PDA works on Anchor through [demo 3](https://github.com/urani-labs/solana-dev-onboarding-rs/tree/main/demos/03_anchor_pda).

<br>

---

### Program Composition
### References

<br>

* There are two ways for developers to make programs interact with each other.
- Via Multiple Instructions in a Transaction: while a transaction can be used to execute a single call to a program, a single transaction can also include multiple calls to different programs.
- Via Cross-Program involcations (CPI), the explicit tool to compose programs. A CPI is a direct call from one program to another within the same instruction.





* [Anchor Docs on PDA](https://www.anchor-lang.com/docs/pdas)

8 changes: 8 additions & 0 deletions demos/03_anchor_pda/game/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

.anchor
.DS_Store
target
**/*.rs.bk
node_modules
test-ledger
.yarn
8 changes: 8 additions & 0 deletions demos/03_anchor_pda/game/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

.anchor
.DS_Store
target
node_modules
dist
build
test-ledger
18 changes: 18 additions & 0 deletions demos/03_anchor_pda/game/Anchor.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[toolchain]

[features]
seeds = false
skip-lint = false

[programs.localnet]
game = "DiUrXVjpm8stNeqnzHcssBLTW3uQBC426Bc2j4QoazDT"

[registry]
url = "https://api.apr.dev"

[provider]
cluster = "Localnet"
wallet = "/Users/m/.config/solana/id.json"

[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
Loading

0 comments on commit 2112535

Please sign in to comment.