一个多月前,我们热情地宣布了OVM,一个区块链的扩展通用2层(L2)解决方案,同时继承了基础链(L1)的所有安全性。这项工作虽然非常有希望,但纯粹是理论上的…直到今天!
我们很高兴地宣布rubber已经以概念验证的形式在OVM上实现了状态通道。这项工作演示了状态通道如何在OVM上无缝运行,如果您稍微推断一下,如何在OVM上构建所有的二级解决方案,从而以较少的开发工作实现更好的标准化、安全性和互操作性。
什么是OVM?
OVM是一个通用框架,可以在廉价,轻便的L2应用程序中完全继承缓慢而昂贵的基链的优势。其区别在于它是区块链不可知论。创建了用户、钱包、开发人员等可以遵循的标准,以支持许多不同的二级应用程序,而不是每个二层方法的单独范例。
它是怎么做到的?我们将深入探讨,但与许多提议的缩放解决方案一样,OVM仅使用L1来实现L1擅长的功能:基于一组明确定义的规则实现不变、一致的共识。我一直认同的思维模式是,L1是法官和陪审团,用它来追溯处理法律没有得到遵守的主张要比主动监督一切以确保法律始终得到遵守要有效得多。
OVM进一步采用这种方法,认识到如果所有这些不良行为的声明都能以相同的方式表达,我们可以对所有情况使用相同的司法系统(L1争议合同)(L2实施)。
状态通道POC概述
它是什么?
1. 具有证明OVM上可能存在完整状态通道所需的最低功能的示例。
2. 通过L2中的相互协议乐观地演变L1状态的代码,完全不用了解L1,以参与者可验证和争议的方式,从而完全继承L1安全性。
3. 在通用OVM L2客户端上实现的众多扩展思想之一。
它不是什么?
1. 仅用于状态通道的特殊用途代码。
2. 状态通道的生产就绪演示,没有错误和小的加密经济漏洞。
3. 实际上与L1交互的东西(我们将在这里讨论如何发生这种情况并在后面的文章中演示该部分的工作原理)。
高级OVM工作流
输入L2:将资金(添加/状态) 锁 定在L1上的争议合同中,参考[L1]裁决合同。在这种情况下,我们将引用包含逻辑的状态通道合约,该逻辑定义什么构成有效的可退出状态。状态通道合约以及可能所有的OVM裁决合同,将依赖于争议合同来进行标准的退出请求和退出争议处理。
使用L2:在L2中高效交互,完全继承L1安全性。
按照L1状态通道合同中规定的规则,在没有实际交互的情况下,交换L2中双方约定状态的光速更新。
退出L2:在挑战期间没有有效挑战的有效索赔退出。对于状态通道,此声明将为退出状态有效,如一级状态通道合约所定义。在使用L2状态通道时,双方必须收集能够对无效退出声明进行争议的证据。
深入了解状态通道L2
L1裁决合同
如果我们要使用L1作为法官和陪审团,我们需要定义一套清晰的法律,它将用于对索赔作出裁决。这将至少包括定义有效的可存在状态。对于状态通道,可以用英语将有效的可存在状态定义为“通道的最新相互签署状态”。
为了使该声明可由通用法官评估,甲方退出状态通道C并更新其L1状态以匹配L2状态的有效退出声明包含两个断言:
1. 所有信道参与者已签署信道C的状态为S的消息M。
2. 对于通道C,不存在消息m‘,因此m’的nonce比m高,m‘由所有通道参与者签名。
如果提出此类索赔,可能会导致两种可能的情况:
1. 该索赔通过争议期的重叠进行验证,没有有效的质疑。
2. 如果发生以下任何一种情况,索赔在争议期间无效:
a)L1合同评估消息M,并确定它不是由通道C的所有参与者签署的。
b)一级合同从任何一方收到一条“M”信息,该信息否定了该信息不存在的主张。
评估此类索赔的逻辑必须存在于L1合同中。虽然这篇文章不会证明这一点,但希望读者充分相信可以构建智能合约以将地址与通道ID相关联,确定特定地址是否已签署特定消息,比较不同消息的非属性,采取后续行动指定的时间延迟等。
L2交互
Alice和Bob已将资金存入L1合同,成功启动了状态通道。怎么办?OVM完全取决于它们。
信息
如果Alice和Bob想要改变其在L2的初始存款状态,他们需要签署和交换符合L1合同可验证格式的消息,并确保不会违反L1合同中规定的任何规则。假设这是消息格式(如我们在此处和此处的repo中所述):
{
“channelId”: “1234567890”, // L1 ID
“nonce”: 1, // The fi rs t message
“data”: {
“addressBalance”: {
“0x0a”: 100, // Alice’s ini ti al balance
“0x0b”: 100 // Bob‘s ini TI al balance
}
}
}
如果交换的消息不遵循这种格式,那么L1合同将无法解释它们,它们将毫无用处。
发送,签名和重新签名
假设Alice正在从她的余额中支付Bob 5以获得一些好处或服务。她可以通过简单地签署并向他发送以下消息(我们的回购中的逻辑)来做到这一点:
{
“channelId”: “1234567890”,
“nonce”: 2, // Most recent message
“data”: {
“addressBalance”: {
“0x0a”: 95, // Alice -5
“0x0b”: 105 // Bob +5
}
}
}
如果Bob接受该消息有效,他将签署此消息并将其发送回Alice(让我们忽略他现在没有签署有效消息的情况,因为这是状态通道中已解决的问题)。
如果消息无效,Bob将不会对其进行签名,并且前一个状态将继续为有效状态。
他们可以通过以这种方式签名和交换消息来继续发展状态,从而增加每条新消息的随机数。
消息 存储
正如OVM不规定如何交换消息一样,它也不规定Alice和Bob需要存储什么,但他们知道L1合同处理出口需要什么信息,以及他们需要提供什么来质疑出现的任何无效出口。因此,他们需要存储最近的会签签名消息以及任何一方已签署和发送的任何待处理(意思不是会签)消息。
如果Alice或Bob想要退出,他们将向L1合同提交最近的会签签名消息作为他们想要退出的状态。如果任何一方试图退出先前状态的消息,则另一方将提交最新的会签消息作为另一消息无效的证据。
状态通道消息的示例数据存储在我们的repo中(请注意,它扩展了我们的基本MessageDB中的功能)。
退出和挑战退出
每个退出和退出挑战不仅需要L1裁决合同需要对其进行评估的数据,而且还需要以一般L1争议合同可以理解的方式呈现。
这就是我们真正了解OVM如何工作的地方。
假设Alice想在上面的消息之后退出状态通道和nonce 2。这是她将发送给L1裁决合约的状态通道出口索赔的结构。它现在没有什么意义,但当我们通过下面的过程时,它会变得更加清晰:
{
“decider”: AndDecider,
“input”: {
“left”: {
“decider”: SignedByDecider,
“input”: {
“publicKey”: “0x0b”, // Bob’s Address
“message”: { // Most recent message
“channelId”: “1234567890”,
“nonce”: 2,
“data”: {
“addressBalance”: {
“0x0a”: 95,
“0x0b”: 105
}
}
}
}
},
“leftWitness”: {
“signature”: “0xbbbbbbbbbbbbbbb” // Bob‘s msg signature
},
“right”: {
“decider”: ForAllSuchThatDecider,
“input”: {
“quant if ier”: SignedByQuan TI fier,
“quan TI fierPa ram e te rs”: {
“publicKey”: “0x0a”, // Alice’s address
“channelID”: “1234567890” // Our Channel
}
“propertyFactory”: (message) =》 {
return {
“decider”: MessageNonceLessThanDecider,
“input”: {
“messageWithNonce”: deserializeBuffer(
signedMessage,
deserializeMessage,
stateChannelMessageDeserializer
),
“lessThanThis”: 3,
},
}
}
}
},
“rightWitness”: undefined
}
}
首先,让我们回到上面的状态通道退出声明定义:
1、所有信道参与者已签署信道C的状态为S的消息M。
2、对于通道C,不存在消息m‘,因此m’的nonce比m高,m‘由所有通道参与者签名。
如果我们暂时忽略这种时髦的格式,我们可以看到Alice的声明类型遵循这种声明结构。
第一部分列出了一个名为SignedBy edA cider的东西,虽然我们还不知道这意味着什么,但我们看到它是由Bob的地址、我们最近的消息和Bob对我们最近消息的签名列出的。我们可以看到,这有所有必要的信息来证明Bob签署了最新的状态。
第二部分更加激烈,但是我们看到一个我们不完全理解的ForAllSuchThatDecide,一个带有Alice的地址和我们的Channel ID参数的SignedByQuan TI fie,以及一个MessageNonceLessThanDecider,右边是LessThanThis:3。如果我们只是按顺序读取部分内容,我们请参阅ForAll 。.. SignedBy 。.. Alice的地址和我们的频道ID,MessageNonceLessThan 。.. 3。这是一个延伸,但也许这声称Alice已为此频道签名的所有消息的nonce小于3?
最后,这两个部分嵌套在AndDeciderblock中。它有一个左侧部分和一个右侧部分,所以它可能意味着左右两边?
OVM中的VM表示虚拟机
OVM是一个虚拟机,虚拟机需要执行有用的指令。为此,OVM必须为指令定义基本 接口 。由于OVM完全基于这些声明的声明和争议,因此其指令必须遵循“根据规则集S确定输入N是否有效”的形式。
为此,OVM具有Property的概念。属性由一个Decider组成,它直接映射到一个简单的L1智能合约,能够做出非常具体的true/false决策,并输入到要评估的决策者。例如,AndDecider决定是否为true,并且仅当其input.leftproperty求值为true且其input.rightproperty求值为true时。
决策者也可能需要证人,这是与输入相关的证明。例如,SignedByDecider决定消息是否已由公钥签名。它的输入(message和publicKey)定义了正在决定的内容,其见证(签名)是用于做出决定的证明。
最后一部分是Quantifiers(其他简单的L1智能合约)。在给定一组特定约束的情况下,Quantifiers能够列出所有适用的信息。例如,SignedByQuantifier能够列出由给定公钥签名的所有消息。
在上面,您可以看到ForAllSuchThatDecider使用SignedByQuantifie来获取Alice为相关频道签名的所有消息。ForAllSuchThatDecideralso接受它调用的属性工厂函数,传递其量词的每个结果,以获得它将评估的所有属性*。正如您可能想象的那样,ForAllSuchThatDecider会判断它正在评估的所有属性是否为true。
把它们组在一起
Alice的退出声明演示了如何将这些粒度属性嵌套在一起以表示复杂语句。我们还可以看到,就像其他虚拟机一样,组装一小组细粒度指令(决策者)的不同排列,我们应该能够代表每一个可能的声明。
*注意:PropertyFactoryfunctions适用于此示例,但它们最终不会用于传递给L1合同的声明中,因为它们不能一般地表示。这不是一个阻塞,因为它很容易通过简单地传递一个Decider和一个变换器将Quantifierresults转换为ForAllSuchThatDeciderto来枚举属性本身来解决,但我们正在寻找最好的方法。
现在我们知道OVM如何启用状态通道。我不会讨论OVM如何支持其他扩展解决方案,将其作为练习向读者介绍如何为这些其他实现构建L1裁决合同和退出声明。然而,我要谈到的一件事是这种方法如何提供其他有价值的好处,例如安全性,兼容性和链不可知性。在标准化实际拥有所有L2资金的L1争议合同时,OVM将通过提供类似于ERC-20标准的可重复使用,可扩展,经过实战 检验 的合同来提供出色的安全性。这种标准化以及OVM操作的通用性将提供作为副产品的其他不同扩展解决方案之间的兼容性,从而允许更好的钱包集成和UX。最后,尽管我们将目标定位于以太坊进行初始实施,但由于某种原因,我没有提到具体的L1链--OVM应该适用于任何支持智能合约的L1。更进一步,使用OVM,可以在不兼容的L1链上实现相同的扩展解决方案,并共享几乎所有L2代码。