新消息:Helius 收购 Light Protocol
什么是 Solana PDA?解析与示例
博客/基础知识

什么是 Solana PDA?解析与示例(2026)

开发者教育X 上的 Mike MacCanaLinkedIn 上的 Mike MacCana
阅读需 6 分钟

感谢 0xIchigo 审阅本文,感谢 Unboxed Software 提供影评程序,也感谢 Paul Verhoeven 创作了《机械战警》。

Solana 程序(智能合约)将数据存储在称为程序派生地址(PDA)的独立账户中。

PDA 可以独立访问和更新,从而减少争用并支持并行处理。

PDA 的概念并不复杂,但新手开发者可能不容易理解。

本文将帮助你把 PDA 理解为键值存储,并介绍四个实用的 PDA 示例。

让我们开始吧。

将 PDA 用作键值数据存储

键值存储早在区块链出现之前就已在编程领域存在多年。它能让你快速查找数据。在存储中查询给定键对应的值,总会找到相同的数据。

在 Solana 的编程模型中,PDA 系统就是程序的键值存储。

每条数据的键是一种特殊地址,由程序员确定的输入种子生成。

相同的种子始终会生成相同的地址,因此任何人都能以确定性的方式找到一组给定种子对应的数据。

PDA 地址绝不会与真实公钥冲突,因为它们的值是“离曲线”的。也就是说,PDA 地址在数学上不同于 Solana Ed25519 曲线上存在的公钥值。

值是一个结构体(或对象),其中包含你作为程序作者希望存储的字段和值。

用示例最容易解释 PDA,所以我们直接来看示例。

1. 使用 PDA 存储与钱包关联的代币

先从别人的程序开始——而且是你已经用过的程序。你已经知道自己的钱包中有不同的代币,而且每种代币都有各自的余额。欢迎来到第一个 PDA 示例!

你的每项代币余额都存储在一个 PDA 账户中,其种子由关联代币账户程序确定。

下面来具体看看它如何运作:

视频回顾

程序:关联代币账户程序

账户用途:存储钱包中某种唯一代币的余额

种子:钱包地址和代币的铸币地址

数据:该钱包中这种代币的余额

优势:

用户持有的特定代币有一个规范位置可供查询。由于用户余额位于不同账户中,更多交易可以并行运行,让 Solana 保持高速!

2. 使用 PDA 存储程序数据

很好,但如何在 Solana 程序中将 PDA 用作通用数据存储?设计 PDA 的种子和数据时需要考虑什么?

视频回顾

程序:一个利用资产所有权来提高影评真实性的影评程序

账户用途:存储每位资产所有者对电影的评价

种子:钱包地址、电影名称和上映年份

数据:

  1. 一段书面影评(string)
  2. 以 u8 存储的 0–10 分评分

优势:

用户对特定电影的影评有一个规范位置可供查询。用户可以并行更新各自的影评,彼此不会阻塞。巧妙的 PDA 设计确保每位用户对每部电影只能发表一条影评,还能处理恶意人士翻拍《机械战警》之类的边缘情况。

3. 使用 PDA 为程序设置可配置值

开发自己的应用时,你很可能需要设置一些可在程序整个生命周期中配置的值: 

  • 常量值(例如平台费用)
  • 程序将使用的代币铸币地址列表
  • 可随时启用和停用的功能标志
  • 程序处于活动还是暂停状态(例如,允许管理员账户暂停程序,是许多区块链程序中典型的紧急干预功能)

我们不希望仅为了更改这些值就升级程序,所以可以把配置放进 PDA 账户!然后,我们可以创建一些指令处理器来更新这些值,并检查传入的指令是否由指定的“管理员”账户签名。 

在这个示例中,配置将包含一个允许的公钥列表,以限制谁能与程序交互,不过我们也可以添加任何其他需要的配置项。

这是一个很有意思的示例,因为 PDA 还能用于存储这样的全局配置,这一点可能并不直观!

视频回顾

程序:你创建的任何程序

账户用途:存储一些可动态更新的配置

种子:"config"

数据:配置,在本例中包括允许列表和管理员账户

  • allow_list:由获准使用此应用的用户公钥组成的向量
  • authority:可以更改这些设置的账户公钥(Solana 应用通常使用 authority 一词来表示某种权限)。我们会确保该账户为特权操作签名!

优势:

无需将特定配置硬编码到源代码中,我们可以使用程序中的指令函数实时更新配置。

配置更新也不会被无关数据的更改阻塞。首次部署程序时,你还需要运行 intialize_config() 并设置权限账户!

4. 使用 PDA 持有和转移代币

PDA 不只能存储数据,也可以拥有自己的代币账户。程序随后能以 PDA 的身份为交易签名,将代币从这些代币账户转移到其他位置。这样一来,程序就可以存储和转移价值:

视频回顾

程序:兑换程序

账户用途: 

  1. 存储兑换报价的详细信息,具体包括报价创建者提供代币后,希望换回哪些代币以及多少数量。 
  2. 该 PDA 拥有一个代币账户,用于存储已提供的代币。PDA 可以签署交易,并将该账户中的代币转移给接收方。 

种子:"offer"、报价 ID(只要尚未被占用,可以使用任意识别符)以及创建者的地址

数据:

  • maker_wanted_token:希望换回的代币,以该代币铸币地址的公钥表示
  • maker_wanted_amount:希望获得的代币数量(u64)

优势:

这个 PDA 既能让用户存储数据,也能作为代币账户的所有者持有代币,并将其转移到其他账户。

总结

以上就是 Solana PDA 的四个实用示例。

第一,关联代币账户程序使用 PDA 存储钱包所拥有的每种代币的余额。

第二,你编写的程序可以使用用户的公钥来存储与特定用户关联的数据,也可以使用你为特定数据项设置的 ID 来存储与这些数据项关联的数据。

第三,程序可以在 PDA 中存储自己的配置,并通过仅限管理员使用的指令处理器限制谁能修改这些设置。

第四,PDA 可以拥有自己的代币账户,从而让程序持有资金。只需指定拥有这些代币的 PDA 的种子,程序就能为使用这些代币的交易“代签”。

PDA 不仅让 Solana 保持高速,还提供完整的键值存储,使程序能够根据你指定的种子快速查找数据。 

祝你愉快使用 PDA,也别忘了多看几部 Paul Verhoeven 的电影!

订阅 Helius

及时了解 Solana 开发的最新动态,并在我们发布新内容时收到更新