Solana 是一个高性能、低成本的公链平台,通过 PoH、Gulf Stream、Sealevel 等创新实现极高吞吐量。本节涵盖打包机制、账户模型和浏览器使用。
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
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 越多。
由于排班表提前确定,Solana 可以在 Leader 上岗前就把交易发给它:
| 对比维度 | 传统区块链(PoW/PoS) | Solana |
|---|---|---|
| 出块节点 | 即时选举或竞争 | 提前按权重排班 |
| 能否预测 Leader | 无法预测 | 可以预测 |
| 交易发送方式 | 广播至全网 mempool | 无 mempool,直接发给 Leader |
| 出块速度 | 较慢 | Leader 上岗时已收到交易 |
| 防抢跑 | 容易产生 MEV | 没有 mempool,减少前置交易风险 |
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: [] }"]
关键点:
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
Solana 与 EVM 有根本差异:程序(Program)不维护任何状态,所有状态都存储在账户中。
graph LR
subgraph "ETH 模式"
EC["智能合约<br/>= 代码 + 数据"]
end
subgraph "Solana 模式"
SP["Program<br/>= 只有代码"]
SA["Account<br/>= 只有数据"]
SP -->|"读写"| SA
end
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
}Solana 链上存储数据需要支付租金:
免租金额 = 租金速率 × 数据大小 × 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
新创建的账户 owner 默认为 System Program(1111...1111),相当于一张白纸:
CreateAccount 指令Assign 变成其他类型(Token/Stake 等)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 是一种标准的、唯一的、可推导的 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 | ETH |
|---|---|---|
| 账户类型 | 系统账户、程序账户、PDA | 外部账户、合约账户 |
| 数据存储 | 数据与程序分离 | 合约内有独立存储 |
| 账户创建 | 需通过系统程序显式创建 | 外部账户由私钥生成 |
| 调用方式 | 必须传入账户列表(显式声明) | 合约内部可随意调用 |
| 存储成本 | 租金机制(可免租) | 一次性 Gas 费 |
Solscan 是 Solana 上的区块浏览器(类似 Etherscan)。