人工智能 (AI) 正在改变我们构建软件的方式。它可以发现和修复错误、启动新功能并处理一些我们不想做的琐事。Copilot 和 Cursor 等工具使编码更快、更轻松。但它们并不总是能很好地与 Solana 配合使用。

Solana 的架构使其有别于大多数区块链。它并行处理交易,依赖于账户而非合约拥有的状态,并使用程序派生地址 (PDA) 来提高安全性。如果您读过我们的博客文章,您就会知道在 Solana 上构建与在以太坊上构建不同。Solana 提供高吞吐量,并采用独特的账户管理方法。这种区别常常使在不同编码模式上训练的 AI 模型感到困惑。
本文将探讨为什么 AI 有时会与 Solana 发生冲突。它还将提供避免这些问题的方法。我们的主要重点是:
提示工程:为人工智能编写更好的指令。
上下文输入:提供项目的详细信息,以便 AI 输出更加准确。
迭代工作流程:以小步骤构建代码。继续操作之前先检查并完善。
无论是新手还是有经验的人,这些技巧都将帮助您在使用 Solana 时从 AI 中获得更多收益。
Solana 开发中 AI 面临的挑战
Solana 独特的架构和要求可能会给 AI 带来问题。如果 AI 不考虑这些问题,您将浪费时间调试代码或重写程序,这违背了使用 AI 简化开发的目的。
Solana 的独特建筑
Solana 主要在三个方面脱颖而出:
1.基于账户的模型
许多区块链(例如以太坊)将数据直接绑定到智能合约的内部存储。另一方面, Solana 的编程模型围绕“账户”组织一切。这些账户保存数据,而“程序”(Solana 的智能合约等同物)修改数据并与之交互。
一个关键的区别是,在 Solana 上,一切都是账户,甚至程序本身也是如此。程序只是存储可执行数据的账户,这使它们能够处理指令。相比之下,以太坊区分了由私钥控制的外部拥有账户 (EOA) 和拥有其代码和内部存储的智能合约。
这种根本差异可能会导致误解,尤其是在为 Solana 编写代码时。与以太坊智能合约一样,不熟悉账户模型的开发人员可能会错误地认为程序可以拥有其数据。在部署 Solana 时,此类假设可能会导致运行时错误或安全漏洞。
2. 程序派生地址 (PDA)
程序派生地址 (PDA) 由程序 ID 和种子创建。PDA 允许程序组织账户而无需私钥。但是,AI 模型可能无法看出标准地址和 PDA 之间的区别。如果它们忘记处理种子或检查所有权,PDA 将是正确的 Rust 代码,但不是正确的 Solana 代码。
3.并行执行
Solana 的运行时 Sealevel 允许它并行处理交易,而不像传统的区块链每次只处理一个交易。这是因为交易指定了它们将读取和写入哪些帐户。有了这些信息,Solana 可以确定哪些帐户需要锁定,并安全地同时执行许多交易。
AI 经常误解这个模型。它可能会假设交易将按顺序运行,就像在以太坊虚拟机 (EVM) 中一样。这可能会导致代码无法优化并行性。由于 Solana 基于帐户的锁定系统与 EVM 的方法不同,AI 可能会编写性能不佳或扩展性不佳的代码。
常见痛点
开发人员在使用 AI 构建 Solana 应用程序时会面临一些反复出现的问题:
1. 代码错误
AI 可能会提供在 Rust 中编译的函数,但当您将它们部署到 Solana 时会失败。例如,AI 配对编程工具可能会忽略签名者或误解帐户引用。结果如何?在运行测试、实际交易或完成安全审计之前,您无法发现错误或安全漏洞。
2. 次优代码
即使人工智能生成的代码有效,它也可能不会针对计算单元进行优化,导致交易处理缓慢,或引入无法看到的隐藏瓶颈。想象一下,一个人工智能编写一个函数来一次更新一个账户。它无法认识到如果正确实施,Solana 可以同时处理它们。
3. 艰难的调试
除非您告知 AI 模型,否则它们不会知道您的文件夹结构或您如何定义自定义数据类型。这意味着它们可能会提出与您现有设置相冲突的解决方案,而将这些解决方案重新合并到您的项目中可能会成为一件令人头疼的事情。
如何使用 AI 进行 Solana 开发
请遵循以下建议使用 AI 构建 Solana 应用程序:
1. 从强大的系统提示开始
系统提示就像是 AI 的工作描述。它告诉 AI 自己的角色(例如“您是使用 Anchor 进行 Solana 编程的专家...”),并概述了您希望它遵循的规则。
这是一个典型的例子,稍微扩展了一下:
代码
# You are an expert in Solana program development.
Specializing in building and deploying smart contracts using Rust and Anchor,
and integrating on-chain data with @solana/web3.js.
---
## General Guidelines
- Write secure, efficient, and maintainable code for Solana programs.
- Thoroughly test and audit all programs before deployment.
## Solana Program Development with Rust and Anchor
- Prioritize Rust's safety and performance.
- Use Anchor macros to simplify account management, error handling, and
data serialization.
- Keep code modular and maintain a clear separation between logic and data.
## Security and Best Practices
- Enforce strict access controls--ensure only permitted signers can modify data.
- Use PDAs responsibly: validate seeds and ownership checks to prevent conflicts.
## Performance and Optimization
- Minimize transaction costs by bundling operations efficiently.
- Exploit parallelism--don't serialize steps unnecessarily.
- Regularly benchmark your code to spot and remove performance
为什么有效
编写良好的系统提示就像蓝图一样,它将人工智能与 Solana 的架构保持一致。这确保每个响应都是准确、安全的,并且符合您的需求。
设置正确的上下文:将 AI 声明为“Solana 专家”可确保它专注于 Solana 特定的功能,例如 PDA、并行性和 Anchor,而不是做出通用的区块链假设。
生成一致的代码:包括严格访问控制和并行执行等最佳实践,指导 AI 创建安全、可靠和可预测的输出。
避免常见错误:突出显示 Rust 安全性、Anchor 宏和序列化可减少错误。它节省了您调试和重写代码的时间。
发挥 Solana 的优势: AI 必须增加带宽并减少延迟。这将优化代码以实现 Solana 的高吞吐量和效率。
2. 写出清晰的提示
当要求 AI 生成代码时,精度是关键。精度越高,结果就越好。比较以下示例:
错误提示:
“编写一个函数来初始化一个账户。”
这个提示太模糊了。人工智能不知道编程语言、框架,也不知道这个提示是针对 Solana 代码的。它可能会给你通用或无用的代码。
好的提示:
“使用 Anchor 在 Rust 中编写一个函数来初始化 Solana 代币帐户。使用从种子派生的 PDA。验证帐户状态,如果帐户已初始化,则处理错误。”
这就是为什么好的提示有效的原因:
清晰的提示有助于节省时间和精力。通过明确人工智能的目标,您可以避免程序因创建混乱、不明确或错误代码而需要稍后纠正。它还可以最大限度地减少误解,使人工智能的工作更加有效。
它清晰直接:通过直接命名 Rust、Anchor 和 PDA,AI 确切地知道要使用哪些工具和功能。它不会猜测或包含不相关的细节。
它专注于 Solana 的需求:提及 PDA 会告诉 AI 包含特定于 Solana 的逻辑。如果没有这一点,代码可能会错过安全派生地址等重要步骤。
它在需要的地方增加了深度:验证和错误处理指令告诉人工智能超越基础。这有助于确保代码在真实场景中发挥作用。
好的提示就像一张地图,可以引导人工智能并帮助它避免陷阱并实现目标。
3.提供适当的背景
当你为 AI 提供适当的上下文时,它会更好地工作。许多工具都允许你上传代码或链接文件。这有助于 AI 理解你的项目并创建适合你的代码库的解决方案。
但不要让它超载。向人工智能输入过多信息(例如整个大型代码库)可能会导致它产生幻觉或做出不相关的反应。
相反,你应该专注于提供代码的相关部分。这可以让人工智能保持专注,并提高其建议的质量。
例如,假设您的应用程序已经有一个定义自定义数据结构的文件:
代码
#[account]
pub struct TokenAccount {
pub balance: u64,
pub is_initialized: bool,
// ... more fields
}
如果您上传此文件或将其作为输入的一部分,AI 可以在其生成的代码中使用您的确切字段名称( balance, )。is_initialized
它还可以使其建议与您的项目结构和惯例保持一致。
这就是为什么提供背景信息有效
提高准确性:如果没有上下文,AI 可能会猜测字段名称、引入不必要的更改或假设错误的数据类型。例如,它可能会将您的余额字段称为金额或使用 f64 而不是 u64。提供实际结构可以消除这种猜测。
保持代码一致性:当 AI 理解您的命名约定时,它会生成适合您项目的代码。这样就省去了重命名变量或重新编写代码以匹配现有模式的麻烦。
减少集成工作:如果人工智能看到您的帐户结构,它可以定制其输出以直接与其集成。这避免了人工智能生成的代码需要大量重写才能适应您现有逻辑的情况。
示例:如何添加上下文来改善人工智能输出
如果没有适当的上下文,像“编写一个函数来更新代币账户余额”这样的提示可能会导致 AI 生成如下代码:
代码
pub fn update_balance(ctx: Context<UpdateAccount>, amount: f64) -> Result<()> {
let account = &mut ctx.accounts.token_account;
account.amount += amount;
Ok(())
}
这段代码有两个问题:
首先,它使用f64金额而不是u64。
Solana 对原生浮点运算的支持非常有限。首选方法是使用定点运算并根据使用的小数缩放数字,这样可以避免性能和兼容性问题。
其次,它调用了余额字段 amount,这与您的结构不匹配。这可能会在将来导致混乱和错误。
现在,如果你提供 TokenAccount 结构作为上下文,AI 可能会生成以下内容:
代码
pub fn update_balance(ctx: Context<UpdateAccount>, amount: u64) -> Result<()> {
let token_account = &mut ctx.accounts.token_account;
token_account.balance += amount;
Ok(())
}
此输出与您的项目更加契合。
然而,即使有了这样的改进,仍然值得在操作上添加溢出检查token_account.balance += amount 以确保代码的稳健性和安全性。
如何提供背景信息
记住以下步骤,为您的 AI 工具提供适当的上下文:
上传文件:如果您的 AI 工具允许,请上传您的结构定义、帐户模式和其他项目文件。
提示中的参考代码:将相关片段复制并粘贴到提示中,以便 AI 可以将它们用作参考。
描述结构:如果无法上传,请在提示中清楚地描述您的数据。例如,“我有一个名为 TokenAccount 的结构,其中包含字段 balance (u64) 和 is_initialized (bool)。 ”
4. 基于现有代码
您不必每次都从头开始。通常,您已经有一段可以运行的代码,但可以做得更好。人工智能可以帮助您改进它。以下是一个例子:
以下是原始代码:
代码
pub fn create_token_account(ctx: Context<CreateAccount>) -> Result<()> {
let token_account = &mut ctx.accounts.token_account;
token_account.balance = 0;
Ok(())
}
此代码初始化一个代币账户并将余额设置为零。这很简单,但不能处理更新现有账户或检查所有权等场景。
您的提示:
“让这个功能更加强大。如果代币账户存在,就将其添加到余额中。如果不存在,就用特定金额初始化它。另外,确保当前程序拥有该账户。”
这是根据您的提示 AI 生成的代码:
代码
pub fn create_or_update_token_account(
ctx: Context<CreateAccount>,
amount: u64
) -> Result<()> {
let token_account = &mut ctx.accounts.token_account;
// Check ownership
if token_account.owner != ctx.program_id {
return err!(ProgramError::IncorrectProgramId);
}
// Update or initialize
if token_account.is_initialized {
token_account.balance += amount;
} else {
token_account.balance = amount;
token_account.is_initialized = true;
}
Ok(())
}
为什么有效
解决常见场景:新代码处理已初始化和未初始化的帐户,使其在实际应用中更有用。
添加所有权验证:这可以防止未经授权的更改,因为程序会检查它是否拥有该帐户。
使函数更智能:该函数现在可以更新余额,而不是每次都将其重置为零。这减少了冗余并适合实际用例。
节省时间:您不必重写整个函数。AI 会扩展您已有的功能,从而更快地从基本功能转变为强大的功能。
如何使用这种方法
记住以下步骤,以便将来可以遵循此方法:
从工作基础开始:确定可以运行但可以改进的功能或片段。
在提示中要具体:解释您想要改进什么,例如添加错误检查、处理边缘情况或改进逻辑。
查看 AI 建议:查看 AI 生成的输出以确保它适合您的项目并遵循 Solana 的最佳实践。
根据需要进行迭代:如果第一个输出不完美,请调整提示或编辑代码以更接近您的目标。
5. 一步步迭代开发
逐步编写代码可帮助您避免错误,并在过程中不断完善工作。与其尝试一次性创建复杂的功能,不如将其分解为较小的任务。这样,在继续之前,测试和改进每个部分会更加容易。
示例工作流程
让我们从小事做起。要求人工智能使用种子计算程序派生地址 (PDA) 的简单函数。
以下是示例提示:
“编写一个 Rust 函数,使用 Anchor 根据种子和程序 ID 计算 PDA。”
人工智能的输出:
代码
pub fn find_pda(seed: &[u8], program_id: &Pubkey) -> Pubkey {
Pubkey::create_program_address(&[seed], program_id).unwrap()
}
这是一个很好的起点,但还不完整。让我们添加错误处理。
检查代码并找出问题。例如,如果种子无效,使用 unwrap() 可能会导致程序崩溃。
提示AI修复此问题:
“更新此功能以包含无效种子的错误处理。返回结果而不是解包。”
更新代码:
代码
pub fn find_pda(seed: &[u8], program_id: &Pubkey) -> Result<Pubkey, ProgramError> {
Pubkey::create_program_address(&[seed], program_id)
.map_err(|_| ProgramError::InvalidSeeds)
}
现在,该函数可以通过返回错误而不是恐慌来妥善处理无效种子。
接下来我们来集成该功能。
让人工智能在更大的例程中使用 PDA 功能。例如:
“编写一个使用此 PDA 创建新令牌帐户的函数。验证 PDA 尚未被使用。”
以下是人工智能的输出:
代码
pub fn create_token_account(ctx: Context<CreateAccount>, seed: &[u8], amount: u64) -> Result<()> {
let program_id = ctx.program_id;
let pda = find_pda(seed, &program_id)?;
if ctx.accounts.token_account.key != pda {
return Err(ProgramError::InvalidSeeds);
}
if !ctx.accounts.token_account.is_initialized {
let token_account = &mut ctx.accounts.token_account;
token_account.balance = amount;
token_account.is_initialized = true;
}
Ok(())
}
此步骤将 PDA 逻辑集成到帐户创建中,同时确保 PDA 不会被错误地重复使用。
现在,让我们优化并完成代码。要求人工智能使用以下提示进一步完善该函数:
“优化此功能以最大限度地降低交易成本并包括所有权验证。”
以下是人工智能的输出:
代码
pub fn create_token_account(ctx: Context<CreateAccount>, seed: &[u8], amount: u64) -> Result<()> {
let program_id = ctx.program_id;
let pda = find_pda(seed, &program_id)?;
if ctx.accounts.token_account.key != pda || ctx.accounts.token_account.owner != program_id {
return Err(ProgramError::IncorrectProgramId);
}
if !ctx.accounts.token_account.is_initialized {
let token_account = &mut ctx.accounts.token_account;
token_account.balance = amount;
token_account.is_initialized = true;
}
Ok(())
}
最终功能现在高效、安全,并且与 Solana 的最佳实践保持一致。
为什么这种方法有效
保持事情可控:每次专注于一个小任务,避免让人工智能不堪重负。每一步都建立在最后一步的基础上,使其更容易测试和改进。
尽早发现错误:步骤越小,您就能在问题影响其余代码之前发现它们。例如,尽早添加错误处理可防止以后出现崩溃。
促进迭代:如果某些功能不能完美运行,您可以调整功能而不需要重新编写整个代码库。
生成更好的代码:每次改进都会使代码更加健壮,最终您会得到更可靠、更易于维护的解决方案。
如何使用这种方法
下次与 AI 结对编程时,请记住这些提示:
将任务分解为更小的步骤:不要请求单个复杂的功能,而是将其分解为更简单、更易于管理的任务,然后一个接一个地执行。
每一步后测试结果:每次更改后运行代码以确认其是否有效。如果无效,请修复问题或调整提示,然后再继续下一步。
不断完善:不要将自己限制于单一结果。要求 AI 优化或添加验证、性能改进或更好的错误处理等功能。
结论:开始在 Solana 上使用 AI 开展工作
如果您采取谨慎而周到的方法,使用 AI 构建 Solana 将会非常强大。Solana 的架构与其他区块链不同,就像它使用 PDA、并行交易处理和基于帐户的设计一样。这意味着您需要正确引导 AI。
从明确的提示开始。准确地告诉人工智能你想要什么,并具体说明 Rust、Anchor 和 PDA 等工具。一个好的提示可能是:
“编写一个 Rust 函数,使用 PDA 初始化 Solana 代币账户,验证账户状态并处理错误。 ”
这种清晰度使人工智能更有机会生成适用于 Solana 的代码。
始终提供背景信息。分享项目代码或解释您正在使用的结构,例如帐户架构或数据类型。例如,如果您有一个TokenAccount结构,请包含其详细信息,以便 AI 可以调整其输出。但不要让 AI 感到不知所措 - 专注于相关部分,以确保建议准确且有价值。
将任务分解为更小的步骤。使用迭代过程来改进代码。从简单的任务开始,例如计算 PDA,然后在此基础上进行错误处理或帐户验证。每一步之后进行测试。通过这样做,您可以尽早发现问题并稳步前进。
最后,仔细检查 AI 工作。大多数情况下,AI 生成的代码也存在一些小问题,例如缺少溢出检查或跳过验证。确保输出遵循 Solana 的规则、保持无错误并使用并行执行功能。
AI 只是一个起点;你必须完成这项工作。使用清晰的说明、上下文、逐步开发和仔细的审查,你可以使用 AI 创建安全且优化的 Solana 程序。继续参与这个过程,AI 将成为一种有价值的工具,帮助你节省时间并编写更好的代码。