Solana账户基础:第一部分 - 构建模块

这篇文章深入探讨了Solana账户的工作原理及其在高效区块链应用开发中的重要性。内容涵盖了账户的基本结构、核心组件、不同账户类型及其特性,并提供了安全性和性能的最佳实践,适合具有Rust背景的开发者学习与应用。

Solana的账户系统构成了其高性能区块链架构的核心。在本综合指南中,我们将探讨Solana账户的工作原理、基本属性以及它们为什么对开发高效区块链应用至关重要。

本文假设你对Rust有一定的了解

什么是Solana账户?

Solana账户是一种基本的数据结构,用于在区块链上存储代币和数据。每个Solana网络中的账户都有一个唯一的32字节公钥地址,并且可以持有SOL代币、程序代码或应用程序数据。

将Solana账户视为容器。与只存放资金的普通银行账户不同,Solana账户可以同时存储数据和代币。挺酷的,对吧?每当你与Solana的去中心化应用进行交互时,实际上是在幕后与这些账户进行工作。

以下是Solana账户的基本结构:

pub struct Account {
    lamports: u64,      // 你的SOL代币(1 SOL = 10亿lamports
                          // 可以把它想象成`wei`)
    data: Vec<u8>,       // 你的账户存储其数据的地方(在一个向量中)
    owner: Pubkey,       // 控制此账户的程序
    executable: bool,    // 此账户可以作为程序运行吗?
    rent_epoch: u64,    // 租金到期时间(稍后会详细介绍!)
}

Solana账户的核心组成部分

公钥地址

每个Solana账户都有一个唯一的公钥,通过Ed25519密码学生成。此地址既作为标识符,也作为验证交易的公钥。

账户所有权

在Solana的架构中,程序拥有账户——而非用户。这种基本的设计选择确保了Solana的高安全性和高性能。只有所有者程序可以修改账户的数据,从而在协议层面上执行严格的访问控制。

我知道,这听起来奇怪,但请继续关注。可以这样理解:如果账户是保险箱,程序就是银行,而你是拥有钥匙的客户。

假设你想转移一些代币。你不能直接拿手进去移动它们——你需要请求代币程序(所有者)为你执行此操作。这可能看起来像是额外的工作,但实际上这对安全性来说非常聪明。

数据存储

账户直接在字节数组中存储数据,使得:

  • 快速、直接访问数据
  • 可预测的存储成本
  • 高效的数据序列化
  • 清晰的所有权边界

假设你正在Solana上构建一个简单的游戏。你可能需要一个存储你数据的账户,如下所示:

// 在PDA中存储的示例游戏状态
##[account]
pub struct GameAccount {
    player: Pubkey,          // 玩家钱包地址
    score: u64,             // 当前分数
    tokens_earned: u64,     // 游戏内奖励
    last_played: i64,      // 时间戳
}

如果你不熟悉Anchor基础知识,请忽略此处的语法,而更关注数据存储的概念。

理解Solana中的账户类型

系统账户

系统账户是Solana账户中最基本的一种。它们可以持有SOL代币并作为用户钱包。这些账户由系统程序拥有,构成了用户与Solana网络交互的基础。

一个有趣的事实是:每次你创建一个新的Solana钱包时,实际上是创建了一个由系统程序拥有的系统账户。

程序账户

程序账户在Solana区块链上存储可执行代码(智能合约)。这些账户的可执行标志被设置为真,且由BPF加载程序拥有。程序账户默认是不可变的,以确保代码的安全性。

为了更好地理解这些账户,可以将它们视为操作的“大脑”。我们开发者将代码上传到程序账户。当你在Solana上部署智能合约时,你实际上是在创建一个将包含你程序代码的程序账户。程序账户的优点在于它们的可执行标志被设置为真,意味着它们实际上可以运行代码!

程序派生地址(PDAs)

这就是Solana真正聪明的地方。PDA是从程序派生的特殊账户——就像程序的个人文件柜。它们非常适合于:

  • 存储程序数据
  • 创建可预测的地址
  • 管理程序状态

PDA的一个好处是,没有人可以生成他们的私钥——它们是真正由程序控制的!你可以在这里阅读更多关于它们的内容

代币账户

如果你曾使用SPL代币(Solana等同于ERC-20的代币),那么你已经使用了代币账户。每个代币账户代表你特定代币的余额。这里有一个可能会让你感到惊讶的事实:你必须为每种持有的代币创建一个单独的代币账户!最重要的是,它们是由Token-Program拥有的,这是一个程序账户,并包含用于管理Token Accounts数据的代码。

数据账户

数据账户存储程序状态和用户数据。它们由各自的程序拥有,只能通过程序指令进行修改。这种设计确保了数据的完整性和受控访问。

这意味着这些账户不能被手动修改,因为里面存储着数据。根据Solana的架构,只有程序的代码才被允许对其进行更改。

例如:你有一个Struct来存储用户的股份数据详情。那么,你将把这个结构存储在DATA账户中,并且要修改该结构,只有你的程序指令(你编写的Rust代码)才能修改此数据。

总结不同账户类型的比较

租金系统:为什么你的账户需要“津贴”

现在,让我们谈谈Solana独有的内容——租金。就像在现实世界中,存储数据在Solana上是需要付费的。你的账户需要支付租金以保持在网络上的存活。但是不要担心!如果你在账户中保持足够的SOL(大约每千字节0.002 SOL),它就会变为“免租”——就像购房而不是租房。

租金计算遵循以下公式:

let rent_exempt_minimum = account_size * LAMPORTS_PER_BYTE * 2;

没有Anchor的账户管理最佳实践

Anchor是流行的Solana开发框架,简化了账户管理,同时强制执行最佳实践。在本文中,我们不会深入探讨Anchor,而是首先理解Solana的核心模型,因为这将使我们更快地理解Anchor。

如果你现在无法立即理解,不用担心。我们将很快推出一个独立的Anchor系列!

大小规划

在初始化之前仔细计算账户大小:

// 计算带填充的账户大小
const ACCOUNT_DISCRIMINATOR: usize = 8;
const GAME_STATE_SIZE: usize =
    ACCOUNT_DISCRIMINATOR +  // 需要的前缀
    32 +                    // 公钥
    1 +                     // game_type
    2 +                     // current_round
    4 +                     // total_players
    1;                      // is_active

免租

在创建期间始终使账户免租:

let rent = Rent::get()?;
let rent_exempt_lamports = rent.minimum_balance(GAME_STATE_SIZE);

所有者验证

在你的程序中始终验证账户所有权:

if account.owner != program_id {
    return Err(ProgramError::IncorrectProgramId);
}

安全考虑

在处理Solana账户时,请考虑以下安全方面:

  • 账户所有权验证
  • 适当的权限检查
  • 安全数据序列化
  • 租金豁免状态

性能影响

Solana的账户模型通过以下方式促进了其高性能:

  • 直接数据访问
  • 并行事务处理
  • 高效状态管理
  • 清晰的所有权边界

后续步骤

了解Solana的账户系统对于构建高效的区块链应用至关重要。在第2部分和第3部分中,我们将进一步探索账户管理、交互及其实际应用。

开始在你的本地开发环境中实验这些概念。理解Solana账户的最佳方式是与之构建应用。

关键要点:Solana账户通过其独特的所有权模型和高效的数据存储系统,为区块链开发提供了灵活、安全的基础。

  • 原文链接: tusharbhatia43.medium.co...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OxElliot
OxElliot
https://tusharbhatia43.medium.com/