Solana 多行业应用的技术共性:账户模型、PDA 模式与 CPI 调用的可复用范式
Solana 多行业应用的技术共性账户模型、PDA 模式与 CPI 调用的可复用范式一、引言Solana 生态在 2026 年已经覆盖了 DeFiJupiter、Marinade、NFTMagic Eden、Tensor、DePINHelium、Hivemapper、支付Solana Pay四类场景。表面上看这些项目的合约逻辑截然不同——DeFi 处理的是 AMM 曲线和借贷因子NFT 处理的是元数据和版税分配DePIN 处理的是物理设备验证和激励机制——但它们在 Solana 的编程模型层面共享着同一套底层范式账户模型做数据隔离、PDAProgram Derived Address做确定性寻址、CPICross-Program Invocation做合约组合。理解这三项技术共性是跨行业开发 Solana 程序的基础。掌握后从一个 DeFi 项目切换到 NFT 项目的学习曲线会从学一套新工具变为学一套新的业务逻辑发在已经熟悉的原语上。本文不是 Solana 入门教程而是针对已有 EVM 开发经验的工程师梳理 Solana 编程模型中的可复用范式展示四个场景如何基于相同的底层技术构建出差异化的业务逻辑。二、三大范式架构Solana 的账户模型和 EVM 的存储模型有根本差异这个差异决定了开发范式的不同核心差异EVM 中合约的数据存储在合约自身的 storage 中每个合约管理自己的状态。Solana 中程序代码和数据是完全分离的——程序只包含可执行逻辑BPF 字节码数据存储在与程序关联、由用户创建并支付 rent 的独立 Account 中。这意味着 Solana 程序天然支持数据可以在不修改程序的情况下升级结构——因为数据格式由 Account 的序列化方式决定不需要像 EVM 那样做存储布局迁移。PDA 是 Solana 最具特色的设计。它是由程序 ID 和一组 seed 确定性派生出的地址没有对应私钥因此只有关联的程序可以通过invoke_signed进行程序签名。PDA 的典型用途是程序托管的资产池——用户将 token 转入 PDA只有程序逻辑验证通过后才能从 PDA 中转出 token。这比 EVM 中通过mapping(address uint256)记账更安全因为 token 真正地在程序的账户里而不是在合约的 accounting 中。三、可复用范式实现Anchor 框架以下代码展示四个场景共享的三段核心范式代码// programs/shared-paradigms/src/lib.rs use anchor_lang::prelude::*; use anchor_spl::token::{self, Token, TokenAccount, Transfer}; declare_id!(Para1111111111111111111111111111111111111); /** * 范式一PDA 作为程序托管账户 * 四个场景都用到DeFi 的池子、NFT 的市场托管、DePIN 的奖励池、支付的中间账户 * 设计决策 * - seed 中纳入 authority 的 pubkey确保每个用户有独立 PDA * - seed 中纳入场景标识pool / market避免同用户的不同场景 PDA 碰撞 * - PDA 的 bump 存储在 account 内而非每次重新计算节省 CU */ #[derive(Accounts)] pub struct InitializeVaultinfo { /// 场景通用程序托管账户 /// 确定性地址 PDA(seed[bvault, scene.as_bytes(), authority.key().as_ref()], program_id) #[account( init, payer authority, space 8 Vault::INIT_SPACE, seeds [bvault, scene.as_ref(), authority.key().as_ref()], bump )] pub vault: Accountinfo, Vault, #[account(mut)] pub authority: Signerinfo, pub system_program: Programinfo, System, /// 场景标识用于区分同一个程序的多个场景 /// DeFi - bdefi_pool NFT - bnft_market DePIN - bdepin_reward 支付 - bpayment pub scene: String, } #[account] #[derive(InitSpace)] pub struct Vault { pub authority: Pubkey, pub bump: u8, pub total_deposited: u64, /// 场景标签在 deposit/withdraw 时做场景校验 pub scene_tag: [u8; 32], } /** * 范式二CPI 调用 SPL Token Program * Solana 的 token 转账必须通过 CPI 调用 Token Program * 这是所有 DeFi/NFT/DePIN/支付项目都需要的基础操作。 * 设计决策 * - 使用 anchor_spl 的高层封装而非手动构造 Instruction * 减少手动管理 account_info 出错的概率 * - 关键风险在 signer_seedsPDA 签名的 seed 必须与创建 PDA 时使用的 seed 完全一致 * 任何 seed 参数的顺序、大小写差异都会导致签名验证失败 */ implinfo InitializeVaultinfo { pub fn deposit_tokens( self, from: Accountinfo, TokenAccount, to: Accountinfo, TokenAccount, amount: u64, ) - Result() { let cpi_ctx CpiContext::new( ctx.accounts.token_program.to_account_info(), Transfer { from: from.to_account_info(), to: to.to_account_info(), authority: ctx.accounts.authority.to_account_info(), }, ); token::transfer(cpi_ctx, amount)?; Ok(()) } pub fn withdraw_tokens_with_pda( self, vault: Accountinfo, Vault, from: Accountinfo, TokenAccount, // PDA 关联的 token account to: Accountinfo, TokenAccount, amount: u64, scene: str, ) - Result() { let seeds [ bvault, scene.as_bytes(), vault.authority.as_ref(), [vault.bump], ]; let signer_seeds [seeds[..]]; let cpi_ctx CpiContext::new_with_signer( ctx.accounts.token_program.to_account_info(), Transfer { from: from.to_account_info(), to: to.to_account_info(), // 关键authority 是 PDA使用 signer_seeds 签名 authority: from.to_account_info(), }, signer_seeds, ); token::transfer(cpi_ctx, amount)?; Ok(()) } } /** * 范式三跨程序组合 * DeFi 聚合器调用多个 DEX、NFT 市场调用 Metaplex、DePIN 调用 oracle * 本质上都是通过 CPI 组合多个程序的能力 * 设计决策 * - 使用 anchor 的 CpiContext 而非 solana_program::invoke * 前者做编译期 account 校验后者只在运行时报错 * - 调用深度限制 4 层是硬约束复杂编排需要扁平化调用层级 */ pub fn composable_swapinfo( ctx: Context_, _, _, info, ComposableSwapinfo, amount_in: u64, min_amount_out: u64, ) - Result() { // Step 1: 调用 DEX A 做第一次 swap let cpi_ctx_a CpiContext::new( ctx.accounts.dex_a_program.to_account_info(), dex_a::Swap { user: ctx.accounts.user.to_account_info(), pool: ctx.accounts.pool_a.to_account_info(), // ... }, ); dex_a::swap(cpi_ctx_a, amount_in, 0)?; // 先全量换出 // Step 2: 用 DEX A 的输出调用 DEX B 做第二次 swap let cpi_ctx_b CpiContext::new( ctx.accounts.dex_b_program.to_account_info(), dex_b::Swap { user: ctx.accounts.user.to_account_info(), pool: ctx.accounts.pool_b.to_account_info(), // ... }, ); dex_b::swap(cpi_ctx_b, intermediate_amount, min_amount_out)?; Ok(()) } #[derive(Accounts)] pub struct ComposableSwapinfo { pub user: Signerinfo, /// 跨程序调用的关键把被调用程序的 Account 声明在这里 /// Anchor 在 #[derive(Accounts)] 阶段就会校验这些 Account 的存在性和所有权 pub dex_a_program: Programinfo, dex_a::program::DexA, pub dex_b_program: Programinfo, dex_b::program::DexB, pub pool_a: Accountinfo, dex_a::Pool, pub pool_b: Accountinfo, dex_b::Pool, }四、边界与 EVM 迁移陷阱账户数据的序列化成本。在 EVM 中读写 storage 直接操作 256-bit slot。Solana 中读取 Account 数据需要反序列化全部数据到一个 Rust struct 中写回需要序列化整个 struct。一个 10KB 的 Account 每次 CPI 调用都需要额外消耗大约 5000 CU 的序列化/反序列化开销。对于高频交易场景需要将热数据拆分为多个小 Account 以减少序列化成本。PDA 的确定性与灵活性矛盾。PDA 的确定性地址是双刃剑——它让你可以计算一个地址而无需存储但这也意味着 PDA 的 seed 必须在设计阶段就确定后续无法更改。如果初始设计中没有在 seed 中包含某个业务维度如场景版本后期想加入时不得不部署新程序并使用新的 seed 前缀旧 PDA 中的数据需要迁移。EVM 开发者习惯在 mapping 中动态添加 key这种自由度在 Solana 的 PDA 模型中需要通过更谨慎的前期设计来弥补。账户 rent 的经济成本。Solana 上创建 Account 需要存入 rent-exempt 的最低 lamports。一个简单的 vault Account约 80 bytes需要约 0.0015 SOL 的 rent。对于需要为每个用户创建 PDA 的应用每 100 万用户需要约 1500 SOL 的 rent 成本——且这笔费用由用户或应用支付。对于大规模 C 端应用需要在设计阶段就评估 rent 的经济可行性。CPI 深度限制 4 层。这意味着调用链 A→B→C→D 是极限A→B→C→D→E 会直接失败。对于聚合器、路由器这种需要组合多个程序的场景需要在设计时做好扁平化——将多步操作合并为一个程序的内部逻辑通过减少 CPI 层数来绕过深度限制。Anchor 版本迭代导致的 IDL 不兼容。Anchor 框架的升级从 0.28 到 0.29 到 0.30引入了 IDL 格式变化、account serialization 变化等 breaking changes。跨场景复用时需要确保所有依赖同一个程序的其他程序使用相同的 Anchor 版本。五、总结Solana 的 Account 模型、PDA 和 CPI 是三个正交但相互配合的范式。理解它们的组合方式后DeFi、NFT、DePIN、支付四个场景的差异就回到了业务逻辑层面——AMM 曲线、版税分配、设备验证、结算流程——而不是在底层编程模型上重新学习。从 EVM 迁移到 Solana 时最重要的心态调整是从合约拥有数据切换到程序处理账户数据。这个观念转变后PDA 和 CPI 的运用会变得自然。最大的陷阱不是技术细节这些文档都有写而是带着 EVM 的设计习惯来设计 Solana 程序的架构——比如习惯性地把不同用户的数据放在同一个数组中而不是为每个用户创建独立的 PDA。

相关新闻

告别龟速!2026最新百度网盘加速/解析下载技巧,轻松跑满宽带上限

告别龟速!2026最新百度网盘加速/解析下载技巧,轻松跑满宽带上限

在日常生活与工作中,我们经常需要通过网络存储工具接收或保存各类文件资料。然而,在传输较大体积的文件时,偶尔会遇到读取进度极其缓慢的情况,导致时间成本大幅增加。面对这种传输效率偏低的问题,我们可以从网络环境、…

2026/10/16 1:13:49 阅读更多 →
深度学习在脑部MRI配准中的创新应用与优化策略

深度学习在脑部MRI配准中的创新应用与优化策略

1. 脑部MRI配准技术背景与挑战医学影像配准是临床诊疗和科研分析中的基础性技术,尤其在神经影像领域,精准的脑部MRI配准能够实现跨个体解剖结构的空间对齐,为疾病诊断、手术规划和神经科学研究提供关键支撑。传统配准方法主要分为基于特征和基…

2026/10/16 2:58:56 阅读更多 →
C++实战指南:从环境配置到算法优化,解决开发中的常见问题

C++实战指南:从环境配置到算法优化,解决开发中的常见问题

1. 项目概述:从“遇到问题”到“解决问题”的C学习心路 最近在XMUOJ(一个在线判题系统)上刷C题目,我遇到了不少让人挠头的“坎”。从环境配置报错,到指针内存泄漏,再到面对算法题时毫无头绪,相…

2026/10/16 2:10:10 阅读更多 →

最新新闻

en_core_web_sm 2.2.5实战:小模型搞定命名实体识别与CPU部署

en_core_web_sm 2.2.5实战:小模型搞定命名实体识别与CPU部署

简介:spaCy官方英语小型模型en_core_web_sm的2.2.5版本离线压缩包,面向需要在Python环境中快速完成分词、词性标注、命名实体识别和依存句法分析的NLP开发者与学习者。该模型体积轻巧,适合内存受限或对推理速度敏感的场景。压缩包装载共30个文…

2026/10/17 3:00:43 阅读更多 →
sqli-labs Less-44实战:从Cookie报错注入到堆叠注入

sqli-labs Less-44实战:从Cookie报错注入到堆叠注入

我第一次做sqli-labs-Less-44时,先在登录框里折腾了十几分钟,以为这只是Less-42的换皮关卡。直到某次登录成功后顺手改了返回包里的Cookie,页面直接吐出一行SQL语法错误,我才意识到:这道题真正考的是把POST型堆叠注入和…

2026/10/17 3:00:43 阅读更多 →
模型量化入门:从FP32到INT8的压缩原理与实战方法

模型量化入门:从FP32到INT8的压缩原理与实战方法

1. 量化到底在压缩什么:一次把收益算明白做模型部署的人应该都有过这种经历:训练好的模型明明在离线评测里表现不错,一上生产环境就被“内存超限”打回来。一个标准的 FP32 模型,光权重就占 4 字节/参数,几千万参数就是…

2026/10/17 3:00:43 阅读更多 →
全局热键一键唤出/隐藏xterm:Linux终端高效切换实战

全局热键一键唤出/隐藏xterm:Linux终端高效切换实战

如果你和我一样,桌面永远堆着一排窗口,浏览器、编辑器、聊天工具各自占着一块屏幕,那么你一定经历过这种事:正写到一半想跑个命令,却发现唯一能用的 xterm 早被挤到不知道哪一层去了。鼠标移到任务栏翻来翻去找窗口&am…

2026/10/17 3:00:43 阅读更多 →
果园柑橘检测数据集:VOC+YOLO双格式2511张单类别实战解析

果园柑橘检测数据集:VOC+YOLO双格式2511张单类别实战解析

做农业视觉项目的同行,应该都体会过找数据的痛。果园场景尤其难搞——光照复杂、枝叶遮挡、果实重叠,想训练一个靠谱的树上柑橘检测模型,光数据就能卡你一周。这份《果园柑橘树上柑橘检测数据集 VOCYOLO格式 2511张 1类别》我实际跑了一遍&am…

2026/10/17 3:00:43 阅读更多 →
多智能体系统安全:协同攻击、权限隔离与纵深防御的工程实践

多智能体系统安全:协同攻击、权限隔离与纵深防御的工程实践

把时间拨回几天前。如果你是一位正在把多智能体系统推向生产环境的工程师,你一定见过这样的画面:代码里跑着十几个 Agent,它们共享同一份上下文记忆,也会在同一个事件总线上互通消息。某个 Agent 被一条用户输入诱导,输…

2026/10/17 2:59:43 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →