{"content":{"title":"Solana中的程序派生地址（PDAs）：是什么，为什么，以及如何？","body":"## **程序派生地址 (PDA) 在 Solana 中的应用：什么、为什么和如何？**\r\n\r\n在学习 Solana 时，你会经常听到关于 **程序派生地址 (PDAs)** 的讨论。它们就像这样 —— 强大、多功能，而且最重要的是，稍微被误解。如果你是一个开发者，试图理解它们，不用担心。我们将在本文中一起揭开 PDAs 的面纱。\r\n\r\n在本文中，我将从基础开始解释 PDAs，假设你刚刚开始接触 Solana。因此，不需要任何先前的知识 —— 让我们开始吧。\r\n\r\n### **什么是 PDA？**\r\n\r\n让我们简单开始。**程序派生地址 (PDA)** 是 Solana 中一种特殊的地址。我们都知道 Solana 使用账户存储所有数据，而 Solana 程序天生是无状态的。与普通账户（如你的钱包）不同，PDAs 没有私钥。相反，它们是 **在运行时由程序生成和管理的**。\r\n\r\n可以把 PDAs 想象成 **程序控制的储物柜**：\r\n\r\n• 每个储物柜 (PDA) 属于特定的程序。\r\n\r\n• 只有程序可以访问、控制它，并使用它来存储数据。\r\n\r\n• 没有人类可以直接为 PDA 签名交易，因为没有私钥可丢失或被盗。\r\n\r\nPDAs 是通过以下方式生成的：\r\n\r\n1. **种子**：输入数据（如用户 ID 或自定义字符串）。\r\n\r\n2. **程序 ID**：控制 PDA 的程序。\r\n\r\n3. **哈希函数**：确保 PDA 是唯一和安全的。\r\n\r\n> **重要提示** — PDA 是 **确定性的**：相同的输入将始终生成相同的 PDA。\r\n\r\n### **PDA 与普通账户有什么不同？**\r\n\r\n你可能会想，“如果 PDA 只是一个地址，那它和我的钱包或其他账户有什么不同呢？”\r\n\r\n下面是一个对比，让它更清晰：\r\n\r\n![](https://img.learnblockchain.cn/2025/03/09/13WDFZvucEYUHXg4IttLr8A.png)\r\n\r\n> 普通账户是你用于钱包或与应用程序交互的账户。而 PDA 则是 **程序拥有的账户** —— 只有程序可以与之交互。\r\n\r\n### **PDA 何时以及如何使用？**\r\n\r\n以下是 PDA 常见的使用时机和方式：\r\n\r\n**1. 数据存储**\r\n\r\n程序通常使用 PDA 来存储数据。由于 PDA 是以可预测的方式生成的，因此程序不需要跟踪它们的地址。\r\n\r\n> 它可以在需要时计算它们。\r\n\r\n**示例**：一个游戏程序可以为每个玩家创建一个 PDA，以存储他们的分数、库存和成就。\r\n\r\n**2. 代币账户**\r\n\r\n许多程序使用 PDA 来管理代币账户。例如，质押程序创建 PDA 来表示你的质押，这直接与你的钱包相关，并且只有质押程序会对此拥有控制权。\r\n\r\n> **为什么选择 PDA？** 因为它们安全，并且完全由程序控制 —— 没有用户可以篡改它们。\r\n\r\n**3. 资金托管和多签名**\r\n\r\nPDA 非常适合临时持有资金（例如，在托管系统中）或管理多签名钱包。它们充当公正的账户，仅在满足程序规则时执行交易。\r\n\r\n### **如何创建 PDA？**\r\n\r\nPDA 是使用 find_program_address 函数创建的。其工作原理如下：\r\n\r\n1. 提供 **种子**（如“user123”或 user_pubkey）。\r\n\r\n2. 将其与 **程序 ID** 组合。\r\n\r\n3. 该函数输出 PDA 和一个 **增量种子**（以避免冲突）。\r\n\r\n以下是 Rust 语言中的示例：\r\n\r\n```\r\nlet (pda, bump_seed) = Pubkey::find_program_address(\r\n    &[b\"user-seed\", user_pubkey.as_ref()],\r\n    program_id\r\n);\r\n```\r\n\r\n这将生成一个只有程序可以控制的 PDA。同样的输入对于 user-seed 和公钥将始终导致相同的 PDA —— 没有意外！\r\n\r\n### 静态程序拥有账户的问题：\r\n\r\n1. **本质上是静态的：**\r\n\r\n— 程序拥有的账户通常在程序初始化时手动创建。\r\n\r\n— 每个账户需要明确资助（以免租金）并存储。\r\n\r\n2. **每个用户或用例的唯一账户：**\r\n\r\n— 如果你的程序需要为许多用户提供单独的账户（例如，特定于用户的托管或质押账户），使用普通程序拥有账户将会要求：\r\n\r\n— 为每个用户预生成许多账户。\r\n\r\n— 手动跟踪每个账户地址。\r\n\r\n— 在前期产生额外的费用（租金豁免）对每个账户。\r\n\r\n3. **灵活性有限：**\r\n\r\n使用普通程序拥有账户，程序无法根据用户输入或事件动态生成新地址。\r\n\r\n这些限制使普通程序拥有账户不适合动态、可扩展的应用，如质押池、流动性协议或特定于用户的数据管理。\r\n\r\n### **PDA 的安全隐患**\r\n\r\nPDA 是酷炫而强大的，但它们并非没有奇怪之处。如果使用不当，可能会导致严重的安全问题。让我们讨论一些需要注意的陷阱。\r\n\r\n**1. 不应将 PDA 用于授权**\r\n\r\n这是黄金法则。PDA 没有私钥，这意味着它们无法签署交易。如果你使用 PDA 来授权敏感操作（如转账），你就邀请了麻烦。攻击者可以轻松计算 PDA 并绕过你的检查。\r\n\r\n> **注意**：始终使用密码学签名进行用户授权。\r\n\r\n**2. 唯一的种子至关重要**\r\n\r\n在生成 PDA 时，确保你的种子是唯一的。如果两个 PDA 产生相同的种子，你将覆盖数据。这就像给两个人相同的储物柜钥匙 —— 混乱将随之而来。\r\n\r\n**3. 不要在 PDA 中存储敏感数据**\r\n\r\nPDA 是公共的。任何人都可以计算地址并查看里面的内容。如果你需要存储敏感数据，请先加密它。\r\n\r\n### **结论**\r\n\r\n程序派生地址 (PDA) 是 Solana 的一个独特特性，为智能合约带来了确定性控制。它们灵活、强大且安全 —— 只要你负责任地使用它们。通过了解它们的工作原理和局限性，你可以在你的 Solana 程序中解锁全新的功能级别。\r\n\r\n记住：PDA 没有私钥。因此，如果你在等待一个来签署某个东西，你将永远等下去。祝你编码愉快！\r\n\r\n>- 原文链接： [tusharbhatia43.medium.co...](https://tusharbhatia43.medium.com/program-derived-addresses-pdas-in-solana-what-why-and-how-9bdc69c8d969)\r\n>- 登链社区 AI 助手，为大家转译优秀英文文章，如有翻译不通的地方，还请包涵～"},"author":{"user":"https://learnblockchain.cn/people/26960","address":null},"history":null,"timestamp":1741486656,"version":1}