以太坊 layer2: optimism 源碼學習(二) 提現原理

作者:林冠宏 / 指尖下的幽靈。轉載者,請: 務必標明出處。

掘金://juejin.im/user/1785262612681997

部落格://www.cnblogs.com/linguanh/

GitHub : //github.com/af913337456/

出版的書籍:


本次是系列文章,這是第二篇。第一篇在: 以太坊 layer2: optimism 源碼學習 (一)


目錄:

  • 為什麼存在提現動作
  • 提現的原子性
  • 提現的調用鏈
  • 源碼中的提現實現
  • 下一篇核心組件 Relayer 的源碼實現

為什麼存在提現動作?

OP 本質是個大型的 DApp,我們要使用它,就要先從以太坊的主網充值 Token 進去,充值的原理及其源碼分析在第一篇文章中。

用戶在 OP 裡面進行了系列的交易動作後,需要把 Token 轉回到主網,才能與其他的 DApp 的交互或主網轉賬。因此對應地,OP 提供了提現 Token 到主網的功能。

提現的原子性

雖然在 OP 中的交易都直接發生在 OP 的網路中,比如轉賬的地址是 OP 網路中的以太坊地址。但是所有的交易都會被同步到以太坊主網中,與 OP 的合約發生實際的主網交互。這就意味著,地址所在 OP 中 Token 餘額的變化也會導致主網上的餘額變化。這一點見第一篇文章中的 OP 原理介紹。

提現的調用鏈

用戶是提現發起的對象,提現遵循下面的步驟:

  1. 用戶向 OP 的 Sequencer 發起提現交易;
  2. 這筆交易是一次合約調用交易,指向 L2StanderBridger.sol 中的 withdraw 函數;
  3. withdraw 函數中會構造最後在主網合約中發起真正提現的函數數據;
  4. 交易被 OP 網路正常打包;
  5. 交易被Batch-Submitter 提交到主網 CTC 合約,走正常的挑戰機制;
  6. 挑戰期過後,Relayer 為此交易生成證明,調用 L1 上的 L1CrossDomainMessenger.relayMessage 函數,使之完成合約檢查然後在內部調用目標合約,最終在 L1 完成 L2 交易的最終目的,用戶的 Token 在 L1 地址上得到了提現;
  7. 提現閉環。

源碼中的提現實現

首先是 L2 上的 withdraw 函數,如下圖所示,參數細節描述在圖中。要知道同個地址的私鑰是一樣的,意味著用戶在 OP 的地址,在主網上,一樣是這個私鑰所擁有所有權。

withdraw 函數組裝 L1 合約上的目標最終提現函數。如下圖所示,留意這句重點 IL1StandardBridge.finalizeETHWithdrawal.selector,和充值流程中的 deposit.selector異曲同工的做法。

最終 Relayer 會調用到的 L1CrossDomainMessenger.relayMessage 函數,在這個函數裡面,就會把前面包裝的,對應到 L1StandardBridge.sol 合約中的 finalizeETHWithdrawal 函數給執行掉。實現最終的提現。如下圖所示。

上圖 relayMessage 函數中,_target 就是合約 L1StandardBridge.sol_message 就是被 L2StanderBriger.sol 的提現函數中包裝的數據,如下:

message = abi.encodeWithSelector(
    IL1StandardBridge.finalizeETHWithdrawal.selector,
    _from,
    _to,
    _amount,
    _data
);

這個 message 就是對應 relayMessage 函數中的 _message。最終執行到 L1StandardBridge.sol 中的 finalizeETHWithdrawal 函數,其源碼如下:

下一篇核心組件 Relayer 的源碼實現