聊聊 Nervos 的链下肯定性(Off-Chain Determinism)

在这里插入图片描述
Nervos 是个分层的多资产价值存储公链,是一套与其余公链彻底不一样的首创设计。Layer 1 底层专一于安全以及系统的强健性,将使用体验、性能等等交给 Layer 2 去处理。清晰的分工也造就了许多开发时不一样的体验以及权衡。在本文中,Nervos CKB 核心开发者 jjy 带你们来看看 Nervos 底层的重要特性——链下肯定性,是如何让整个系统更加安全并能够减小资源消耗,以及其中有什么样的权衡。安全

如何获取当前的区块高度

我已经反复的听到开发者抱怨说为何他们没有办法在他们的脚本(智能合约)中读取当前的区块高度这件事情了。网络

如每位开发者所知,从智能合约读取当前的区块高度是个以太坊以及其余使用 EVM 的区块链上的基本功能。那若是 CKB 真如咱们所说,是下一代的区块链,那为何他没办法作到这件上一代公链就能作到的事情呢?架构

嗯,我猜应该没啥人能够回答这个问题,CKB 核心团队也比较没有常常解释 CKB 的独特设计,这点我以为核心团队应该要作的更好。函数

因此我决定要写这篇文章来解释这个设计的权衡之处:为何咱们不能在智能合约(脚本)中读取当前的区块高度呢。性能

正确的方式

让咱们从验证 CKB 脚本如何读取区块高度的正确方式开始吧!区块链

个人观察是多数的开发者是透过请求区块高度来计算两个动做之间的区块时间,抽象地用术语来讲,一个用户在区块高度 X 时进行存款,而且在高度 Y 时取出。在取出这个动做发生以后,智能合约就须要去计算区块 X 到区块 Y 之间的区块数,而且根据用户的存款时间去发送奖励(注:例如流动性挖矿便是如此)或者作其余相似的事情。ui

以太坊上面能够直接的读取区块高度以及计算奖励。然而,在 CKB 中,咱们必须采用其余方法而不是直接读取区块高度:spa

  1. 咱们可使用 transaction valid since 的功能来限制取款交易,以确保至少在存款完后的 Z 个区块后,才会发生取款交易。可是,这样一来用户能够把取款的时间延长至区块 Z 以后 ,这在某些状况下可能不合适。

在这里插入图片描述

  1. 咱们能够采起两步取款来定位区块高度。首先第一步是借由 CKB syscalls 来读取用户存款的区块高度 X ,而且记录 X 这个高度在新的「准备取款 Cell」中;第二步就是咱们可使用 syscall 来读取准备取款的 cell Y 以及从这个 cell 的 data 字段来读取 X。

所以咱们同样能够计算出区块时间是 Y-X。
(译注:想一想 Nervos DAO 的设计就是如此)设计

链下肯定性

那么这样作的目的是什么呢?开发者显然更喜欢更简单、更直观的方法,那么为何 CKB 要使用如此困难的方法来完成简单的工做?!3d

这都是由于链下肯定性。让咱们先解释两个问题:以太坊合约的输入是什么?CKB 脚本的输入是什么?

若是咱们将合约(或脚本)视为函数「f」,那么咱们能够将智能合约的计算表示为如下形式:

在以太坊上:

output = f(tx, state tree, current blockchain)

在 CKB 上:

output = f(tx, deterministic blockchain)

在以太坊中,一个合约能够从三个输入中检索信息:tx、账户状态树和当前区块链状态。

例如,智能合约能够从区块链中读取当前区块高度和区块哈希。

在 CKB 中,咱们只容许脚本读取肯定性的输入。若是用户想从区块链读取信息,那么用户首先必须在交易中包含区块哈希。所以,脚本能够读取的全部信息都是肯定的。咱们称之为链下肯定性,这是CKB的一个基本特征。

优势

链下肯定性带来了一些好处,最重要的一点是,一旦咱们验证了一个交易,咱们就知道它会是有效的或无效的,由于输入输出都是肯定的,这个验证结果不依赖于区块链状态。

这个肯定性在 CKB 中引入了一个验证策略,就是在将交易推入内存池前咱们只验证一次。当咱们将交易打包到一个区块中时,咱们只须要检查交易输入是否仍然是未使用的,这和对交易进行完整的验证相比成本很小。

交易的这种链下肯定性不只绑定到一个节点;咱们能够保证一个交易是有效的,即便咱们经过 P2P 网络发送它。由于若是一个交易有效,那么它将永远有效,因此 CKB 只广播有效的交易到其余节点。若是恶意节点试图广播无效的交易,那么一旦没法验证恶意节点发送的交易,网络中的其余节点将当即禁止它。因为无效的交易不能广播到 CKB 网络中,因此 CKB 只将有效的交易打包到区块,我认为这是 CKB 的一个主要优点。

注意哦,这件事在以太坊中是不可行的,由于以太坊的交易并非链下肯定性的,一个交易可能在区块高度 42 上失败,即便它在区块高度 41 上是有效的。所以,咱们永远不知道失败的交易是恶意节点故意发送的,仍是由于区块链当前状态改变而失败的。

因此以太坊选择了另外一种方式,就是容许节点广播无效的消息并将其打包到块中。而后,该协议容许矿工经过向发送者的帐户收取最高费用来对失败的交易进行处罚。该机制旨在鼓励用户只发送有效的短信,以增强安全;但即便你是一个诚实的用户,您也可能因为意外地运行到一个无效的合约状态而发送一个失败的交易。( 当我试图将钱存入 Curve 时,我在一次失败的交易中损失了大约 50 美圆。)

在区块中只包含有效的交易,仍是在区块中包含失败的交易并惩罚发送者,这两种不一样的设计思想来自于对一个简单问题的不一样回答:咱们应该容许脚本(智能合约)读取当前区块吗?

Layer 1 强健性 vs 用户体验

根据个人理解,在 Layer 1 的强健性(鲁棒性)和用户体验之间,CKB 的设计明显选择了前者。

我相信这是一个正确的选择;Layer 1 区块链惟一重要的事情是提供强健性性和安全的服务。这种权衡并不意味着 CKB 不关心用户的体验。记住 CKB 的口号——为 Layer 2 建造 Layer 1。在这种状况下,Layer 1 是为了强健性,Layer 2 (以上)才是为了用户体验。

在分层架构中,大多数人会使用高层的技术,只有少数人须要从底层直接去访问。例如,在互联网中大多数用户使用 HTTP 或 WebSocket;不多有人使用 TCP 或 UDP,几乎没有人直接使用 IP。
在这里插入图片描述
译注:图片为译者添加,便于不了解互联网分层架构者参照这个互联网的分层图来了解做者所言。

Source:khan Academy
https://www.khanacademy.org/c...:the-internet/xcae6f4a7ff015e7d:the-internet-protocol-suite/a/the-internet-protocols

从智能合约开发者的角度来看,您可能会发现这种设计难以理解 ,可是若是你看一下分层的架构,你会发现 Nervos 的设计很是适合 Layer 1 区块链。

一旦 Nervos 的 Layer 2 设施启动,开发者将可以轻松访问 Layer 2 提供的功能,不只能用Layer 2 读取区块高度(这很简单),并且还可使用其余 Layer 2 更强大的功能(这里留给开发人员本身想象的空间)。

*原文连接:
https://talk.nervos.org/t/off...
原文做者:CKB 核心开发者 jjy
译者:Williams*

在这里插入图片描述

// 若是你喜欢 Nervos 而且喜欢开发
// 你能够关注并私信我哦~
if (you like Nervos && you like dev) {
    println("you can follow me and private letter for me~");
}
相关文章
相关标签/搜索