Solana基础概念【上】

本文介绍了Solana比较重要的一些核心概念和基本原理,包括共识机制、POH、Leader选举、账户模型、Solana租金等等

参考文档: HackQuest社区:https://www.hackquest.io/zh Solana中文文档: https://www.solana-cn.com/SolanaDocumention/home.html

更多更及时的文章请访问作者博客 原文链接:https://leapwhale.com/zh/article/q84o82vf

Solana VS ETH

一、共识机制

Solana

  • Proof of History (PoH): PoH 是一种创新的时间记录机制,通过加密散列函数生成一个可验证的时间顺序,使得区块链中的事件可以按时间线性顺序排列。这减少了节点之间的时间同步需求,使得节点能够迅速达成共识,而无需等待整个网络确认。
  • Proof of Stake (PoS): 验证者需要抵押一定数量的 SOL 代币,持有更多代币的验证者有更高的概率被选中生成区块。PoS 提供了经济激励,确保验证者行为诚实。
  • PoH 确保区块的时间戳和顺序,PoS 则确保网络的安全性和抗攻击性,两者结合使得网络能够达到每秒数千笔交易处理速度

以太坊

  • 从 PoW 到 PoS 的转变: 以太坊 2.0 的升级(The Merge)将共识机制从能源密集的 PoW 转为 PoS,大幅降低了能耗。验证者通过锁定 ETH 参与共识,取代了矿工的角色,提升了网络的安全性和可持续性。

 

二、交易处理能力

Solana

  • 并行处理: 通过将交易分解为多个子集,利用不同的验证节点并行处理,提高了吞吐量。Solana 的架构支持高达每秒数千笔交易,平均出块时间为 400 毫秒,平均每秒 2000+ 笔交易,在高负载时保持较低的交易费用。
  • 低延迟和低费用: Solana 的架构设计使其能够快速确认交易,通常在一秒以内完成。即使在高负载下,交易费用仍保持低廉,适合需要高频交易的应用。

以太坊

  • 串行执行: 以太坊的智能合约在虚拟机(EVM)中按顺序执行,每笔交易必须等待前一笔完成才能开始。虽然这种方式确保了状态的一致性,但也限制了以太坊吞吐量长期维持在每秒15笔~30笔,以牺牲性能换来安全性和一致性。
  • Layer 2 和 Rollup: Layer 2 解决方案通过将大量交易在链下处理,然后将结果提交到主链,显著提高了交易速度和降低了成本。Rollup 是其中一种常见的技术,能够将数百笔交易合并为一个批次,能够将燃料费减少多达100倍。

 

三、交易费用(Gas费)

Solana它的交易费用是根据交易的复杂度和大小动态计算的,这意味着,交易费用会根据交易的执行成本而变化,而不是根据网络上的交易量变化。Solana 的平均交易费用通常低于 0.01 美元,平均为 0.00025 美元,这使得进行小额交易更具成本效益。

以太坊 的交易费用因网络拥堵而波动,这是一种纯粹的市场机制,网络中交易拥堵情况下你的交易要想被确认,就需要支付高昂的手续费。目前一笔转账交易的手续费大概在 1 ~ 10 美元左右。

 

四、智能合约

Solana中一切皆账户,它的智能合约(Solana 中称之为程序program,后续也统一使用“程序”这一术语)也是账户,但细分为可执行账户数据账户,前者存储程序的代码,用来执行特定的逻辑,后者存储状态,即程序运行时的数据。这种分离的模式,使得程序的升级更加简单,因为程序本身无状态,可以直接升级为新的代码逻辑。

以太坊 的智能合约本身就包含了合约的逻辑代码,以及状态数据。因此合约部署之后,就不支持直接的升级,只能通过代理的方式间接升级,即重新部署一套合约代码,生成新的合约地址,代理再指向这个新的合约地址。

 

五、账户

Solana中一切皆账户,它的账户就像一个容器(或者电脑中的文件夹),可以包含程序代码、状态数据以及账户元数据。按照功能可划分为可执行账户数据账户,前者为存储程序代码的账户,也称为程序账户。后者包括普通用户账户和其他非程序账户,这些账户存储了用户的余额、交易历史和其他相关数据,但它们本身不包含程序代码。对于熟悉以太坊账户的同学来说,这种划分方式也许有点奇怪,不过随着了解的深入,就会认识到 Solana 的单一账户模型,使得多个交易能够并行处理,这正是 Solana 高性能的基础。

以太坊 分为EOA账户智能合约,前者是普通用户在以太坊网络中的账户,用于存储以太币(ETH)和进行交易。后者是包含智能合约代码和状态的账户,这些账户由合约创建并部署在以太坊区块链上。通过这两种账户类型的结合,以太坊提供了一个灵活且功能强大的去中心化应用开发平台。

 

共识机制

PoH 工作流程

Proof of History (PoH) 是 Solana 区块链的核心创新之一,它为区块链提供了一个去中心化的时间源。PoH 本质上是一个高频可验证延迟函数 (VDF),它能够创建历史记录,证明某个事件发生在特定时刻之前或之后。

我们看一个简化版的 PoH 工作流程,从一个随机值开始,运行 hash 函数,并将输出(output)作为输入(input)再次运行该函数。记录函数执行的次数(index)以及每次调用的结果(output)。次数,提供了顺序和时间两个维度的支持;将输出作为输入,依次头尾相连,形成了一条完整的证据链。

随机值的选择,可以选择纽约时报当天的标题,或者其他的事实。

image-20241027152102800

 

hashN 代表实际的 Hash 输出,Solana 中每个交易都与前一笔交易的哈希相连接,形成一个由交易构成的链,当一定数量的交易都被执行并构成了PoH 链后,它们被打包到一个区块(slot)中。

image-20241027152111317

 

只要选择的哈希函数是抗碰撞的,这个哈希集和就只能被单线程顺序计算出来。这满足了在 index 为 300 时,如果不通过算法实际运行 300 次,无法获得这样的结果的设定。

因此,我们可以从数据结构中推测出从 index 0 到 index 300 真实的过去的时间。这样以来,在网络中尽管每个节点的时间戳可能会有不一致,但是我们通过 hash 的次数(比如300),就变相的替代了时间,于是网络中有了全局一致的时间钟,并保持了交易的顺序。

 

PoH 的特性和优势

  1. 去中心化时间戳: PoH 提供了一个不依赖中心化时间服务器的时间戳机制。
  2. 顺序保证: 由于每个事件都嵌入到连续的哈希链中,事件的顺序得到了密码学保证。
  3. 高效验证: 验证者可以并行验证 PoH 链,大大提高了验证速度。
  4. 减少网络开销: 节点间不需要频繁同步时间,减少了网络通信。
  5. 提高交易处理速度: PoH 允许 Solana 在不牺牲安全性的情况下实现高吞吐量。

 

PoH 的广播和验证

  1. 区块生成: Leader 节点生成包含 PoH 序列和交易的区块。
  2. 并行验证: 其他节点接收区块后,可以将 PoH 序列分割成多个部分,在 GPU 上并行验证。
  3. 快速共识: 由于 PoH 提供了时间和顺序保证,节点可以快速就区块的有效性达成共识。
  4. 动态调整: Solana 可以根据网络条件动态调整 PoH 的哈希频率,以适应不同的硬件能力。

 

PoH 应用

假设我们正在观察 Solana 网络中的一个时间段,我们将看到 PoH 是如何与其他组件协同工作的。

1. PoH 生成器启动

  • 假设当前的 PoH 生成器(通常是当前的 leader 节点)开始工作。
  • 初始哈希值:0x1234...(这可能来自之前的状态或预定义的起始点)

2. PoH 序列生成

PoH 生成器开始连续进行哈希操作:

Index 0: Hash(0x1234...) = 0xabcd...
Index 1: Hash(0xabcd...) = 0xef01...
Index 2: Hash(0xef01...) = 0x2345...
...

3. 交易到达

  • 在 Index 50 时,一个交易 T1 到达:"Alice 发送 5 SOL 给 Bob"
  • T1 的哈希值为 0x7890...

4. 交易嵌入 PoH

PoH 生成器将 T1 嵌入到 PoH 序列中:

Index 50: Hash(0x...|| 0x7890...) = 0xdead...
Index 51: Hash(0xdead...) = 0xbeef...
...

5. 继续生成 PoH 和处理交易

  • 更多的交易陆续到达并被嵌入 PoH 序列
  • 例如,在 Index 100 嵌入 T2,Index 150 嵌入 T3,等等

6. 形成区块

  • 假设每 200 个 PoH 条目形成一个区块
  • 当达到 Index 200 时,当前的 PoH 序列和所有嵌入的交易被打包成一个区块

7. 区块广播和验证

  • Leader 节点将这个区块广播给其他验证者节点
  • 验证者接收到区块后,可以并行验证 PoH 序列:
    • 验证者 1 检查 Index 0-66
    • 验证者 2 检查 Index 67-133
    • 验证者 3 检查 Index 134-200

8. 共识和确认

  • 验证者快速确认 PoH 序列的正确性
  • 他们也验证嵌入的交易(T1, T2, T3 等)是否有效
  • 一旦大多数验证者确认,区块被添加到链上

9. Leader 轮换

  • 基于 PoH 序列,网络预先知道下一个 leader 是谁
  • 例如,如果每 1000 个 PoH 条目轮换一次 leader,那么在 Index 1000 时,新的 leader 接管 PoH 生成

10. 时间估算

  • 假设每次哈希操作平均需要 0.1 毫秒
  • 那么 200 个 PoH 条目(一个区块)大约代表 20 毫秒的真实时间
  • 网络可以据此估算交易的确切时间戳

 

实际应用中的优势

  1. 高吞吐量:由于 PoH 提供了时间和顺序保证,Solana 可以并行处理大量交易。
  2. 低延迟:交易几乎立即被嵌入 PoH,提供近乎实时的确认。
  3. 可预测的 leader 选择:网络总是知道谁是下一个 leader,减少了切换开销。
  4. 快速终结性:由于快速的验证过程,交易可以在几秒内达到最终确认。
  5. 精确的时间戳:每个交易都有一个与 PoH 序列关联的精确时间戳。

 

POS 工作流程

先来了解下在 Solana的系统架构中最重要的两种角色:Leader(出块者)和 Validator(验证者)。两者实际上都是质押了 SOL 代币的全节点,只是在不同的出块周期内,Leader 会由不同的全节点来充当,而没有当选 Leader 的全节点会成为 Validator。 所以在选择验证者方面, Solana 采用的是 PoS(权益证明)机制,验证者是通过抵押一定数量的代币来参与网络交易的验证的,持有更多代币的验证者有更大的机会被选中生成新的区块。

image-20241027151758993

 

1.用户发起交易后,会被客户端直接转发给 Leader 节点,或者先被普通节点接收,再立刻转发给 Leader;

2.出块者 Leader 接收网络内全部的待处理交易,一边执行,一边给交易指令排序,制成交易序列(类似区块)。每隔一段时间,Leader 会把排好的交易序列发送给 Validator 验证节点;

3.Validator 按照交易序列(区块)给定的顺序执行交易,产生相应的状态信息State(执行交易会改变节点的状态,比如改变某些账户的余额);

4.每发送 N 个交易序列,Leader 会定期公开本地的状态 State,Validator会将其与自己的 State 作对比,给出 肯定/否定 的投票。这一步就类似于以太坊2.0或其他POS公链里的“检查点”。

5.如果在规定时间内,Leader收集到占全网 2/3 质押权重的节点们给出的肯定票,则此前发布的交易序列和状态 State 就被敲定,“检查点”通过,相当于区块完成最终确认 Finality;

6.一般而言,给出肯定票的 Validator 节点与出块者 Leader 所执行的交易、执行后的状态都是相同的,数据会同步。

 

Leader 选举

在 Solana 的共识协议中,有 Epoch(纪元)和Slot(间隔)两大时间单位。每个 Slot 约为0.4\~0.8秒,相当于一个区块的时间间隔。而每个Epoch周期包含43.2万个Slot(区块),长达2\~4天。每过4个 Slot(出块周期),Leader节点就会进行一次变更。

image-20241027153707784

 

Solana 使用一种称为 Tower BFT(一种改进的实用拜占庭容错算法)的共识机制,结合 Proof of Stake (PoS) 和 Proof of History (PoH) 来选择和轮换 leader。

  1. Leader 调度:
    • Solana 网络预先确定一个 leader 调度表,通常覆盖未来几天的时间。
    • 这个调度是基于验证者的质押量(stake)按比例分配的。
  2. Leader 轮换:
    • Leader 角色在验证者之间频繁轮换,通常每 400 毫秒(一个 "slot")就会切换。
    • 在一个 "epoch"(大约 2-3 天)内,每个验证者都有机会成为 leader。
  3. 单一 Leader:
    • 在任何给定的时刻,只有一个节点作为 leader
    • Leader 负责生成 PoH 序列和打包交易到区块。
  4. Leader 的职责:
    • 生成 PoH 序列
    • 接收交易并将其打包到区块
    • 广播区块给其他验证者

 

在每个新的Epoch周期开始时,Solana网络会按照各节点的质押权重进行抽选,组成一个出块者Leader轮换名单,“钦定”了未来不同时刻的出块者。也就是说出块者会提前获知他们成为出块者。 具体而言,究竟如何指定 Leader 会考虑诸多因素,比如:

1.质押的代币数量: 在 PoS 中,质押的代币数量是一个关键的考虑因素。Validator 通常倾向于选择质押数量较大的节点,因为这增加了节点被选中为区块生产者的机会。这也有助于确保网络由具有足够利益参与的节点维护。

2.节点的性能: Validator 的节点性能是另一个关键因素。高性能的节点能够更快速地验证和打包交易,有助于维持网络的高吞吐量。Validator 可能会选择性能较好的节点以提高整个网络的效率。

3.网络延迟: Validator 可能会考虑节点之间的网络延迟。选择网络延迟较低的节点有助于减少区块的传播时间,从而提高网络的实时性。

4.节点的可用性: Validator 会关注节点的可用性,确保它们能够稳定运行而不容易出现故障。可靠的节点能够为网络提供更稳定的服务。

 

去中心化考虑

虽然 Solana 在任何时刻只有一个 leader,但这并不意味着系统是中心化的。以下几点说明了 Solana 如何维护去中心化:

  1. 频繁轮换:
    • Leader 角色快速轮换(每 400 毫秒)大大降低了单一实体控制网络的风险。
  2. 基于质押的概率选择:
    • 成为 leader 的机会与验证者的质押量成正比,鼓励更多参与者加入网络。
  3. 大量验证者:
    • Solana 网络有数百个活跃验证者,确保了足够的去中心化程度。
  4. 验证者的持续参与:
    • 即使不是 leader,其他验证者也在持续验证交易和区块,维护网络安全。
  5. 惩罚机制:
    • 对于行为不当的验证者(包括 leader),存在削减质押的惩罚机制。
  6. 开放参与:
    • 任何人只要满足硬件要求并质押足够的 SOL,都可以成为验证者。
  7. 治理决策:
    • 网络参数和升级通过去中心化的治理过程决定,而不是由单一实体控制。

 

Solana 要实现的目标是选择一组合适的 Leader,确保网络的安全性、效率和公平性。通过综合考虑这些因素,Solana 能够做出最佳的区块生产决策,从而推动网络的正常运行。

 

小结

现在在了解了基础的细节后,让我们来看看 Solana 的网络整体是如何通过 PoH 和 PoS 运作的:

1.生成交易: 用户创建并广播交易,包含交易的详细信息和数字签名。

2.PoH 链上的排序: 交易的哈希通过数字签名连接到 PoH 链上。由于 PoH 链是有序的,交易也就被排序了。

3.Validator 验证: Validator 负责验证交易的有效性,并选择哪些交易将包含在下一个区块中。Validator 的选择可能基于质押的代币数量、验证者的性能等因素。

4.交易打包成区块: Validator 选择的交易被打包成一个区块,其中包括一个特殊的块生产交易,它包含了当前 PoH 链的哈希以及其他信息。

5.区块传播和确认: 区块广播到整个网络,其他节点验证并确认区块的有效性。确认后,区块和其中包含的交易就被添加到整个区块链中。

通过这个过程,Solana 通过 PoH 链的时间有序性和 PoS 的节点验证机制,实现了交易的流转和整个区块链的更新。这样的设计使得 Solana 平均出块时间被压缩至 400 毫秒,且无需 Layer2 即拥有较高速度,手续费亦可忽略不计。

 

账户模型

每个帐户都可以通过其唯一地址进行识别,地址以Ed25519算法生成32个字节的公钥来表示。

在以太坊中,我们将代码与数据、状态直接存储在智能合约中。而 Solana 账户最大的不同就是将两者分开存放在不同的账户上。所以 Solana 账户又分为程序账户数据账户

  • 程序账户(可执行账户):存储不可变的数据,主要用于存储程序的代码(BPF 字节码)。
  • 数据账户(不可执行账户):存储可变的数据,主要用于存储程序的状态。

说明:Solana中的智能合约并不叫“智能合约”,而是“程序program”,尽管它们代表的是相似的概念。为了避免混淆,后续我们将统一使用“程序”这一术语。

 

账户分类

基本账户

  • 数据账户:用于存储各种数据,如用户的 SOL 余额、代币余额、NFT 元数据或游戏状态信息。
  • 程序账户:存储可执行代码,类似于智能合约。一旦部署,这些程序就变成不可变的,可以被其他账户或程序调用执行。
  • 原生账户:这是 Solana 内置的特殊账户,用于执行系统级的功能,如创建新账户或转账 SOL。

 

特殊账户类型

  • PDA(Program Derived Addresses):程序派生地址。PDA 是由程序确定性生成的地址,不与任何私钥相关联。该类账户存储程序的状态,即程序执行过程中存储的数据,跟以太坊的状态是一个概念。
  • ATA(Associated Token Account)账户:关联账户。它是用户与特定的 SPL(Solana Program Library)Token 代币关联的账户,地址是用户主钱包和代币铸造地址的派生,主要作用是允许用户方便管理他们持有的代币。

 

Solana 链上程序是只读或无状态的,即程序的账户(可执行账户)只存储代码,不存储任何状态,程序会把状态存储在其他独立的账户(不可执行账户)中。如果一个程序账户是一个数据账户的所有者,那么它就可以改变数据账户中的状态。

要点

  • 帐户最多可以存储10MB的数据,这些数据主要包含由可执行程序代码或程序状态。
  • 帐户需要以SOL为单位的租赁押金,与存储的数据量成正比,该押金在帐户关闭时可全额退还。
  • 每个帐户都有一个程序“所有者”。只有帐户所有者的程序才能修改其数据或扣除其lamport余额。但是,任何人都可以增加余额。
  • 程序(智能合约)是存储可执行代码的无状态帐户。
  • 数据帐户由程序创建,用于存储和管理程序状态。
  • 本机程序是Solana运行时附带的内置程序。
  • Sysvar帐户是存储网络群集状态的特殊帐户。

 

账户定义

帐户的最大大小为10MB(10兆字节),存储在 Solana 上每个帐户上的数据具有以下结构,称为AccountInfo

image-20241027154916018

对于每个帐户AccountInfo都包含以下字段:

  • lamports: 表示账户余额,lamport 是 Solana 中的基本货币单位,类似于以太坊的wei。
  • data:表示存储的内容,这是一个字节数组,可以包含任意类型的数据,如程序的状态、用户资产信息,以及存储程序的字节码等。
  • owner:表示拥有或管理该账户的程序的公钥。这表示了哪个程序有权对该账户进行操作。如果账户包含的数据是可执行的,那么owner表示加载该账户的程序。
  • executable:表示是否可执行,如果为true,表示该账户中的数据可以被执行,是程序账户。如果为false,表示该账户用于存储普通的数据,而不是可执行代码。
  • rent_epoch:表示下一次该账户将被扣除租金的时期。Solana使用租金机制来防止账户被无限期占用而不使用,避免状态膨胀。

作为Solana账户模型的关键部分,Solana 上的每个账户都有一个指定的“所有者”,特别是一个程序。只有被指定为账户所有者的程序才能修改账户上存储的数据或扣除lamport余额。需要注意的是,虽然只有所有者可以扣除余额,但任何人都可以增加余额。

 

租金机制

Solana 引入了租金概念来管理账户存储和网络资源使用。租金与交易费用不同。用户支付租金以将数据存储在 Solana 区块链上。而交易费用是为了处理网络上的指令而支付的。

  1. 租金的目的:
    • 防止网络存储无限增长
    • 激励用户清理不再需要的账户
    • 补偿验证者存储和处理数据的成本
  2. 租金计算:
    • 基于账户大小(以字节为单位)
    • 当前租金率:每字节每年 0.00000348 SOL(可能会随时间调整)
  3. 租金豁免:
    • 账户余额超过两年租金的账户可以免租金
    • 例如,如果账户大小为 1KB,约需 0.0035 SOL 来获得租金豁免
  4. 租金收取:
    • 每个 epoch(约 2-3 天)收取一次
    • 从账户余额中扣除
  5. 账户关闭:
    • 如果账户余额不足以支付租金,账户可能被关闭
    • 关闭的账户数据将被删除,剩余余额返回到一个指定账户

 

PDA

在Solana区块链中,PDA指的是“程序派生地址”(Program Derived Address)。这是一种特殊类型的地址,由 Solana 的程序生成,而不是由用户的私钥直接派生。PDA的主要目的是允许程序拥有和控制某些数据或资产,而不需要传统的私钥签名

 

为什么需要 PDA?

在区块链中,你需要一个私钥来证明你拥有一个公钥的所有权,同时你才能签字同意这个账户的转账请求。但如果这个账户的所有者不是一个人而是一个去中心化程序,那么把私钥放在这个程序上就不是一个好主意,因为所有程序代码都在链上都是公开的,如果所有人都能看到你的私钥,那么人们就能进行一些恶意操作,比如偷走你的代币。这时我们就需要一个没有私钥的 PDA。 这样程序不需要私钥就能对一个地址进行签名操作

 

私钥、公钥与助记词

Solana 和以太坊一样,有私钥、公钥、助记词三种东西。私钥是私自保管不可示人的,当我们授权某一笔交易时,我们需要通过私钥签名并“授权”该交易。私钥是一串乱码,不好记,与之对应有一串助记词。助记词可以通过算法推出私钥,所以实际上我们在使用钱包时,只要记住助记词。而我们可以通过加密算法从私钥推算出公钥。公钥是可以展示给别人看的,别人通过你的公钥给你转账,同时公钥也是程序的地址,也叫 program_id

要注意的是我们只能从助记词通过加密算法推算出私钥,从私钥推算出公钥,而无法反向从公钥推算出私钥,从私钥推算出助记词。否则我们所有加密地址中的代币都可以被任何人控制了。这其中的过程通过ECDSA算法进行计算,如果希望了解具体的原理可以先从了解 ECDSA算法开始。但是理解 PDA 账户可以不必这么深入,让我们先把这个过程进行一个简化。

image-20241027161341441

 

如上图所示(这是一个简化的图示),每一个 X 轴私钥会在曲线上对应一个 Y轴公钥,但是 Q 点的 公钥没有对应任何一个 X 轴上的私钥。那么这就意味着这个公钥没有对应的私钥! 这意味着这个公钥不是从私钥派生/衍生(Secret Key Derived)出来的。

这就是 PDA 的原理,“程序派生地址”(Program Derived Address)是没有对应的私钥的,它是由一个程序的program_id和seed派生/衍生出来的,这也是为什么它被称之为“程序派生地址”(Program Derived Address)。有时候我们通过 program_id 和 seed 获得的公钥正好有对应的私钥,那么这种情况下我们就需要重新生成一个公钥,通常是在我们的 program_id 和 seed 之外再加上一个数字(这个数字有个专有名词叫 bump),这个数字从 255 开始,依次往下,直到生成的公钥没有私钥为止。

作者:加密鲸拓 版权:此文章版权归 加密鲸拓 所有,如有转载,请注明出处! https://leapwhale.com/zh

点赞 4
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
加密鲸拓
加密鲸拓
现Golang 后台开发,Web3 技术爱好者,承接各类合作,欢迎联系