以太坊 layer2: optimism 源碼學習(二) 提現原理
作者:林冠宏 / 指尖下的幽靈。轉載者,請: 務必標明出處。
GitHub : //github.com/af913337456/
出版的書籍:
本次是系列文章,這是第二篇。第一篇在: 以太坊 layer2: optimism 源碼學習 (一)
目錄:
- 為什麼存在提現動作
- 提現的原子性
- 提現的調用鏈
- 源碼中的提現實現
- 下一篇核心組件
Relayer
的源碼實現
為什麼存在提現動作?
OP 本質是個大型的 DApp,我們要使用它,就要先從以太坊的主網充值 Token 進去,充值的原理及其源碼分析在第一篇文章中。
用戶在 OP 裡面進行了系列的交易動作後,需要把 Token 轉回到主網,才能與其他的 DApp 的交互或主網轉賬。因此對應地,OP 提供了提現 Token 到主網的功能。
提現的原子性
雖然在 OP 中的交易都直接發生在 OP 的網路中,比如轉賬的地址是 OP 網路中的以太坊地址。但是所有的交易都會被同步到以太坊主網中,與 OP 的合約發生實際的主網交互。這就意味著,地址所在 OP 中 Token 餘額的變化也會導致主網上的餘額變化。這一點見第一篇文章中的 OP 原理介紹。
提現的調用鏈
用戶是提現發起的對象,提現遵循下面的步驟:
- 用戶向 OP 的
Sequencer
發起提現交易; - 這筆交易是一次合約調用交易,指向
L2StanderBridger.sol
中的withdraw
函數; withdraw
函數中會構造最後在主網合約中發起真正提現的函數數據;- 交易被 OP 網路正常打包;
- 交易被
Batch-Submitter
提交到主網CTC
合約,走正常的挑戰機制; - 挑戰期過後,
Relayer
為此交易生成證明,調用 L1 上的L1CrossDomainMessenger.relayMessage
函數,使之完成合約檢查
然後在內部調用目標合約,最終在 L1 完成 L2 交易的最終目的,用戶的 Token 在 L1 地址上得到了提現; - 提現閉環。
源碼中的提現實現
首先是 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
函數,其源碼如下: