作者:林冠宏 / 指尖下的幽靈。轉載者,請: 務必標明出處。
GitHub : https://github.com/af913337456/
出版的書籍:
前序:
對於區塊鏈每個階段的風口產品,我都會挑選其中某個研究其原始碼,當作學習並增加經驗。早前看的是
zkSync
,難度巨大而能力有限,遂轉於Optimism
。
本次是系列文章,這是第一篇。
這裡就不說什麼是 Layer2 了,可以去網路搜尋其它文章來閱讀。在 Layer2 的擴容方案中目前有 3 種,Rollups
是其中一種,稱為打包
。打包又分兩大派別:
這兩派的風格各異,特點突出。Optimistic rollups
對智慧合約
的支援可以說是完全相容,而 ZK rollups
目前對智慧合約支援不友好,但是在交易提款
上鍊這塊非常快、更安全卻計算量巨大,技術難度複雜。關於它們的對比
,我後續再寫篇文章詳細說說
Layer2 是公鏈下的第二層。比如安卓系統下的底層軟體。
Optimism,下面簡稱 Op,是基於 Optimistic rollups
方案所實現的 Layer2 應用,下面簡稱 L2。作用是幫助 以太坊
擴容以及加速交易。
特點如下:
欺詐證明
;雖說 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
:
DataTransportLayer
儲存的 TransactionEnqueued
事件資料,並把交易在 L2 鏈中執行,使之正常被打包到 L2 區塊中;Batch-Submitter
,定期從 L2 區塊中將交易資料以打包的形式組裝到交易:
txBatch
提交到 L1 的 CTC
合約;stateBatch
提交到 L1 的StateCommitmentChain.sol
等待挑戰
視窗,挑戰方式就是欺詐證明
;Relayer
,定時從 L2 區塊中過濾交易中的 SentMessage
事件資料:
L1CrossDomainMessenger.relayMessage
函數,使之完成合約檢查
然後在內部呼叫目標合約,最終在 L1 完成 L2 交易的最終目的;它們的組合通訊流程圖如下:
注:
目前所有的 Op 組建,都由官方執行著,欺詐證明還在完善。使用者必須要相信官方不會做惡。
使用 Op 網路分兩種情況:
L1StandardBridge.sol
進行充值到 Op;L1StandardBridge.sol
充值 Token 到 L2 地址;按照流程,使用者需要呼叫 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
);
}
在這裡我們主要看 Sequencer
的是如何執行 TransactionEnqueued
中的交易到 L2 的。
在 Sequencer
的啟動中,首先是它會進入一個定時從資料庫中獲取交易的函數,如下圖所示:
接下來的呼叫鏈是: s.sequnece --> syncQueueToTip --> syncQueue --> syncQueneTransaction
如下圖所示,在 syncQueneTransaction
中,呼叫 GetEnqueue
從遠端介面即 DataTransportLayer
服務中獲取目標交易資料。最後執行 applyTransaction
執行交易
回到前面合約層的 IL2ERC20Bridge.finalizeDeposit.selector
這一句,最後交易的執行會走到 L2 合約層的 L2ERC20Bridge
合約的 finalizeDeposit
函數,如下圖所示,最終 mint 操作完成充值流程,至此閉環。
內容比較多,提現留給下一篇。持續關注