作者:林冠宏 / 指尖下的幽靈。轉載者,請: 務必标明出處。
掘金:https://juejin.im/user/1785262612681997
部落格:http://www.cnblogs.com/linguanh/
GitHub : https://github.com/af913337456/
出版的書籍:
- 《1.0-區塊鍊DApp開發實戰》
- 《2.0-區塊鍊DApp開發:基于公鍊》
前序:
對于區塊鍊每個階段的風口産品,我都會挑選其中某個研究其源碼,當作學習并增加經驗。早前看的是
,難度巨大而能力有限,遂轉于
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 元件或使用者來調用,包含不限于有:合約
-
,基于 geth 源碼改造的鍊,運作在 Op 生态裡;L2 側鍊
-
垮鍊橋合約,用來處理充值 Token 到 Op 位址或從 Op 位址提現到 L1 位址 所用;L1StandardBridge.sol
-
規範處理CanonicalTransactionChain.sol
的交易,下面簡稱L2 --> L1
;CTC
-
跨鍊信使合約,裡面主要編寫進行了各種要觸發跨鍊事件的函數。L1CrossDomainMessenger.sol
-
-
,定時掃描 L1 區塊,從中擷取到DataTransportLayer
事件,并存儲到TransactionEnqueued
資料庫;LevelDB
-
:Sequencer
- 接受使用者發來 L2 的交易;
- 定期從資料庫中擷取
存儲的DataTransportLayer
事件資料,并把交易在 L2 鍊中執行,使之正常被打包到 L2 區塊中;TransactionEnqueued
-
,定期從 L2 區塊中将交易資料以打包的形式組裝到交易:Batch-Submitter
- 打包批量交易
送出到 L1 的txBatch
合約;CTC
- 打包批量狀态
送出到 L1 的stateBatch
StateCommitmentChain.sol
- 之後這些交易進入
視窗,挑戰方式就是等待挑戰
;欺詐證明
- 打包批量交易
-
,定時從 L2 區塊中過濾交易中的Relayer
事件資料:SentMessage
- 判斷目前交易是否過了挑戰時間;
- 為此交易生成證明,調用 L1 上的
函數,使之完成L1CrossDomainMessenger.relayMessage
然後在内部調用目标合約,最終在 L1 完成 L2 交易的最終目的;合約檢查
它們的組合通訊流程圖如下:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAjM2EzLcd3LcJzLcJzdllmVldWYtl2PnBnauYDO0IGZkRzYjdzNxIjYlVTNxgzM4YTM0UGOwUTN2UjYvwlNzQDO0ETMtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.jpg)
注:
目前所有的 Op 組建,都由官方運作着,欺詐證明還在完善。使用者必須要相信官方不會做惡。
3. 如何使用 Op
使用 Op 網絡分兩種情況:
- 直接使用原生 Token 進行交易,即以太坊,那麼:
- 需要先在 L1 通路
進行充值到 Op;L1StandardBridge.sol
- 充值結束後,到賬了,可以進行 Op 網絡内的交易活動;
- 提現到 L1 的位址;
- 流程到這裡閉環
- 需要先在 L1 通路
- 其他協定,比如 ERC-20:
- 先去 Op 網絡部署對應的合約;
- 在 L1 的
充值 Token 到 L2 位址;L1StandardBridge.sol
- 到賬後,便可自由交易。提現動作和 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 操作完成充值流程,至此閉環。