深入理解Plasma(三)Plasma MVP
这一系列文章将围绕以太坊的二层扩容框架 Plasma,介绍其基本运行原理,具体操作细节,安全性讨论以及未来研究方向等。本篇文章主要介绍 Plasma 的一个最小实现 Plasma MVP(Minima Viable Plasma)。
在上一篇文章中我们已经理解了 Plasma 中的一些关键操作,但是 Plasma 是一套框架,如果脱离了实际的应用,仍然很难彻底理解它。因此本篇将详细介绍 Plama 的第一个项目 Plasma MVP(Minimal Viable Plasma),即在 Plasma 框架下的最基础的实现。Plasma MVP 是 Vitalic 和他的团队在 2018 年初提出的基于 UTXO 模型实现的 Plasma 设计标准[1],它以最简单的方式实现了链下交易,但无法支持复杂的计算,例如脚本(Script)和智能合约。在阅读下面的内容之前,请确保已经理解了这个系列之前的文章。
整个 Plasma MVP 的生命周期可以通过下面这幅图表现出来:
Plasma 合约
首先需要将 Plasma 合约部署到主链(以太坊)上作为主链和子链沟通的媒介。Plasma 合约会处理由子链提交的区块,并且将区块的哈希值存在主链上。除此之外,还会处理用户的存款(deposit)、取款(withdrawal/exit)以及争议(challenge)操作。
Plasma 合约中主要包括的数据结构有:
- Owner:合约的拥有者(即部署合约交易的发送者)的地址,即部署合约交易的发送者;
- Plasma 区块列表:每个 Plasma 区块中存储了(1)区块的 Merkle root(2)区块提交的时间;
- 退出列表:即提交了退出申请的列表,每个退出申请存储了(1)申请者的地址(2)申请退出的 UTXO 的位置。
Plasma 合约中主要包括的函数有:
- submitBlock(bytes32 root):向主链提交一个区块,仅仅提交区块中所有交易的 Merkle root;
- deposit():生成一个只包含一个交易的区块,这个交易中包含与 msg.value 值相等的 UTXO;
- startExit():执行给定 UTXO 的退出操作;
- challengeExit():向某个正在执行的退出提出争议。
Operator
在前面的文章中我们已经知道 Plasma 子链是一个独立的区块链,那么也就有独立的共识机制。在 Plasma MVP 中采用的共识机制就是 PoA(Proof of Authority),即参与共识的只有唯一一个矿工,称为 Operator。Operator 负责处理所有子链上发生的交易,将其打包成区块存储在子链上,并且周期性地向 Plasma 合约提交区块,将子链上的状态(区块的哈希值)提交到主链共识。那么,既然 Operator 是唯一的矿工,这不就意味着 Plasma 违背了去中心化的初衷了吗?其实,这是去中心化向执行效率的妥协。在之前的文章中也提到过,Plasma 的安全基础依赖于底层的区块链,只要底层的区块链能够保证安全,那么在 Plasma 子链上发生的最差结果也只是迫使用户退出子链,而不会造成资产损失。
Operator 可以采用最简单的 REST API 方式实现,子链中的用户可以通过调用简单的 API 获取到子链中区块的数据。
存款(deposit)
用户 Alice 通过存款(deposit)操作向 Plasma 合约发送带有一定数额的以太币或 ERC20 token 加入 Plasma Chain,这时 Plasma 合约会执行 deposit() 函数,生成一个只包含一个交易的区块,这个交易的 UTXO 记录了 Alice 从主链转移到子链的数额。当这个区块被主链确认后,Alice 就可以使用新生成的 UTXO 向其它用户发送交易了。
交易(transaction)
在 Plasma MVP 中,所有用户发送的交易都是直接发送给 Operator,当积累了一定数量的交易后,由 Operator 将交易打包成区块。这里需要注意的是,由于 Plasma MVP 采用的是 UTXO 模型,所以即使交易的收款方不存在,交易也是成立的。
在子链上 Alice 向 Bob 发送一个交易的流程如下:
- Alice 首先需要得到 Bob 在子链上的地址;
- Alice 将一个或多个 UTXO 作为输入构造交易发送到 Bob 的地址,并对交易签名;
- 等待该交易被打包到区块中;
- Alice 向 Bob 发送确认消息,并且使用相同的私钥签名。
生成区块
在 Plasma MVP 中,一个 Plasma 区块产生的情况只有两种:一种是 Operator 打包生成区块,另外一种是当用户执行 deposit 操作时,由 Plasma 合约直接生成一个只包含一个交易的区块。
监视子链
为了保证子链上资产的安全,用户需要周期性地检查子链上的数据,保证没有恶意交易产生。用户需要运行一种自动化的软件(例如钱包),每隔一段时间下载子链中的区块数据,检查每个区块中的交易,如果有恶意交易产生,立即退出子链。
取款/退出(withdrawal/exit)
当 Alice 想要退出子链时,需要向 Plasma 合约发送一个 exit 交易,申请中需要包含(1)所要退出的 UTXO 的位置,包括区块号(blknum)、区块内交易号(txindex)以及交易内输出号(outindex)(2)包含该 UTXO 的交易(3)该交易的 Merkle proof(4)用于生成该 UTXO 所涉及的之前一系列交易的确认签名。除此之外,exit 交易中还要包含“退出押金(exit bond)”。如果这个 exit 被 challenge 成功,那么取款的操作将被取消,而且退出押金将被发送给提出 challenge 的用户。
之后这个申请会被放入一个优先队列中,通过这个公式计算优先级:
Priority = blknum * 1000000000 + txindex * 10000 + oindex
之所以采用这种优先队列的方式处理取款顺序的原因是保证旧的 UTXO 总能优先于新的 UTXO 被取出。也就是说,当有恶意交易(例如双花等)产生时,所有在恶意交易发生之前的交易都可以被优先取出。那么如何解决在恶意交易之后被确认的交易的取款问题呢?Plasma MVP 采用了“确认签名(Confirmation Signatures)”的机制,在下一小节我们将介绍这一机制是如何工作的。
确认签名(Confirmation Signatures)
在 Plasma MVP 中,用户的退出顺序以所要退出的 UTXO 所在的交易的位置为准。假如 operator 作恶,在一个合法的交易之前插入一个非法的交易,那么当用户执行取款时,由于非法交易可以先被取出,因此当执行到该用户的交易时,可能 Plasma 合约中的资产已经被取空。为了解决这个问题,Plasma MVP 采用了“确认签名”机制,例如当 Alice 产生一个交易时,她首先会对交易签名。当该交易被打包入区块后,Alice 还需要对该交易进行一次签名,即“确认签名”。
引入确认签名机制后,当 Alice 发现在一个区块中自己的合法交易之前存在非法交易时,可以拒绝对自己的交易进行“确认签名”,同时申请取款。这样可以使得当前的交易失效,保证自己之前“确认签名”后的交易可以优先于非法交易之前取出。
这种确认签名机制极大地破坏了用户体验,用户每产生一个交易都要经历签名->等待确认->确认签名。而且由于确认签名也需要占据 Plasma 区块的空间,因此也降低了子链的可扩展性。为了解决这个问题,Plasma 的研究人员提出了扩展版本 More Viable Plasma 移除了确认签名的要求[2]。
争议(Challenge)
每个取款操作都会经历一个争议期。例如在 Alice 的某个 UTXO 退出子链的过程中,如果 Bob 在争议期内发现有恶意行为发生,他可以提出一个争议(challenge)。一个争议需要给出针对的 UTXO 的位置,以及该 UTXO 被花费的证明,即该 UTXO 已经存在于某个交易中,且这个交易已经被打包到区块。
合约通过调用 challengeExit() 函数执行一个争议,争议成功后会取消正在执行的取款操作,并将提交取款申请所冻结的押金发送给 Bob。
攻击场景
在 Plasma 子链中主要存在两种攻击场景:
- Alice 试图忽视在子链中转移给 Bob 的资产,使用最初加入 Plasma 子链时的交易证明向主链提出取款申请。
- Operator 生成一个恶意交易,占有其他用户的资产,并且尝试退出子链。
下面对这两个攻击场景进行分析,观察 Plasma MVP 如何保证资产的安全性:
场景1
- Alice 使用最初加入子链时生成的交易作为证据向主链提出取款申请;
- Bob(或者其他任意用户)拥有 Alice 申请退出的 UTXO 被花费的交易证明,并将此作为证据向主链提出一个争议;
- 争议生效,Alice 的退出申请被驳回,同时将 Alice 申请退出的押金发送给 Bob;
- Alice 的攻击失效。
场景2
- Operator 创建了一个非法交易,并且将其打包生成区块之后在主链得到确认;
- Operator 提交取款申请,打算将 Alice 的资产取走;
- 在争议期内,Alice 发现了 Operator 的恶意行为,立即提出取款申请,退出子链;
- 由于 Alice 的申请优先级较高,因此会在 Operator 之前退出;
- Operator 的攻击失效。
相关项目
Talk is cheap, show me your code.
目前已经有许多机构和公司已经实现了 Plasma MVP,但实现的语言和细节有所不同:
总结
本文介绍了 Plasma 的最小实现版本 Plasma MVP,虽然采用最简单的 UTXO 模型,但已经足够体现出 Plasma 的核心思想。在 Plasma MVP 中,用户资产的安全主要依赖于用户及时发现恶意行为,并退出子链。接下来的文章将会介绍另外一个稍微复杂一点的项目,Plasma Cash。
相关资源
- https://ethresear.ch/t/minimal-viable-plasma/426
- https://ethresear.ch/t/more-viable-plasma/2160
- https://github.com/fourthstate
- https://github.com/omisego/plasma-mvp
- https://github.com/kyokan/plasma
本文的作者是盖盖,他的微信公众号: chainlab
深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。
深入理解Plasma(三)Plasma MVP的更多相关文章
- 深入理解OOP(三):多态和继承(动态绑定和运行时多态)
在前面的文章中,我们介绍了编译期多态.params关键字.实例化.base关键字等.本节我们来关注另外一种多态:运行时多态, 运行时多态也叫迟绑定. 深入理解OOP(一):多态和继承(初期绑定和编译时 ...
- 理解RxJava:(三)RxJava的优点
理解RxJava:(三)RxJava的优点 在第一部分,讲解了RxJava的基本结构.在第二部分,展示了operators的强大之处.但是你们可能仍然没有被说服,也没有足够的理由信服.下面是一些能让你 ...
- Java 反射理解(三)-- Java获取方法信息
Java 反射理解(三)-- Java获取方法信息 基本的数据类型.void关键字,都存在类类型. 举例如下: public class ClassDemo2 { public static void ...
- ReadHub项目Kotlin版开发指南(三、MVP架构)
ReadHub项目Kotlin版转换指南(一.环境搭建) ReadHub项目Kotlin版转换指南(二.数据库和网络请求) ReadHub项目Kotlin版转换指南(三.MVP架构) Android ...
- 简单理解Hibernate三种状态的概念及互相转化
本文描述了Hibernate三种状态的概念及互相转化.Java对象的生命周期中有三种状态,而且互相转化.它们分别是临时状态,持久化状态,以及游离状态. AD:WOT2015 互联网运维与开发者大会 热 ...
- 学习C++ Primer 的个人理解(三)
第三章,主要内容是字符串和数组.感觉作者的意图是希望读者可以早一点可以写出简单的小程序,并且可以早点接触迭代器这种思想. 在我看来,这种内容的难度并不大. 对于编程来说,最重要的应该是思想,类似vec ...
- 关于SVM数学细节逻辑的个人理解(三) :SMO算法理解
第三部分:SMO算法的个人理解 接下来的这部分我觉得是最难理解的?而且计算也是最难得,就是SMO算法. SMO算法就是帮助我们求解: s.t. 这个优化问题的. 虽然这个优化问题只剩下了α这一个变 ...
- 对HashMap的理解(三):ConcurrentHashMap
HashMap不是线程安全的.在并发插入元素的时候,有可能出现环链表,让下一次读操作出现死循环.避免HashMap的线程安全问题有很多方法,比如改用HashTable或Collections.sync ...
- Spring深入理解(三)
Spring 中 AOP 特性详解 动态代理的实现原理 要了解 Spring 的 AOP 就必须先了解动态代理的原理,因为 AOP 就是基于动态代理实现的.动态代理还要从 JDK 本身说起. 在 Jd ...
- 理解TCP三次握手和四次挥手
TCP相关知识 TCP是面向连接的传输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,HTTP协议并没有明确要求必须使用TCP协 ...
随机推荐
- c# Castle Windsor简单例子
Windsor是Castle的IOC框架.需要用到两个dll(Castle.Core.dll和Castle.Windsor.dll). 1.接口以及接口实现类: public interface IT ...
- Oracle启动关闭
启动: [oracle@oracleSigle ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.1.0 Production on Wed Nov ...
- eclipse 中配置php的 XDebug调试
1. 打开 eclipse for php IDE,window->preference->PHP->Debug 2. 配置phpserver 3. 我的已经增加好了,默认的应该有l ...
- Vue引入elementUI组件全过程
参考:https://www.cnblogs.com/fubinbin/p/9938528.html 在vue脚手架安装完成之后,页面正常跳出vue刚安装完的界面 我们开始引入elementui 1. ...
- #WEB安全基础 : HTTP协议 | 0x8 HTTP的Cookie技术
说道Cookie,你喜欢吃饼干吗? 这里的Cookie不是饼干=_= HTTP不对请求和响应的通信状态进行保存,所以被称为无状态协议,为了保持状态和协议功能引入了Cookie技术 Cookie技术在请 ...
- 【转】Robot Framework用法总结
今天总结下Robot Framework最基本的用法,一来呢,希望自己以后看到这篇总结,很快能回忆起如何使用Robot Framework.二来呢,以初学者的姿态总结Robot Framework,希 ...
- supervisor 守护进程
一.supervisor 安装 1.yum -y install epel-release 2.yum -y install supervisor 二.supervisor 配置文件详解 三.supe ...
- idea显示左边的树形项目结构
直接上步骤: File-->Project Structure-->Modules-->点击:中间一列框的"+"-->Import Module--> ...
- 关于angular2 打包(一)
在讲到angular2 及以上项目打包之前,我先讲一下.angular cli 拥有自己的打包工具,熟悉的可以直接上手.如果用不惯,也可以去使用webpack 之类的.内置的systemjs也是很好用 ...
- Jmeter对SQL Server进行压力测试
下载地址 https://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/ 选择binary版本即可 下载的是apache-jmeter-5. ...