干货 | 图灵完备的状态通道的实现办法, Part-1

Ajian   |     |   2415 次阅读

状态通道自其初步设想提出以来就激起了加密社区的兴趣,多年以来都是热门的讨论话题。

两方或多方在链上提交初始状态,使用一系列已签名信息进行链下交易,并通过第二笔链上交易将最终结果提交回区块链上。这一过程听起来像是如今区块链实现案例中固有的扩展性问题的一大解决措施。

虽然到目前为止有很多讨论都是围绕多方之间的代币转让进行的,但是这一概念的用途远不止这点。因此,让我们探索如何在状态通道上实现图灵完备逻辑的方法吧。

为此,我将讨论范围缩小至由交易双方轮流交互的一对一通道,不过这些概念可以扩展至更广泛的用例上。

首先,让我们回顾一下什么是状态机。状态机是一个很简单的概念,支持着世上很多软件的各种形式,可以总结为:

f(state, action) => state’

也就是说,这个函数采用当前的状态和一次行动(即更改状态的方法),之后将该行动应用于这种状态并返回新的状态。这是支持大多数传统电子游戏(我进入密码学领域之前的从业经历)的核心概念之一 ——其中,行动可以是用户按下按钮、网络包抵达,或是(常见于电子游戏中的)时间流逝(有希望达到流畅的每秒60帧画面!)等等。

接下来,我要举一个很好的例子:国际象棋。国际象棋属于一对一游戏,棋手轮流下棋,而且规则明确,因此它天然适用于状态机。执行下棋步骤的状态机如下:

状态:棋盘上棋子的当前摆位,轮到哪一方走棋,是否出现下一步“将军”或者已将死的情况(简单起见,我会忽略弃局与和局的情况)。

行动:指定一个棋子进行移动并且将棋子移动至目标方格内。

在受到调用之时,状态机需要做以下两件事:

  • 验证该行动是否有效:
    • 是否轮到该棋手走棋?
    • 棋手将棋子移动至目标方格是否符合走棋规则(包括“将军”的限制条件等)?
    • 是否在“将军”之后仍有翻盘余地?
  • 更新状态
    • 将棋子移动至新的方格
    • 将“被吃”棋子从棋盘上拿下
    • 核实“将军”情况
    • 更新轮到哪方走棋

如此一来,通过让双方棋手不断交替调用函数并且每走一步都会传递之前的状态,你就能利用状态机实现一场对弈。

我们能在(比方说)Solidity中编写该函数吗?当然可以了,不过始终将状态保存在链上,并且每轮都直接调用合约代码更新状态会造成费时又费钱的用户体验,这时状态通道就可以派上用场了!

让我们看看在现实世界中执行状态通道的初次尝试——首先先赋予它一个存在于链上的理由——两人为争得某个有价值之物进行比赛。只需编写一个合约,从参赛双方处获取一些资金,我们就可以开启一条通道,将这些资金锁定,直到通道关闭为止。不过我们还需要做什么呢?

首先,我们需要为参赛者各创建一个应用。让我们假设一下,该应用是基于网络的,使用web3与区块链进行交互以及某个未指定的点对点机制实现参赛双方应用之间的直接交流,并且为与之进行交互的参赛者带来良好的用户体验。

这时,如果我们在浏览器应用中执行状态机函数,之后参赛双方就可以开始对弈,每位参赛者轮流走一步棋,通过状态机更新状态,并将状态传递给另一方。然而在不经任何审查的情况下,参赛双方都可以轻松作弊。因此进一步来说,可以添加下列步骤确保游戏的公平性:

  • 行棋方不只传递新状态,还要传递行动。非行棋方也要根据之前状态的本地副本运行状态机,查看其结果是否与新状态一样。如果不一样的话,说明行棋方作弊了。
  • 行棋方用其私钥签署包含其行动和新状态的信息。如果另一方发现状态转换无效,即可证明行棋方作弊了。
  • 行棋方联合签署之前来自另一方的信息(已经在上述步骤二中签署过了)并将该信息与新的行棋状态一同发送出去。这一步真的很重要,因为它设定了双方棋手都认可的基准线。
  • 每当一条已签名信息发送出去后,另一方会审核这些签名。如果签名无效,该信息会被当作错误信息而非作弊行为被拒绝(因为我们需要有效签名来证明信息的有效性)。

当游戏结束之时,参赛双方共同签署最终状态。在这场对弈中,每一步都经过参赛双方的验证和认同。

那么——我们该如何在状态通道中将这场对弈放到区块链上?从工程学的角度来看,这还是比较简单的——我们在状态通道合约上创建一个链上 CloseChannel() 函数,从参赛双方处获取已签名状态,验证签名的有效性,再验证“将军”的情况下该游戏的签名状态,并将锁定的资产转给赢家。棒极了!

但是...我们已经创建出了这样一个可证公平的分布式自主游戏吗?没有!有两点原因:

  • 我们还没有想好一方作弊时该如何处理,而且
  • 游戏的实际规则是嵌入在客户端应用中的,可能会遭受恶意修改或操纵(这取决于它的托管方式)。
  • 此外——我们可以如何确保参赛双方实际使用相同的状态机?

最后,让我们言归正传,聊一聊解决方案!如上文所述,我们可以在区块链上将国际象棋的规则编写成代码,不过我们真的不想要在对弈的每一步棋都用上链上交易。然而,没有理由不让区块链自身管理游戏规则——更重要的是,管理执行游戏规则的代码。如果我们在 Solidity 上创建了状态机函数,并将它发布在链上,它可以预先自主验证为正确的,而且任何人都可以参照。

然而,更重要的是,该函数可以在链下执行,比在链上执行更快、也更便宜数十倍。(注:状态机这个形式本身不会带来副作用,因此它实际上是常用函数。)

因此,如果把我们上述例子中的本地客户端状态机执行替换为链上代码的链下执行,参赛双方都会对运行的代码和他们签署的信息的准确性更有信心。

不过最大的优点是,我们现在有方法应对作弊行为了。如果作弊方发送的签名信息中包含无效的状态转换——就如同不遵守链上代码规则——我们可以采取行动了!接收方可以调用链上争端解决函数,将已签名的无效状态转换传递进去。该函数可以调用 相同的链上状态机代码并显示它是无效的,作弊方会受到惩罚。

因此,通过这种方法,我们可以出于各种目的构建各种各样的状态机,可以坚持使用链上逻辑通过可验证的方式在链下推进,出现争端时可以在链上进行验证。

这种方法没有限制状态机、状态或转换状态的行动的复杂性,除了能够在链上执行的部分——因此状态机和执行状态机的区块链一样图灵完备。

在第二部分,我打算讨论:

  • 在FunFair,我们是如何基于这个概念执行实际解决方案的,以及我们面对的一些挑战
  • 我们是如何在这一过程中注入随机性的
  • 如何处理一些试图作弊的恶性情况(例如,在对弈中参赛者意识到自己再不采取行动就要输了)
  • 讨论对每个参与者设定不同规则的固定赔率的赌博游戏,以及在相同的状态通道中进行的一系列游戏在其轮次间和轮次内状态之间的差异
  • 如何将这种方法扩展应用至上百种实行不同规则的各类游戏中

FunFair的首席技术官 Jeremy Longley 写于2017年12月15日。


原文链接: https://funfair.io/approach-turing-complete-state-channels-part-1/
作者: Jeremy Longley
翻译&校对: 闵敏 & Elisa


你可能还会喜欢:

科普 | Raiden Network — Ethereum 区块链支付通道
白皮书 | 以太猫白皮书
链上,链下?

 
0 人喜欢