Skip to content

SOL #1:Solana 基础与工具使用

Solana 是一个高性能、低成本的公链平台,通过 PoH、Gulf Stream、Sealevel 等创新实现极高吞吐量。本节涵盖打包机制、账户模型和浏览器使用。


Solana 简介

Solana 专为去中心化应用和加密金融系统设计,通过一系列创新技术实现了极高的交易吞吐量和低延迟,是目前 Web3 生态中发展最快的区块链之一。


打包机制

核心概念

graph LR
    subgraph "时间结构"
        SLOT["Slot<br/>~400ms<br/>最小时间单位"] -->|"432,000 个"| EPOCH["Epoch<br/>~2 天"]
    end

    subgraph "角色"
        LEADER["Leader<br/>负责出块的验证者"]
        VALIDATOR["Validator<br/>验证并投票"]
    end

    EPOCH -->|"生成排班表"| LEADER
  • Slot:约 400ms,每个 Slot 指定一个 Leader 出块
  • Epoch:约 432,000 个 Slot(~2天),每个 Epoch 重新计算 Leader Schedule
  • Leader:在特定 Slot 内负责打包交易的验证者节点

Leader Schedule(出块排班表)

Leader Schedule 是预先生成的排班表,在 Epoch 开始前根据质押权重确定。

Epoch 12345
 ├── Slot 0  -> Leader A (50% stake)
 ├── Slot 1  -> Leader B (30% stake)
 ├── Slot 2  -> Leader A
 ├── Slot 3  -> Leader C (20% stake)
 ...
 └── Slot 431999 -> Leader Z

质押越多,分配到的 Slot 越多。

Leader 预测的优势

由于排班表提前确定,Solana 可以在 Leader 上岗前就把交易发给它:

对比维度传统区块链(PoW/PoS)Solana
出块节点即时选举或竞争提前按权重排班
能否预测 Leader无法预测可以预测
交易发送方式广播至全网 mempool无 mempool,直接发给 Leader
出块速度较慢Leader 上岗时已收到交易
防抢跑容易产生 MEV没有 mempool,减少前置交易风险

PoH(Proof of History)

PoH 是 Solana 独创的时间同步机制,用连续 SHA-256 哈希运算为事件提供全局一致的时间顺序

graph LR
    H0["hash₀<br/>初始值"] -->|"SHA256"| H1["hash₁"]
    H1 -->|"SHA256"| H2["hash₂"]
    H2 -->|"SHA256"| H3["hash₃"]
    H3 -->|"..."| H64["hash₆₄<br/>Tick 1"]
    H64 -->|"SHA256..."| H128["hash₁₂₈<br/>Tick 2"]

    H64 -.->|"绑定交易"| E1["Entry 1<br/>{ hash: hash₆₄,<br/>  transactions: [tx1, tx2] }"]
    H128 -.->|"空 Tick"| E2["Entry 2<br/>{ hash: hash₁₂₈,<br/>  transactions: [] }"]

关键点

  • 每个 hash 基于前一个生成,不可逆、不可伪造、不可插入
  • 每 64 次哈希为一个 Tick,64 个 Tick 为一个 Slot
  • 交易在特定 Tick 绑定到 Entry 中,确定时间点和顺序
  • 传统区块链"先共识后排序",Solana "先排序后共识"

完整出块流程

graph TB
    subgraph "1. 用户操作"
        U["用户连接钱包 → 发起交易 → 签名"]
    end

    subgraph "2. Gulf Stream(交易快速转发)"
        GS["RPC 节点将交易直接发给<br/>预测的下一任 Leader"]
    end

    subgraph "3. Block Building(区块构建)"
        BB1["接收交易"] --> BB2["验证签名"]
        BB2 --> BB3["执行交易"]
        BB3 --> BB4["写入 Entry"]
        BB4 --> BB5["PoH 加时间戳"]
        BB5 --> BB6["构成 Block"]
    end

    subgraph "4. Turbine(分片广播)"
        T["区块切分为 shred 碎片<br/>树状结构广播<br/>减少带宽压力"]
    end

    subgraph "5. Verification + Consensus"
        V["接收分片 → 验证 → 重组执行<br/>→ 投票确认 → rooted(最终确认)"]
    end

    U --> GS --> BB1
    BB6 --> T --> V

Account Model(账户模型)

核心设计理念

Solana 与 EVM 有根本差异:程序(Program)不维护任何状态,所有状态都存储在账户中。

graph LR
    subgraph "ETH 模式"
        EC["智能合约<br/>= 代码 + 数据"]
    end

    subgraph "Solana 模式"
        SP["Program<br/>= 只有代码"]
        SA["Account<br/>= 只有数据"]
        SP -->|"读写"| SA
    end

账户结构

rust
pub struct Account {
    pub lamports: u64,       // 余额(1 SOL = 10⁹ lamports)
    pub data: Vec<u8>,       // 可序列化的数据
    pub owner: Pubkey,       // 控制此账户的程序地址
    pub executable: bool,    // 是否为可执行程序
    pub rent_epoch: Epoch,   // 上次检查租金的 Epoch
}

Rent(租金)

Solana 链上存储数据需要支付租金:

  • 余额不足免租金额 → 系统周期性扣费
  • 余额归零 → 账户被回收销毁
  • Rent Exempt(免租):持有超过 2 年租金额度,则永久免租
免租金额 = 租金速率 × 数据大小 × 2 年

租金 ≠ 交易费。租金是为存储数据支付的,交易费是为处理指令支付的。

账户类型全景

graph TB
    SYS["System Account<br/>系统账户<br/>owner: 1111...1111"]

    SYS -->|"Assign 给<br/>Token Program"| TOKEN["Token Account<br/>代币账户"]
    SYS -->|"Assign 给<br/>Stake Program"| STAKE["Stake Account<br/>质押账户"]
    SYS -->|"部署程序"| PROG["Program Account<br/>程序账户<br/>executable: true"]

    PROG -->|"派生"| PDA["PDA Account<br/>程序派生地址<br/>无私钥"]

    PDA -->|"固定派生规则"| ATA["ATA Account<br/>关联代币账户<br/>PDA 的特例"]

    style PDA fill:#fff3e0
    style ATA fill:#e1f5fe

System Account(系统账户)

新创建的账户 owner 默认为 System Program(1111...1111),相当于一张白纸:

  • 存储 SOL:最基本的功能
  • 创建新账户:通过 CreateAccount 指令
  • 账户转化:通过 Assign 变成其他类型(Token/Stake 等)
  • 链上身份入口:所有钱包地址的初始状态

PDA(Program Derived Address)

PDA 是一种没有私钥的特殊地址,只能由特定程序控制。

graph LR
    SEEDS["Seeds<br/>(如 'GLOBAL STATE')"] --> FIND["findProgramAddress"]
    PID["Program ID"] --> FIND
    BUMP["Bump Seed<br/>(255 递减)"] --> FIND
    FIND --> PDA["PDA 地址<br/>不在 Ed25519 曲线上<br/>没有私钥"]

    style PDA fill:#fff3e0

为什么需要 PDA:Solana 程序不能持有私钥,需要一种"由程序控制、无私钥"的账户来存储数据或管理资源。

派生方式

PDA = findProgramAddress([seeds], programId)

Bump seed 从 255 递减尝试,直到生成的地址不在 Ed25519 曲线上。

ATA(Associated Token Account)

ATA 是一种标准的、唯一的、可推导的 Token 账户。ATA 本质就是一个 PDA

graph LR
    W["钱包地址"] --> DERIVE["findProgramAddress"]
    T["Token Program ID"] --> DERIVE
    M["Mint 地址<br/>(代币合约)"] --> DERIVE
    DERIVE --> ATA["ATA 地址<br/>一个钱包 + 一个 Token<br/>= 唯一 ATA"]
ATA = findProgramAddress(
  [wallet_address, token_program_id, mint_address],
  associated_token_program_id
)

Solana vs ETH 账户模型对比

对比维度SolanaETH
账户类型系统账户、程序账户、PDA外部账户、合约账户
数据存储数据与程序分离合约内有独立存储
账户创建需通过系统程序显式创建外部账户由私钥生成
调用方式必须传入账户列表(显式声明)合约内部可随意调用
存储成本租金机制(可免租)一次性 Gas 费

Solscan 浏览器

Solscan 是 Solana 上的区块浏览器(类似 Etherscan)。

交易查询

  • Overview:交易涉及的账户、费用、程序指令
  • Sol Balance Change:SOL 余额变化
  • Token Balance Change:Token(SPL Token)余额变化

账户查询

  • 钱包账户:Portfolio(持仓概览)
  • SPL Token 账户:代币余额和交易历史
  • Program 账户:Transaction 历史和 IDL(程序接口描述)

学习资源