以太坊 layer2: optimism 源码学习 (一)
作者:林冠宏 / 指尖下的幽灵。转载者,请: 务必标明出处。
GitHub : https://github.com/af913337456/
出版的书籍:
前序:
对于区块链每个阶段的风口产品,我都会挑选其中某个研究其源码,当作学习并增加经验。早前看的是
zkSync
,难度巨大而能力有限,遂转于Optimism
。
本次是系列文章,这是第一篇。
这里就不说什么是 Layer2 了,可以去网络搜索其它文章来阅读。在 Layer2 的扩容方案中目前有 3 种,Rollups
是其中一种,称为打包
。打包又分两大派别:
- 乐观打包,Optimistic rollups;
- 零知识打包,ZK rollups。;
这两派的风格各异,特点突出。Optimistic rollups
对智能合约
的支持可以说是完全兼容,而 ZK rollups
目前对智能合约支持不友好,但是在交易提款
上链这块非常快、更安全却计算量巨大,技术难度复杂。关于它们的对比
,我后续再写篇文章详细说说
目录:
- Op 简介
- Op 的程序组件
- 如何使用 Op
- 源码分析 --- 充值与提现
- L1 合约层源码
- L2 层源码
- 提现
1. 正题,Op 简介
Layer2 是公链下的第二层。比如安卓系统下的底层软件。
Optimism,下面简称 Op,是基于 Optimistic rollups
方案所实现的 Layer2 应用,下面简称 L2。作用是帮助 以太坊
扩容以及加速交易。
特点如下:
- 提款到 Layer1 的周期,约一周。下面简称 L1;
- 速度,L2 内交易,极快,手续费很低;
- 通用性,EVM 兼容,基于以太坊的修改
- 技术复杂度,简单;
- 链下成本,低。链上成本,高;
- 交易安全保证,基于默克尔树--树根哈希的
欺诈证明
; - 源码:https://github.com/ethereum-optimism/optimism
2. Op 的程序组件
虽说 Op 是个 L2 应用,但它的组成程序组件非常多。我这里列出会和我本文内容相关的组件:
合约
,这些会被部署在 L1 公链上面,由 L2 组件或用户来调用,包含不限于有:L2 侧链
,基于 geth 源码改造的链,运行在 Op 生态里;L1StandardBridge.sol
垮链桥合约,用来处理充值 Token 到 Op 地址或从 Op 地址提现到 L1 地址 所用;CanonicalTransactionChain.sol
规范处理L2 --> L1
的交易,下面简称CTC
;L1CrossDomainMessenger.sol
跨链信使合约,里面主要编写进行了各种要触发跨链事件的函数。
DataTransportLayer
,定时扫描 L1 区块,从中获取到TransactionEnqueued
事件,并存储到LevelDB
数据库;Sequencer
:- 接受用户发来 L2 的交易;
- 定期从数据库中获取
DataTransportLayer
存储的TransactionEnqueued
事件数据,并把交易在 L2 链中执行,使之正常被打包到 L2 区块中;
Batch-Submitter
,定期从 L2 区块中将交易数据以打包的形式组装到交易:- 打包批量交易
txBatch
提交到 L1 的CTC
合约; - 打包批量状态
stateBatch
提交到 L1 的StateCommitmentChain.sol
- 之后这些交易进入
等待挑战
窗口,挑战方式就是欺诈证明
;
- 打包批量交易
Relayer
,定时从 L2 区块中过滤交易中的SentMessage
事件数据:- 判断当前交易是否过了挑战时间;
- 为此交易生成证明,调用 L1 上的
L1CrossDomainMessenger.relayMessage
函数,使之完成合约检查
然后在内部调用目标合约,最终在 L1 完成 L2 交易的最终目的;
它们的组合通讯流程图如下:
注:
目前所有的 Op 组建,都由官方运行着,欺诈证明还在完善。用户必须要相信官方不会做恶。
3. 如何使用 Op
使用 Op 网络分两种情况:
- 直接使用原生 Token 进行交易,即以太坊,那么:
- 需要先在 L1 访问
L1StandardBridge.sol
进行充值到 Op; - 充值结束后,到账了,可以进行 Op 网络内的交易活动;
- 提现到 L1 的地址;
- 流程到这里闭环
- 需要先在 L1 访问
- 其他协议,比如 ERC-20:
- 先去 Op 网络部署对应的合约;
- 在 L1 的
L1StandardBridge.sol
充值 Token 到 L2 地址; - 到账后,便可自由交易。提现动作和 ETH 的一样。
4. 源码分析 --- 充值与提现
充值部分 --- L1 合约层源码
按照流程,用户需要调用 L1 上的 L1StandardBridge.sol
智能合约充值,如下图所示:
注意,payable
就是 solidity 语法中标明可以接收 ETH 的语法糖。此时充值 ETH 到了 Op 的 L1StandardBridge 跨链桥合约中。
上图,函数走完了,都没有痕迹告诉我们如何在为 L2 的地址充值了 ETH,我们只需要留意其中的 IL2ERC20Bridge.finalizeDeposit.selector
这一行。这里设置了一个 L2 到时需要调用的函数。
上图,结合我们前面的结论 DataTransportLayer
,会定时扫描 L1 区块,从中获取到 TransactionEnqueued
事件,并存储到 LevelDB
数据库。
所以在 _sendXDomainMessag
内部,最终会触发 emit TransactionEnqueued
事件。L1 层面的闭环结束
ERC-20 的充值也是一样的,只是函数不一样。如下图:
// TransactionEnqueued 事件在 enqueue 内发生
function _sendXDomainMessage(
address _canonicalTransactionChain,
bytes memory _message,
uint256 _gasLimit
) internal {
// slither-disable-next-line reentrancy-events
ICanonicalTransactionChain(_canonicalTransactionChain).enqueue(
Lib_PredeployAddresses.L2_CROSS_DOMAIN_MESSENGER,
_gasLimit,
_message
);
}
充值部分 --- L2 层源码
在这里我们主要看 Sequencer
的是如何执行 TransactionEnqueued
中的交易到 L2 的。
在 Sequencer
的启动中,首先是它会进入一个定时从数据库中获取交易的函数,如下图所示:
接下来的调用链是: s.sequnece --> syncQueueToTip --> syncQueue --> syncQueneTransaction
如下图所示,在 syncQueneTransaction
中,调用 GetEnqueue
从远程接口即 DataTransportLayer
服务中获取目标交易数据。最后执行 applyTransaction
执行交易
回到前面合约层的 IL2ERC20Bridge.finalizeDeposit.selector
这一句,最后交易的执行会走到 L2 合约层的 L2ERC20Bridge
合约的 finalizeDeposit
函数,如下图所示,最终 mint 操作完成充值流程,至此闭环。
提现
内容比较多,提现留给下一篇。持续关注
以太坊 layer2: optimism 源码学习 (一)的更多相关文章
- 以太坊 layer2: optimism 源码学习(二) 提现原理
作者:林冠宏 / 指尖下的幽灵.转载者,请: 务必标明出处. 掘金:https://juejin.im/user/1785262612681997 博客:http://www.cnblogs.com/ ...
- Solidity合约记录——(一)如何寻找以太坊真实Solidity源码
在自主学习Solidity智能合约的过程中,第一份入手资料无疑是官方文档.感谢前辈们还能提供出文档的中文翻译,作为我入门的第一手资料:文末附上有用的学习链接{持续更新中} 阅读完基础文档同时上手合约后 ...
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...
- jQuery源码学习感想
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
- MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)
前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...
- MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)
前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)
前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)
前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...
- 我的angularjs源码学习之旅2——依赖注入
依赖注入起源于实现控制反转的典型框架Spring框架,用来削减计算机程序的耦合问题.简单来说,在定义方法的时候,方法所依赖的对象就被隐性的注入到该方法中,在方法中可以直接使用,而不需要在执行该函数的时 ...
随机推荐
- 交互式 .Net 容器版
背景介绍 在之前的文章 - 交互式 .Net 中已经介绍了什么是交互式 .Net,文中是通过 Visual Studio Code 插件的方式实现交互式 .Net 的.现在,我们将使用容器的方式实现交 ...
- 爬取豆瓣喜剧类热门TOP60的电影
学习任务:爬取豆瓣喜剧类热门TOP60的电影并保存在douban.txt文件中. 代码示例: import requests url="https://movie.douban.com/j/ ...
- cut-列过滤
列过滤命令. 语法 cut [选项] 要过滤的字符串 选项 -f 以字段为单位进行分割 -c 以字符为单位进行分割 -b 以字节为单位进行分割 -d 以分割符为单位进行分割,分隔符可以是"冒 ...
- Spring Boot整合Swagger报错:"this.condition" is null
前段时间看到群里有吐槽swagger整合问题,当时没仔细看,总以为是姿势不对. 这两天正好自己升级Spring Boot版本,然后突然出现了这样的一个错误: Caused by: java.lang. ...
- Java 接口返回值集合防止空指针
接口 返回值为一个集合 public interface UserSearchService{ List<User> listUser(); } 接口实现 public List<U ...
- 在CabloyJS中将Webpack生成的文件自动上传到阿里云OSS
背景 阿里云OSS提供了一个Webpack插件,可在Webpack打包结束后将webpack生成的文件自动上传到阿里云OSS中 下面看看在CabloyJS中如何使用该插件 新建项目,并配置MySQL连 ...
- C#中常用的目录|文件|路径信息操作
更新记录 本文迁移自Panda666原博客,原发布时间:2021年5月16日. 说明 .NET的类库API设计的非常优秀,再加上文档docs.com写的非常优秀,写代码给人一种十分优雅的感觉. 获得当 ...
- [WUSTCTF2020]朴实无华-1
1.打开连接只有如下界面: 2.用bp抓包分析包内数据,未发现有用的信息: 3.进行目录扫描,获得robots.txt文件并进行访问: 4.访问/fAke_f1agggg.ph ...
- BUUCTF-神秘龙卷风
神秘龙卷风 通过提示知道压缩包密码是四位纯数字,通过爆破得到 得到一串编码 看样子应该是brainfuck编码 flag{e4bbef8bdf9743f8bf5b727a9f6332a8}
- WPF开发随笔收录-自定义图标控件
一.前言 1.在以前自学的过程中,软件需要使用到图标的时候,总是第一个想法是下载一个图片来充当图标使用,但实际得出来的效果会出现模糊的现象.后来网上学习了字体图标库的用法,可以在阿里云矢量图网站那里将 ...