什麼是 Solana 的 PDA?
在 Solana 開發中,PDA 代表程序派生地址。
PDA 是由 Solana 程序使用確定性規則生成的一種特殊帳戶地址。與普通錢包地址不同,PDA 沒有私鑰,無法直接由用戶控制。
PDA 是 Solana 中最重要的機制之一,因為它使程序能夠安全地管理鏈上狀態和資產。
為什麼 Solana 需要 PDA?
在 Solana 中,程序是無狀態且為只讀。
這意味著:
- 程序執行邏輯
- 帳戶存儲數據
程序不能像傳統系統那樣直接在內部存儲用戶數據。
backend service。
應用程式如:
- 去中心化金融協議
- NFT 市場
- 質押系統
- 區塊鏈遊戲
都需要帳戶來存儲:
- 用戶餘額
- 持倉
- 元數據
- 資產庫存
常規錢包帳戶由私鑰控制,這為協議帶來了安全性和擁有權的問題。
因此,Solana 引入了 PDA 帳戶:
- 無私鑰
- 僅由程式控制
- 確定性生成
PDA 的運作方式
PDA 由以下內容派生而來:
- 種子
- 程式 ID
- 提升種子
範例:
const [pda, bump] = PublicKey.findProgramAddressSync(
[
Buffer.from("user"),
wallet.publicKey.toBuffer(),
],
programId
);
這裡:
-
"user"是種子 -
wallet.publicKey是用戶地址 -
programId指定了程序
結果是一個確定性的 PDA 地址。
只要:
- 種子保持不變
- 程序 ID 保持不變
PDA 將始終保持一致。
Bump Seed 是什麼?
Solana 地址是橢圓曲線公開金鑰。
然而,PDA 不能擁有有效的私鑰。
因此,Solana 不斷嘗試
bump 值:
255 → 254 → 253 ...
直到找到一個地址:
- 無法生成私鑰
- 只能被程式控制
這個值稱為提升種子。
為什麼 PDA 沒有私鑰
普通錢包地址的生成方式如下:
私鑰 → 公鑰 → 地址
但 PDA 的生成方式不同:
種子 + 程式 ID → 雜湊 → PDA
因此:
- PDA 沒有私鑰
- 用戶無法控制它們
- 駭客無法恢復秘密鑰匙
只有相關的程式可以管理它們。
程式如何控制 PDA
雖然 PDA 無法直接簽署交易,但 Solana 執行環境允許程式通過以下方式來證明擁有權:
- 種子(Seeds)
- 增量(Bump)
- 程式 ID(Program ID)
這使得程式能夠代表 PDA 進行「簽名」。
因此,PDA 可以:
- 轉移代幣
- 修改鏈上狀態
- 執行 CPI 呼叫
- 鑄造代幣
常見的 PDA 用例
去中心化金融金庫
許多 DeFi 協議使用 PDA 帳戶作為金庫,用於:
- 流動性池
- 質押資產
- 財庫管理
NFT 元數據
NFT 協議通常使用以下方式派生元數據帳戶:
metadata + mint address
這將創建可預測的元數據 PDA。
像 Metaplex 這樣的專案在很大程度上依賴於這種設計。
用戶狀態管理
協議通常為用戶創建專用的 PDA:
User PDA Position PDA Stake PDA
這些帳戶存儲:
- 用戶位置
- 質押數據
- 遊戲進度
- 獎勵點數
PDA 與普通錢包地址
類型錢包地址PDA是否有私鑰是否是否可簽署是否由誰控制用戶程式可預測否是主要用途支付狀態管理
Anchor 中的 PDA
在 Anchor 框架中,PDA 被廣泛使用。
例子:
#[account(
seeds = [b"user", user.key().as_ref()],
bump
)]
pub user_account: Account<'info, UserAccount>,
Anchor 自動化:
- 導出 PDA
- 驗證 bump
- 驗證帳戶
這已成為 Solana 的標準開發模式。