ETH的設計如何實現自動收益成長?


《巧妙的合約設計,看看stETH如何按天自動發放收益?讓你的ETH參與質押獲得穩定利息》介紹了將ETH兌換為stETH後,每天自動獲得收益的原理。以太坊網路升級為權益證明機制後,用戶透過質押ETH獲得投票權和收益。為解決普通用戶質押32個ETH的麻煩,出現了流動性質押衍生品,如Lido的stETH。用戶質押ETH給Lido後,Lido參與以太坊的權益證明並產生收益,用戶獲得相應的stETH。概念複雜,但利用智能合約的機制實現了stETH收益每天更新卻無需交易的特性。提醒使用風險並非投資建議。

原文標題:《巧妙的合約設計,看看stETH如何按天自動發放收益?讓你的ETH參與質押獲得穩定利息》

來源:ZAN團隊

筆者把自己為數不多的ETH兌換為stETH後,發現stETH每天都在自然成長,不斷獲得收益。但是卻沒有看到帳戶有交易,這是為什麼呢?本文帶大家一起來看看背後的攻略設計,揭開成果的秘密。

1 個stETH 在過去幾天後已經獲得了一些收益

在這之前先介紹一下stETH的流程圖背後的邏輯,以及以太坊的質押(Stake),已經了解了這部分概念的讀者可以直接跳到後面。

最初的以太坊和比特幣一樣是透過工作量證明(Proof of Work,PoW)來作為它因為的共識機制,但是PoW 耗電以及其他安全性和性能上發展的考慮,以太坊從2022 年9 月開始升級為權益證明(Proof of Stake,PoS)。

到底依靠算力挖礦來吸引礦工實現以太坊的思想,搖身一變,變成了依靠大家透過質押ETH獲取投票權,透過投票來獲取收益,從而激勵大家透過PoS的方式來實現共識。

透過質押32 個ETH 可以加入以太坊網絡,可以成為驗證者,負責儲存資料、處理交易以及向區塊鏈添加新區塊。只需運行將交易正確的資源為新區塊並檢查其他驗證者工作,即可獲得ETH 獎勵,這相當於你可以透過質押的方式讓ETH 可以擁有相對穩定的收益。

但是這樣的質押對於一般使用者來說還是太麻煩了,畢竟32個以太坊和一個要能夠實現最高峰無休止以太接入坊網路的專用電腦還是有一定的承載量的。而且質押ETH會造成損失了這於是產生了流動性質押衍生品(Liquid Stake Derivatives,LSD),它旨在解決傳統質押中的勞動力和流動性問題,允許用戶質押32個以下的ETH,以及不需要自己擁有節點,而是把ETH 委託給第三方質押,並獲取相應的質押代幣(如Lido 的stETH 或Rocket Pool 的rETH),這些流動性代幣可以在其他平台上交易、網絡或用於其他金融這樣,用戶既能更方便地參與質押中獲得獎勵,又能保持資金的彈性。

所以stETH 本質上的邏輯就是把ETH 給予Lido,Lido 會用這些ETH 去參與以太坊的PoS 來獲得收益,用戶會得到對應的stETH 作為收益。接下來就是Lido 將收益收益給予這些擁有stETH 的地址。

我們可以看到stETH的收益每天都會自動更新,下圖是我們測試的收益情況,每天的回應都可以檢查數位貨幣包驗證相關內容。

但到這裡我想熟悉智能合約開發的同學就會懷疑了:每天提供這麼少的收益,可能收益都不夠支付GAS 的。

確實,如果麗都採取最簡單的做法來獲得收益的話,那確實難以覆蓋GAS 的成本。從我們的直覺來看,要往如此大規模的地址發送代幣,GAS 是難以想像的。

但確實Lido 就實現了錢包中的stETH 收益自動增長,而且我們並沒有發現該地址有任何交易,這是怎麼實現的呢?

我們找到了Lido的合約https://etherscan.io/token/0xae7ab96520de3a18e5e111b5eaab095312d7fe84 進一步合約的balanceOf方法:

BalanceOf 是符合ERC20 規範的方法,而錢包就是透過該方法取得用戶有多少代幣的。

我們可以看到stETH 的合約中這裡呼叫了getPooledEthByShares 方法。此方法入參是映射(address => uint256) private share;。這代表使用者有多少stETH?顯然不是,不然每天都需要更新每個地址的數據,雖然這樣也可以實現但只要調用合約中的方法來更新股份來實現一次交易就可以更新所有地址的代幣,顯然這樣做GAS 的消耗同樣也是巨大的。

想必到這裡大家已經要猜測合約是怎麼實現的了,我們繼續看看getPooledEthByShares 方法。

可以看到最終回傳的結果是用位址中的sharesAmount乘以_getTotalPooledEther()再除_getTotalShares。

_getTotalPooledEther 代表總共有多少stETH(依照stETH 兌ETH 為1:1 的話也代表有多少ETH),_getTotalShares 代表有多少份額。這樣一算位址每個有多少stETH 就是動態計算出來的了。

舉例來說如果現在共有1000個份額(Shares,則_getTotalShares方法傳回的數量),其中A位址有100份(對應上面的sharesAmount)。這1000個份額對應1000個stETH(或_getTotalPooledEther)回傳的數量那麼就按照這個計算,一個位址就有100 個stETH。那Lido 拿這總得1000 個ETH 去質押獲取到1 個ETH 的收益後回復更新_getTotalPooledEther 為1001,最初總共1000 個stETH 變多變成1001 個了,那麼新出來的計算A 地址就擁有了100 * 1001 / 1000 = 100.1 個stETH。

簡單點說就是每個地址擁有的股份不變,股份對應的stETH變多了,那麼一計算自然stETH就變多了。

我們繼續看程式碼,_getTotalPooledEther中的邏輯是會受到handleOracleReport方法影響,而這個方法又更新合約中的相關資料。具體的呼叫是會透過https://etherscan.io/address/0x852deD011285fe67063a08005c71a85690503Cee非同步呼叫submitReportData更新資料(submitReportData中會呼叫Lido合約的handleOracleReport):

我們每天都會看到有調用更新相關內容,這就是為什麼雖然我們無法將我們的地址獲得收益的交易,但金額仍然每天在變化的原因。

這背後其實體現了以太坊但是ERC20智能合約的一個特點,就是這些ERC20的合約擁有多少代幣不是寫死地址在上面的,而是合約方法返回的,所以可能會出現帳號雖然沒有任何交易,代幣的數量也可能會改變。這一方面讓ERC20合約更加靈活,但是另一方面也給很多對合約不熟悉的朋友帶來了困惑,希望本文可以幫助大家更多的理解智能合約,更安全的和智能的交互。

另外,雖然透過將ETH 質押為stETH 能夠獲得穩定的質押收益,但仍可能存在的風險,本文僅作為質押合約的技術研究參考,不構成任何投資建議。

原文連結

資訊來源:0x資訊編譯自網際網路。版權所有,未經許可,不得轉載

Total
0
Shares
Related Posts