---
title: "什么是 Solana 账户模型？"
description: "了解 Solana 账户模型、不同的账户类型及其协同工作方式"
---

# 什么是 Solana 账户模型？

在 Solana 上，一切都可以被视为一个账户，账户是协议“组织”区块链数据的方式。本文将全面介绍 Solana 账户模型，包括类型和分类、账户组成部分，以及“租金”的概念。

## **什么是 Solana 账户，它是如何工作的？**

**Solana 账户可以被看作是存储桶，能够容纳各种数据类型：从 SOL 这样的代币，到程序的状态变量（例如整数、字符串、公钥），乃至整个程序本身。** 每个账户都有一个指定的所有者，一个所有者可以拥有多个不同的账户。

账户模型通常被拿来与计算机文件系统作比较：

<EmbeddedTable
  table={{
    columns: [
      { key: "1", width: 200, title: "Computer File", dataType: "object" },
      { key: "2", width: 200, title: "Solana Account", dataType: "object" },
    ],
    data: [
      {
        "1": { title: "<p>Name</p>", tooltip: "", icon: "" },
        "2": { title: "<p>lamports</p>", tooltip: "", icon: "" },
        id: 0,
      },
      {
        "1": { title: "<p>Address</p>", tooltip: "", icon: "" },
        "2": { title: "<p>owner</p>", tooltip: "", icon: "" },
        id: 1,
      },
      {
        "1": { title: "<p>Email</p>", tooltip: "", icon: "" },
        "2": { title: "<p>rent_epoch</p>", tooltip: "", icon: "" },
        id: 2,
      },
      {
        "1": { title: "<p>Experience</p>", tooltip: "", icon: "" },
        "2": { title: "<p>executable</p>", tooltip: "", icon: "" },
        id: 3,
      },
      {
        "1": { title: "<p>GeorgeBrownCV.docx</p>", tooltip: "", icon: "" },
        "2": { title: "<p>0cnjSElkwFlkffjckDSJRU432RIANCLk</p>", tooltip: "", icon: "" },
        id: 4,
      },
    ],
  }}
/>

## **Solana 有哪些账户类型？**

Solana 账户主要分为两种类型：可执行账户和不可执行账户。这是因为 Solana 程序不像 Ethereum 智能合约那样存储状态，所以需要将这两类操作分开。

### **什么是可执行程序？**

可执行程序由不可变的代码组成，这些代码拥有并创建其他用于存储状态的账户。这类代码用 **Rust** 等语言编写，然后编译为 eBPF，即一种字节码形式。

可执行程序最常见的例子是 Solana 的核心系统程序（System Program），负责创建人们用来访问代币和 NFT 的账户（钱包）。

### **什么是不可执行程序？**

不可执行程序是“存储”账户，包含所有其他类型的数据，如程序变量、代币余额、NFT、同质化货币等。协议通过不可执行账户反映每笔交易发生后的状态变化。

### **Ethereum 智能合约与 Solana 程序的对比**

智能合约内置一个称为“[storage](https://www.alchemy.com/docs/smart-contract-storage-layout)”的特殊区域，用于存储其状态变量。智能合约随后使用其可执行代码来修改这些状态变量。可以将 Ethereum 合约看作是可执行代码与不可执行代码共存的统一场所。

以 USDC 代币为例。它的合约包含一个名为“balances”的映射，将用户地址映射到其对应的 USDC 数量。当用户发送或接收 USDC 代币时，合约凭借其可执行代码自行反映这些变化。

Solana 的处理方式有所不同。存在一个 USDC 代币程序，为每个代币持有者创建一个新账户，这些账户存储持有者可用的 USDC 数量。当用户发起一笔交易时，USDC 代币账户会查找想要进行兑换的用户所关联的代币账户，然后在其中反映相应的变化。

<ImageBlock
  src="https://media.alchemy.com/1703697343-solana-associated-token-account-structure.png"
  alt="Solana 代币程序创建关联代币账户以持有每个用户 USDC 余额的示意图"
  width={1600}
  height={901}
  caption="Solana 的关联代币账户结构"
/>

## **Solana 有哪些账户分类？**

可执行账户和不可执行账户还可以进一步细分为若干类别，例如原生程序、[程序账户和数据账户](https://www.alchemy.com/overviews/solana-data-vs-program-accounts)。

### **什么是可执行的原生程序？**

**可执行的原生程序是 [Solana 生态系统](https://www.alchemy.com/dapps/ecosystem/solana)“原生”自带的程序，负责维护和运行验证节点等任务。这一类型最广为人知的例子是系统程序（System Program）**，它负责创建新的系统账户（也就是我们通常所说的“钱包”）、SOL 转账等。原生程序的其他例子还包括**质押程序（Stake Program）**，负责质押机制，以及 BPF Loader，其作用类似于 Ethereum 的 EVM。

### **什么是可执行的程序账户？**

可执行的程序账户是预先构建好的 Solana 程序，用于创建和存储其他程序。一个很好的例子是 [Solana Program Library](https://www.alchemy.com/overviews/solana-program-library)（SPL）——一系列支持链上多种活动的程序集合，包括创建、兑换和借贷代币、生成质押池，以及维护链上域名服务。SPL 中一个突出的代表是**代币程序（Token Program）**，它负责创建和管理代币。

Solana 的 USDC 代币只是一个由代币程序管理的 Token 账户。然而，Token 账户本身并不存储用户的代币余额，这一工作由第三类账户中的成员来完成：**数据账户**。

### **什么是不可执行的数据账户？**

原生程序和程序账户被视为可执行账户，而数据账户则恰恰相反：它们是一种记录簿，反映特定程序以及整个 Solana 协议的状态变化。

数据账户可以分为：

1. **Token 账户** - 由代币程序创建的账户
1. **关联代币账户（ATA）** - 存储每个用户代币余额的账户
1. **系统所有账户（System Owned Accounts）** - 存储数据并允许对交易进行签名

Token 账户代表每一种独立的同质化货币（USDC、USDT 等），包含该代币的基本信息，如供应量、小数位数、名称等。每个独立的 Token 账户都会生成一个不同的[关联代币账户（ATA）](https://www.alchemy.com/overviews/associated-token-account)。例如，如果你同时持有 USDC 和 USDT，你会分别拥有由 USDC 和 USDT 的 Token 账户创建的两个 ATA。

<ImageBlock
  src="https://media.alchemy.com/1703697445-solana-account-types-and-categories.png"
  alt="Solana 账户分类示意图：原生程序、程序账户和数据账户"
  width={1600}
  height={901}
  caption="Solana 账户类型与分类"
/>

## **Solana 账户的组成元素有哪些？**

**每个账户元素都是一组元数据，使协议能够轻松识别账户的类型及其他附加信息。** 元数据包括：

- **lamports** - 账户的 SOL 余额，以 lamport 计量，1 lamport 等于十亿分之一个 SOL 代币
- **owner** - 拥有该账户的程序地址
- **executable** - 一个布尔变量，用于指示该账户是否包含可执行代码
- **data** - 存储在账户中的原始数据字节数组，可以是存储变量，也可以是可执行代码
- **rent_epoch** - 表示该账户下一次需要支付租金的纪元（epoch）

**owner（所有者）**和 **holder（持有者）**的区别在于：所有者是控制该账户的程序，而持有者是持有该账户私钥的用户。例如，系统所有账户由 Solana 的原生系统程序拥有。

### **什么是 Solana 账户租金？**

每个账户都需要[**支付租金**](https://www.alchemy.com/overviews/how-to-calculate-rent-for-solana-programs)以使用区块链上的内存，这是一种预防措施，防止攻击者通过占用全部内存来堵塞网络。

要让所有用户满意，区块链必须包含某种经济激励机制。这对验证者尤为重要，他们提供硬件和计算能力来验证所有交易。验证者需要维护所有状态变化的可用副本，并因此获得租金作为回报。

账户如果维持相当于两年租金的最低余额，即可免除租金。否则，当该账户被某笔交易引用时，或者每个纪元（目前约相当于两天）都会被收取租金。如果一个账户中的 SOL 数量不足以达到租金豁免的最低要求，其数据将从链上被删除。

## **如何创建一个 Solana 账户**

在 Solana 上创建系统账户，正是每次用户创建新“钱包”时，[**Solana 钱包**](https://www.alchemy.com/overviews/solana-wallets)在后台所执行的操作。钱包通过生成一个位于 ED25519 椭圆曲线上的 64 字节密钥对来创建新账户。前 32 字节是私钥，当用户想要创建交易并与另一个账户或程序交互时会用到它。后 32 字节则是该钱包的公钥。

## **开始在 Solana 上构建**

账户模型是 Solana 协议用来组织数据的系统。账户可以被看作是存储桶，能够容纳从原始数据、代码和状态变量，到代币余额、NFT 等一切内容。账户主要分为两种类型：可执行账户和不可执行账户。

要开始使用 Alchemy 进行开发，立即[开通免费的 Solana 开发者账户](https://dashboard.alchemy.com/signup/?a=solana-account-model)！
