智能合约:好,坏和懒惰

为什么私有区块链不应该急于运行代码

我不喜欢“智能合约”一词。 首先,它被许多人用于许多不同的事物,我们可能应该完全禁止使用它。 例如,第一个已知参考文献来自1997年,当时尼克·萨博(Nick Szabo)用它来描述那些 改变他们的行为 根据一些数据。 最近,该术语正好相反:用于描述区块链上的计算 受到影响 受到天气等外部事件的影响。 现在,让我们将这两个含义放在一起。

我想在这里将重点放在“智能合约”上,即在区块链上进行的通用计算。 这个意思是由 以太坊 ,谁的 白皮书 副标题为“下一代智能合约和去中心化应用平台”。 由于以太坊受到关注,这种含义已成为主流,银行(及其他机构)正在努力研究智能合约概念证明。 当然,由于我们谈论的是受监管的金融机构,所以这主要是在私有或经许可的区块链的背景下进行的,这些区块链的参与者数量有限。 由于现在的原因 完全了解,所有的天才公共区块链都不适合企业用途。

那么私有区块链中智能合约的未来光明吗? 好吧,有点,但不是真的。 您看,问题是:

在私有区块链中,智能合约将四个好主意与一个坏主意结合在一起。

那么什么是好主意呢? (a)将业务逻辑表示为计算机程序;(b)将触发该逻辑的事件表示为消息,作为对程序的消息;(c)使用数字签名来证明谁发送了该消息;以及(d)将以上所有内容放在一起区块链

和坏人? 为每个区块链节点上的每个消息执行每个程序。 换句话说, 执行 所有程序中,区块链的工作,而不仅仅是将其用作 存储 用于程序和消息。 然而,这种全球执行是开发以太坊的全部原因。

如果您知道 计算的确定性,了解 停顿问题,并了解如何 数据依赖 防止并发,那么您可能已经被说服了。 但是如果没有的话,那就给自己喝杯咖啡,深吸一口气,然后跟着我走到兔子洞里…

了解以太坊

为了理解以太坊风格的智能合约,我们需要从比特币开始,这是第一个(也是最受欢迎的)公共区块链。 比特币区块链最初仅用于一件事:将比特币从一个所有者转移到另一个所有者。 但是一旦启动并运行,人们便开始将“元数据”嵌入事务中以用于其他目的,例如 数字资产 和 公证。 虽然一些比特币 战斗 这些应用程序 官方机制 于2014年XNUMX月引入元数据 成倍增长 自从。

除了建立在比特币区块链上的项目外,还开发并启动了许多下一代公共区块链,例如 NXT, Bitshares, 纹波恒星。 这些是从头开始设计的,旨在支持更广泛的活动,例如用户创建的资产,分散交易和抵押借款。 根据开发人员的决定,这些区块链中的每一个都具有不同的功能集,并且在添加新功能时必须由所有用户升级。 事情开始变得相当混乱。

参与了其中一些项目之后, Vitalik Buterin 提出了一个简单但出色的问题:为什么不使用可以编程的单个公共区块链来代替许多专用的区块链 无论我们想要什么? 这种über区块链将无限扩展,仅受使用它的人的想象力的限制。 这个强大的想法几乎一致地使加密货币爱好者的世界信服。 因此, 18万美元的众筹资金 以太坊兴奋地诞生了。

以太坊是一个新的公共区块链,具有名为“ ether”的关联加密货币,例如 数以百计 在它之前。 但是与其他区块链不同,以太坊使任何人都可以在区块链内部创建“合约”。 合同是具有相关微型数据库的计算机程序, 只能由拥有它的程序修改。 如果区块链用户想要更改数据库,则必须向其合同发送经过数字签名的消息。 合同中的代码检查此消息,以确定是否以及如何做出反应。 (这个 ”封装“代码和数据”也是 面向对象的 编程)。

以太坊合约可以用几种新的编程语言之一编写,例如 密实度。 像大多数编程语言一样,这些是 图灵完成,表示它们可以表示任何通用计算。 图灵完整语言的主要功能是 循环结构,它会重复执行操作,直到满足某些条件为止。 例如,可以使用循环将数字从一打印到一百万,而无需一百万行代码。 为了提高效率,为以太坊编写的程序是 编译 (即转换为)更紧凑 字节码 在存储在链上之前。 以太坊节点然后在一个 虚拟机,本质上是一台在真实计算机中运行的模拟计算机。

在区块链上创建以太坊合约时,它会设置其数据库的初始状态。 然后停止,礼貌地等待直到被调用为止。 当区块链(或其他合约)的用户在交易中向其发送消息时,合约立即生效。 根据其中的代码,它可以标识消息的来源,触发其他合同,修改其数据库和/或将响应发送回调用方。 所有这些步骤都是独立执行的 在网络中的每个节点上,结果相同。

举个例子,一个简单的以太坊 次货币合约 维护特定资产的用户余额数据库。 如果它收到一条将资金从Alice转移到Bob的消息,它将(a)检查消息是由Alice签名的,(b)检查Alice是否有足够的资金,(c)将资金从Alice的资金转移到数据库中Bob的帐户,以及(d)回答操作成功。 当然,我们不需要以太坊,因为一个简单的比特币风格的区块链 本机资产支持 可以做同样的事情。 以太坊真正适用于复杂的多阶段业务逻辑,例如众筹,分散交易和分层治理结构。 至少, 诺言.

将它分解

现在我们知道以太坊智能合约的工作原理,我们可以将其分解为五个组成部分:

  1. 将业务逻辑表示为计算机程序。
  2. 将触发该逻辑的事件表示为程序消息。
  3. 使用数字签名来证明谁发送了邮件。
  4. 将程序,消息和签名放在区块链上。
  5. 为每个节点上的每个消息执行每个程序。

重复我一开始所说的话,我相信第1至第4部分是非常好的主意。 让我们从前两个开始(顺便说一句, 不新鲜)。 与可以具有 解释的差异, 计算机程序是明确的。 对于任何使用定义良好的编程语言编写的程序,相同的输入始终会导致相同的输出。 因此,如果将某些业务逻辑表示为计算机程序,并且将事件表示为该程序的消息,则业务结果将一成不变。 确实,计算的这种确定性使得 随机性 计算机科学中的一个棘手问题,即使Google的极客也可以 弄错了.

那么数字签名和区块链呢? 这些避免了需要中央权威来确定发送哪些消息,以什么顺序发送以及由谁发送的消息。 而是每个参与者创建一对 私钥和公钥,并分配其公钥 一旦 给其他参与者。 之后,他们 签署 每个消息及其私钥,然后在网络上分发该消息。 然后,其他参与者只能使用发件人的公共密钥来验证邮件的来源。 这是聪明的加密资料。 最后,通过将程序和签名的消息放在区块链上,我们可以确保每个参与者对谁在何时何地执行操作具有相同的看法。 结合确定性计算,这意味着 参与者不能不同意最终的业务成果.

但是最后一个想法是,每个节点为每个消息执行每个程序的最后一个想法是什么? 在这里,我们进入有争议的部分。 因为虽然可以很好地执行此全局执行,但也没有必要。 因为计算是确定性的,所以程序是由一个节点,每个节点还是某个外部进程执行都没有区别。 无论是实时,按需还是10年后发生,也都没有关系。 计算结果将始终相同。 如果由于某种原因不是这种情况,那只能是由于 区块链软件或网络中的问题.

计算的麻烦

如果在哪里进行计算都没关系,为什么 不能 到处都可以吗? 好吧,事实证明 计算机程序是无法预测的。 无论他们看上去多么单纯,他们都可能需要很长时间才能运行。 有时,它们会永远运行下去。 考虑以下经典示例(称为 LCG):

  1. x 到您选择的一位数字
  2. y123 * x + 567
  3. x 到的最后两位数 y,即 y模100
  4. If x 超过 2 然后回到步骤2
  5. 否则停止并输出的值 x

很简单,对不对? 所以这是一个问题:这个程序能完成吗? 还是会卡在 无限循环? 不太确定? 好吧,让我摆脱困境: 它取决于x的初始值.

If x is 0, 1, 2, 5, 6, 7 or 8,程序会很快停止。 但是如果 x is 3, 4 or 9,它会无限期地继续下去。 不相信我吗打开Excel并自己尝试(您将需要“ MOD”功能)。

如果您仅通过查看代码就无法预测到这一点,那就不要太难过。 因为这不仅对人来说很难, 电脑是不可能的。 确定给定程序是否将完成执行的问题称为 停顿问题。 在1936年, 阿兰·图灵,“完成” 在模仿游戏 声名远扬,证明了一般情况无法解决。 除非有少量异常,否则这是找出程序是否将完成运行的唯一方法 是运行它的时间,那可能是永远的。

对于那些我们希望没有生活的人 死亡蓝屏旋转沙滩球,这很不方便。 但是,只要我们与之兼容,大多数软件大多数时候就可以正常运行。 如果不是这样,现代的操作系统(例如Windows)可以让我们手动终止程序,从而防止代码失控。 但是,在以太坊这样的区块链上不能做同样的事情。 如果我们允许各个节点随意终止计算,则不同的节点会对这些计算的结果有不同的看法。 换句话说, 网络共识会破裂。 那么什么是区块链呢?

以太坊的答案是基于交易费的,也称为 。 每笔交易的发送者 国家 对于它触发的计算,这笔款项是由矿工收取的,矿工在一个区块中对其进行确认。 更准确地说,每笔以太坊交易都预先说明了发件人的“以太”可以花多少来处理它。 随着合同在以太坊虚拟机中逐步执行,费用逐渐支出。 如果事务在完成执行之前用完了所有费用,则所有数据库更改都将还原,并且不会退还该费用。 如果交易成功完成,则剩余的费用将退还给其发送者。 通过这种方式,交易只会使网络负担到他们愿意为此付出的程度。 无疑,这是一种精巧的经济解决方案,但是 它需要本机区块链货币才能工作.

智能合约与并发

如果天然气可以防止失控计算,那么智能合约是否可以通过? 嗯,不是那么快,因为智能合约还有另一个问题我们需要讨论:

智能合约无法很好地实现高交易吞吐量.

并发 是计算机体系结构中最基本的问题之一。 如果系统允许多个进程同时且以任何顺序发生,则该系统具有良好的并发性。 并发系统可以通过优化利用诸如以下技术来减少延迟并提高整体吞吐量 工艺调度, 并行处理资料分割。 Google就是这样搜寻的 30万亿 网页几乎 100,000倍 每秒。

在任何计算机系统中,一组事务只能在彼此不依赖或不相互干扰的情况下同时处理。 否则,不同的处理顺序可能导致完全不同的结果。 现在回想一下,智能合约具有关联的数据库,并且它执行包括循环在内的通用计算。 这意味着,响应特定消息,智能合约可以读取或写入其数据库中的每条信息。 例如,如果它正在管理子货币,则可能决定向该货币的每个持有人支付一定的利息。 当然,情况并非总是如此。 但是问题是:在为特定消息运行合同程序之前,区块链节点 无法预测 它将使用合同数据库的哪个子集。 也无法判断该子集在不同情况下是否可能有所不同。 如果一个合同可以触发其他任何合同,则此问题将扩展到 每个合同的每个数据库的全部内容。 因此,必须将每笔交易都视为可能相互干扰。 用数据库术语来说,每个事务都需要一个全局锁。

现在考虑一下一个区块链节点所处的世界。由于没有集中管理的队列,所以交易来自不同的对等点,没有特定的顺序。 此外,以12秒(以太坊)和10分钟(比特币)之间的平均间隔出现了一个新区块,以特定顺序确认了一组交易。 一个节点可能已经看到了区块的大多数事务,但是有些可能是新的。 无论哪种方式,区块中的交易顺序都不太可能反映它们单独到达的顺序。 由于交易顺序可能会影响结果,因此这意味着 在确认区块链中的订单之前无法处理交易.

现在,确实存在未确认的比特币交易可能需要撤消的原因是 双花。 但是未经确认的以太坊交易 根本没有可预测的结果。 实际上,以太坊当前的实现甚至不处理未确认的交易。 但是如果以太坊节点 要立即处理交易,当块进入时,仍然需要以正确的顺序倒带并重播它们。这种重新处理是巨大的工作量浪费,并且会阻止外部流程 同时 在以太坊数据库继续运行的同时读取它。 (公平地说,应该注意的是, 参考实施 还会在出现块时倒回并重播事务,但这仅是由于缺乏优化。)

那么,使乱序执行成为可能的比特币交易模型又是什么呢? 在比特币中,每笔交易 明确指出 与其他交易的关系。 它具有一组输入和输出,其中每个输入都与它“花费”的先前事务的输出连接。 没有其他需要担心的依赖项。 只要(a)两个比特币交易不尝试花费相同的输出,并且(b)一个比特币的输出不会导致另一比特币的输入,一个比特币节点就可以确保交易是独立的,并且 它可以按任何顺序处理它们。 他们在区块链中的最终地位根本不重要。

要使用正式的计算机科学术语,以太坊交易必须 严格完全命令,这意味着必须定义每对交易之间的相对顺序。 相比之下,比特币交易形成了 有向无环图 这只是 部分订购,这表示允许在交易排序中使用一些歧义。 当涉及到并发时,这将改变世界。

从实际角度来看,企业中有很多关于私有区块链的讨论。 但是私有区块链只是一个 具有一些附加功能的分布式数据库。 而且,如果您今天尝试销售不支持并发的企业级数据库, 你会在房间外面被笑。 同样荒谬的建议是,单个节点必须等待12秒才能看到自己的交易结果。 作为维塔利克本人 最近发了推文:

对于我们Coin Sciences而言,这不仅仅是一个学术问题,因为我们需要决定是否以及如何将智能合约纳入 多链。 尽管有数百个功能请求和 问题 到目前为止,我们仅收到了两个与智能合约相关的信息,即使这样,其形式也不及以太坊提供的那样。 因此,尽管我们保持开放的态度,但事实证明,智能合约无法为用户解决任何实际问题。

赞成以太坊

如果仅对参数的一侧感兴趣,则可以在此处停止阅读。 但是您可能想知道:以太坊的创造者是愚蠢的吗? 如果每个节点都可以简单地选择关心运行哪些程序,为什么他们到底需要在公共分布式数据库中全局执行? 以太坊方式有什么好的理由吗?

实际上,如果我们谈论的是公共区块链,我相信确实如此。 但是,为了理解这些原因,我们需要考虑以太坊网络本身的动态。

防止垃圾邮件

区块链由对等网络维护,其中每个节点都连接到其他节点的随机子集。 当在一个节点上创建新事务时,它通过称为“中继”的过程迅速而随意地传播到其他节点。 在开放的公共网络中,任何人都可以创建交易,因此我们需要一种保护自己免受攻击的方法 交易垃圾邮件 这可能会使系统不堪重负。 由于网络是分散的,因此只能通过各个节点评估新交易的出现并确定是否中继这些交易来实现。 虽然此机制无法阻止垃圾邮件发送者 压倒性 一个单独的节点,它确实可以保护整个网络。

在公共网络中,当节点决定是否中继新交易时,一个关键标准是其费用与网络成本之间的比率。 对于比特币,此成本主要基于交易的原始大小(以字节计)。 在以太坊中, 更复杂的公式 基于交易将消耗的计算量来使用。 无论哪种方式,收费都是预防交易垃圾邮件的基于市场的机制。

但是,节点如何知道发件人是否有足够的资金来支付他们提供的费用? 对于以太坊,每个用户的“以太币”余额受先前交易结果的影响,因为 合约既可以花费也可以支付以太币。 因此,如果不为所有先前的消息实际执行所有程序,以太坊节点就无法知道用户的最新余额。 因此,它无法评估事务是否应该中继到其他节点。 否则,开放网络将被轻易摧毁。

紧凑的数据证明

在区块链中,区块主要由它们确认的交易填充。 但是,每个块还具有一个紧凑的“标题”,其中包含重要信息,例如时间戳和指向前一个块的链接。 对于基于的公共区块链 工作证明哈希,则哈希算法的输入仅是此块头。 这意味着“轻量级客户端”可以评估链的权限,而无需下载其大部分内容。 例如,截至2015年30月,完整的比特币标头集的大小为XNUMX MB,而 45 GB 完整的链。 这是1500:1的比率,这对于带宽和存储空间有限的移动设备而言至关重要。

每个以太坊区块的头包含一个“状态根”,它在处理该区块中的交易后对链的状态进行指纹识别。 除其他事项外,此状态涵盖每个合同数据库的内容,并且使用 单向哈希函数树。 对任何合同的数据库进行的最细微更改都会导致状态根完全不同,因此根“束缚”了数据库的内容。 (对比特币的“ UTXO承诺”的等效概念是 讨论 但尚未实施。)

计算状态根的树状方法具有重要的特性: 给定已知的状态根,可以有效地证明合同数据库中特定条目的值。 该证明的大小与深度成正比。 二叉树 其叶子是各个数据库条目,即日志2 数据库总大小。 这意味着,对于单个条目,仅证明 双打 数据库大小为时的长度 平方 –计算机科学家所追求的那种可扩展性。 现在回想一下,每个块的状态根在其标头中,轻量级客户端可以验证该标头。 结果,轻量级客户端可以安全有效地查询网络中的任何完整节点以获取单个数据库条目,并且 完整的节点不能说谎.

但是,如果我们的区块链标头包含状态根,并且状态根取决于数据库的内容,则 每个节点都必须保持区块链数据库的最新状态。 反过来,这意味着要为到目前为止收到的每条消息运行每份合同。 没有这个,挖掘节点将不知道要放置在块头中的状态根,其他节点也无法验证它们接收到的块。 底线是:如果我们希望轻量级客户端安全地从网络检索紧凑的数据证明,则完整节点必须执行链中数据描述的所有计算。

私人区块链的判决

让我们在私有区块链的背景下重新审视这两个论点。 关于私有链的第一件事要注意的是,它们往往没有本机令牌或加密货币。 这有几个原因:

  • 对私有链感兴趣的实体不想处理新的资产类别。
  • 私有链的共识模型基于一组封闭的矿工之间的协议,而不是工作量证明。 因此,采矿成本极低,并且矿工不需要太多奖励。
  • 由于对私有链中的所有参与者都进行了审查,因此对垃圾邮件和滥用的关注减少了。

回想一下,全局执行的第一个参数是使每个以太坊节点能够根据其提供的费用来决定是否中继传入的交易。 好吧,缺少本机令牌使该原因变得无关紧要,因为如果区块链没有本机令牌, 交易不能支付费用。 如果由于某种原因垃圾邮件仍然存在问题,则必须以另一种方式来控制它,例如,通过撤消发件人的权限。

现在让我们考虑第二个参数,以启用紧凑的数据证明。 公共区块链可能会在移动或其他轻量级钱包上吸引最终用户。 但这对于私有链的可能性较小,私有链的主要功能是 共享数据库 大公司之间。 如果区块链 is 从移动设备访问后,移动用户很可能是这些公司之一的客户,并且可以信任该公司告诉他们的信息。

相反,在私有区块链中 问题 全球执行力尤为突出。 如果私有区块链没有本机令牌,那么我们就没有类似天然气的市场机制来防止代码失控。 相反,我们需要根据每种交易的计算步骤引入某种固定限制。 但是,为了允许事务有意执行大量处理,此限制将需要很高。 结果,在最终将其关闭之前,网络仍可能会在意想不到的环路上浪费大量能量。

至于并发性,私有区块链更有可能看到使并发性成为必需的交易量。 公共区块链的容量受到以下事实的限制:为了进行有意义的去中心化,它们需要由预算有限的爱好者运行的数千个节点。 相比之下,私有链更有可能将几十个企业连接在一起,在这种情况下,容量和速度至关重要。

双层区块链

因此,除了全球执行之外,如果智能合约的所有内容在私有链中都有意义,那么这又会给我们带来什么呢? 哪种类型的区块链将为我们提供所需的性能和灵活性? 老实说,我还在考虑。 但是一个答案可能是: 具有两层的区块链.

较低的层将建立在比特币式交易之上,该交易可立即并发处理,而无需等待区块确认。 这些交易可以执行简单的资产移动,包括安全 原子交换,而无需借助智能合约。 但是,该较低层也可以用作 盲存储层 用于表示更复杂的业务流程的程序和消息,作为事务元数据嵌入。

至于上层,每个网络参与者都会选择 他们想运行哪些程序。 有些人可能选择完全不运行,因为他们只对简单的资产移动感兴趣。 其他人可能会执行一小部分与其内部流程相关的程序(知道该组不会与外部程序交换消息)。 一些人甚至可能选择全局执行,像以太坊一样处理每个程序的每条消息。 但是关键是 每个节点仅运行其所需的代码。 在计算机科学中,这种技术称为 懒惰的评价,因为它需要做的是尽可能少的工作,而不必忽略任何关键的事情。 通过惰性评估,如果区块链计算出现问题,那么只有那些实际执行该程序的节点才会注意到。 网络本身不会有任何感觉.

至于MultiChain,如果最终支持图灵完整计算,我怀疑我们是否将实现全局执行。 也许我们会采用这种懒惰的两层方法,或者可能会想到更好的方法。

公共区块链中的智能合约

正如我之前所说, 国家 图灵等完整的区块链图灵 ,那恭喜你, 全球执行的充分理由。 但这是另一个问题:什么是 企业 这些链的用例? 让我们想象未来的某个时间,当企业对公共区块链有足够的信心将其用于实际业务流程时。 如果一组公司希望在公共区块链中嵌入一些计算逻辑,则有两种选择:(1)使用具有全局执行功能的以太坊式区块链,或(2)使用 任何 区块链作为简单的存储层并自己执行代码。 考虑到这些选项, 他们为什么会选择(1)?

合理的选择将是具有(a)每个存储字节最便宜的价格和/或(b)基于总采矿能力的最高安全级别的公共区块链。 由于计算是确定性的,因此公司只需向 商店 他们的合同和信息,而不是实际 过程 他们。 此外,通过仅将区块链用于存储,他们可以使用 他们想要的任何编程语言。 这可能是以太坊字节码, JavaScript / ECMAScript 可读性甚至 机器码 以获得高性能。 实际上,以太坊合约 已经可以存储了 在比特币区块链上使用元数据。 这正是我建议的两层方法。

该讨论与...的概念有关 抽象层,由 OSI网络模型。 为了获得最佳的可靠性和灵活性,系统的每一层都应尽可能与其他层抽象(即独立)。 例如,我们不希望我们的硬盘控制器包含用于渲染JPEG图像的代码。 那么为什么我们要区块链执行它存储的程序呢? 对于大多数用例,我们没有从中受益,并且付出了巨大的代价。

结语

如果在私有区块链中全局执行没有意义,那么为什么每个人都在从事这些工作? 我认为这至少可以通过对区块链可以做什么的误解来解释 在现实世界。 你看,像比特币这样的公共区块链可以 直接移动不动产 (即其本国货币),因为区块链 定义 该货币的所有权。 这将资产的两个方面融合在一起,这些方面通常是截然不同的:(a)记录谁拥有资产的分类帐,以及(b)其实际位置。 这使得加密货币成为终极 承载工具,创建一个勇敢的新世界或洗钱者的天堂,具体取决于您问的是谁。

但是对于独立于区块链而存在的其他资产,一条链唯一可以做的就是持有 记录 他们是谁 应该 属于。 直到我们看到 初次发行 将资产转移到区块链上,并根据链的数据库定义该资产的合法所有权。 对于机构金融部门,我认为今天还有很长的路要走,尤其是因为需要进行监管方面的变化。 直到那时, 总会有一个额外的步骤合同和程序,在区块链所说的和现实世界中发生的事情之间。 此步骤还可能包含一些Turing完整代码,这些代码在最后可能的时间延迟执行。

我们已经听到很多关于“智能债券”的案例,这个问题就更加突出了。 智能债券直接发行到区块链上,区块链确保在适当的时候向债券持有人支付息票。 一切都很好。 但是,如果债券发行人的区块链账户资金不足以支付到期的款项,会发生什么? 区块链当然可以设置一个标志来表明某事不对劲, 但它无能为力。 我们仍然需要一支由律师和会计师组成的大军,通过理发,债务重组,没收或完全破产来解决整个问题。 简而言之:

如果智能合约无法兑现承诺,我们为什么要付出代价?

谢谢您的阅读。

时间戳记:

更多来自 Multichain