作者: StarkWare
本文意在講解 StarkEX 為支持快速取款(Fast Withdrawel)(在一個區塊時間內從 Layer-2 中取款到任意 Layer-1 地址)而提出的解決方案,本方案的優點在于,其速度完全獨立于 L2 的運營者生成有效性證明的速度。
快速取款模塊已經運行在以太坊主網的 StarkEx 上(自 2020 年 10 月 StarkEx 2.0 發布始),并且賦能了 DeversiFi 交易所和 dYdX 交易所。
而下文我們講解的方案除了快速取款以外,還有非常多的使用場景。我們先來了解一下需求是什么,
需求
區塊鏈使得兩方之間的免信任交互成為可能,Alice 想發布一筆僅在特定條件滿足時才能執行的交易;Bob 希望在條件滿足時能直接執行 Alice 的交易、不必再次獲得 Alice 的許可,我們把支持此類交互模式的元件稱作 “有條件交易(Conditional Transaction,CT)”,
在 L1 上實現 CT 不需要什么奇思妙想,因為智能合約可以保證時間和交易執行的耦合。但如果要求在 L2 中實現,那就有些挑戰了,比如,在 StarkEx 中,交易發起人簽名之后把交易傳遞給運營者,后者有責任來執行這筆交易,可是你用什么辦法來阻止運營者在所需條件滿足之前就執行這筆交易呢?
在本文中,我們只聚焦于在 L2 上實現依賴于 L1 事件(記作 L2 | L1)的 CT。也就是說,這種 CT 要能保證,運營者僅能在某個 鏈上事件 發生之后才能執行某筆簽過名的交易,更進一步,我們將加入一種依賴于另一個 L2 中事件(記作L21 | L22 )的 CT,從而支持 StarkEx 實例之間以及 StarkNet 中的互操作性,
下面,我們來形式化這種鏈上事件的概念,看看我們如何在 StarkEx 中的 CT 如何利用它,
有條件交易簡介
鏈上事件的注冊
CT 使用了 Fact Registry 合約來跟蹤鏈上事件,實際上,只有在一個 Fact Registry 合約中注冊了的事件,才能 “解鎖” CT。舉個例子,如果 Alice 直接在以太坊鏈上轉賬了 1 ETH 給 Bob(而不是通過 Fact Registry 合約),那 CT 是不能因此滿足執行前提的,
在上面這個案例中,Fact Registry 合約需要一個函數 transfer(),Alice 傳入 Bob 的地址作為收款方。transfer() 函數做兩件事:(1)把需要轉移的 ETH 發送給收款方;(2)保存對這筆轉賬的記錄,比如存儲這筆轉賬相關參數(發送者、收款方、數額)的哈希值,到合約的存儲項中。Fact Registry 合約還帶有一個 isValid() 函數,接受一條哈希值作為參數,返回一個布爾值 —— 如果該條輸入的哈希值等于合約中記錄的某條哈希值,就返回 True。如此,這個記錄在合約中的哈希值,就可以當成是一個事實(某個事件已經發生)的證明,這個為 Fact Registry 合約引入一個新的事實的過程,通常稱為 “事實注冊”。
一筆簽過名的 CT 所包含的鏈上事件的指紋有兩個字段(實際上是這兩個參數的哈希值):(1)一個 Fact Registry 合約的地址;(2)上述合約中應當記錄的事實,
StarkEx 有條件交易
StarkEx 會批量打包 Layey-2 中的交易,并使用一條發送到鏈上的 STARK 證明來結算這些交易。如果某一批次中包含 CT,StarkEx 將保證相關的事實已經注冊,以便能清算該批交易;否則,整批交易都會回滾。
有條件交易的案例
在本部分,我們會提出一些應用場景,并指出 CT 如何能用在這些場景中,
詳細案例 —— 快速取款
在任意 L2 方案中,最初級的從 L2 轉出資金到 L1 中的辦法便是終局化一次 L2 的狀態更新(在該次更新中包含一筆取款交易)。在基于有效性證明的系統(比如 StarkEx)中,終局化一次 L2 的狀態更新需要在鏈上提交一個相應(于此次更新)的有效性證明,一般來說需要 10 分鐘,這就意味著,如果用戶使用這種方式來取款,就不得不等待至少 10 分鐘,
而快速取款的用意正是為了解耦這種(取款對 L2 狀態更新的)依賴,讓用戶能夠在 “區塊時間” 內免信任地將資金取出,也即,就像使用普通的以太坊合約一樣,
那到底是怎么個流程呢?如果 Alice 想要從 L2 中取出 1 ETH 到 L1,Alice 可以在 L2 上簽名一條將 1 ETH 轉移給流動性提供者(LP)的 CT,條件是 LP 在 L1 上轉移 1 ETH(減去一些手續費)給 Alice,Alice 的 CT 僅能在她收到 L1 上的轉賬之后才能執行,所以她不會面臨對手方風險,
我們來看一個能夠協助 CT 的簡易的 Fact Registry 合約:
我們可以看到這個合約有一個 payabe 函數 transfer(),它的功能有兩個:
(1)轉移一定數量的 ETH 到某個地址
(2)登記 keccack(amount, address, nonce)
Alice 簽發的 CT 只有 keccack(1 ETH, Alice, nonce) 在 Fact Registry 中注冊之后才能執行,而這個事實,也只有在給 Alice 的 1 ETH 轉賬發生了之后才能成功注冊,Alice 可以無需信任地取出 1 ETH,整個過程只需她的前面,和 LP 在以太坊鏈上發起的一筆交易,
更多應用場景
類似的流程可以捕捉到下列類型的事件,從而 L2 的 CT 也可以有更多的用途,例如:
- 如果 ETH 的價格跌到了 1010 DAI(可以通過一個已知的資訊輸入服務在鏈上注冊),Alice 希望在 L2 賣出 1 ETH,換回在 L1 上的 1000 DAI
- Alice 希望在 L2 上給 Bob 10 ETH,只要 Bob 以 Alice 的名義在 Alice 指定的 dApp (比如 Aave 或者 Compound)中存入 9.5 ETH
- Alice 希望在 DeversiFi 的 L2 上給 Bob 10 ETH,只要 Bob 在 dYdX 的 L2 中給 Alice 的賬戶存入 9.5 ETH
總結
CT 的第一種用途是快速取款,但 StarkEx 運營者可以用這一元件實現許多種類的 L2-L1 交互,