巧妙的合約設計, 看看 stETH 如何按天自動發放收益?讓你的 ETH 參與質押獲取穩定利息
筆者把自己為數不多的 ETH 兌換為 stETH 後,發現 stETH 每天都在自然增長,不斷獲取收益。但是卻沒有看到账戶有交易產生,這是為什么呢?本文帶大家一起來看看背後的巧妙設計,揭开收益發放的祕密。
1 個 stETH 過去幾天後已經有了一些收益
在這之前先介紹一下 stETH 賺取收益背後的邏輯,也就是以太坊的質押(Staking),已經了解這部分概念的讀者可以直接跳到後面。
最初的以太坊和比特幣一樣是通過工作量證明(Proof of Work,PoW)來作為它的共識機制,但是 PoW 因為耗電以及其它安全性和性能上發展的考慮,以太坊從 2022 年 9 月开始升級為權益證明(Proof of Stake,PoS)。
原本依靠算力挖礦來吸引礦工實現共識的以太坊,搖身一變,變成了依靠大家通過質押 ETH 獲取投票權,通過投票來獲取收益,從而激勵大家通過 PoS 的方式來實現共識。
通過質押 32 個 ETH 可以加入以太坊網絡,可以成為驗證者,負責存儲數據、處理交易以及向區塊鏈添加新區塊。只要運行將交易正確打包為新區塊並檢查其他驗證者工作,就會獲得 ETH 獎勵,這樣就相當於你可以通過質押的方式讓 ETH 可以擁有相對穩定的收益。
但是這樣的質押對於普通用戶來說還是太麻煩,畢竟 32 個以太坊和一臺要能夠全年無休接入以太坊網絡的專用計算機還是有一定的門檻的。而且質押 ETH 會使得喪失了這部分 ETH 的流動性。於是就有了流動性質押衍生品(Liquid Staking Derivatives,LSD),它旨在解決傳統質押中的門檻和流動性問題,允許用戶質押 32 個以下的 ETH,以及不需要自己擁有節點,而是把 ETH 委托給第三方質押,並獲取相應的質押代幣(如 Lido 的 stETH 或 Rocket Pool 的 rETH),這些流動性代幣可以在其他平臺上交易、借貸或用於其他金融活動,這樣,用戶既能更便捷參與到質押中獲得獎勵,又能保持資金的靈活性。
所以 stETH 本質的邏輯就是把 ETH 給到 Lido,Lido 會用這些 ETH 去參與以太坊的 PoS 以獲取收益,用戶會得到對應的 stETH 作為憑證。接下來就是 Lido 要把收益發放給這些擁有 stETH 的地址。
我們可以看到 stETH 的收益每天都會自動更新,下圖是我們測試的收益情況,對應每天都可以檢查加密錢包驗證相關內容。
但是到這裏我想熟悉智能合約开發的同學就會疑惑了:每天發放這么少的收益,可能收益都不夠付 GAS 的。
確實,如果 Lido 按照最簡單的做法來發放收益的話,那確實難以覆蓋 GAS 的成本。從我們的直覺來看,要往如此衆多的地址發送代幣,GAS 是難以想象的。
但是確實 Lido 就實現了錢包中的 stETH 收益自動增長,而且我們並沒有發現該地址有任何交易,這是怎么實現的呢?
我們找到了 Lido 的合約 https://etherscan.io/token/0xae7ab96520de3a18e5e111b5eaab095312d7fe84 追溯到合約的 balanceOf 方法:
balanceOf 是符合 ERC20 規範的方法,錢包就是通過該方法獲取用戶有多少 token 的。
我們可以看到 stETH 的合約中這裏調用了 getPooledEthByShares 方法。該方法入參是 mapping (address => uint256) private shares;。這代表用戶有多少 stETH?顯然不是,不然每天都需要更新每個地址的數據,雖然這樣也可以做到只要調用合約中的方法來更新 shares 來實現一次交易就能更新所有地址的 token,但是顯然這樣做 GAS 的消耗同樣也是巨大的。
想必到這裏大家已經要猜到合約是怎么實現的了,我們繼續來看 getPooledEthByShares 方法。
可以看到最終返回的結果是用地址中 sharesAmount 乘以 _getTotalPooledEther() 再除 _getTotalShares。
_getTotalPooledEther 代表總共有多少 stETH(按照 stETH 兌 ETH 為 1:1 的話也代表有多少 ETH),_getTotalShares 代表有多少份額。這樣一算每個地址有多少 stETH 就是動態計算出來的了。
舉例說如果現在一共有 1000 個份額(Shares,也就是 _getTotalShares 方法返回的數量),其中 A 地址有 100 份(對應上面的 sharesAmount )。這 1000 個份額對應 1000 個 stETH(也就是 _getTotalPooledEther)返回的數量。那么按照這個計算,A 地址就對應有 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 能夠獲得看似穩定的質押收益,但是依然有可能的風險存在,本文只作為對質押合約的技術研究參考,不構成任何投資建議。
另外之前我們發布了一篇關於『再質押』的文章 https://www.jinse.cn/news/blockchain/3677017.html ,感興趣的讀者可以繼續閱讀,深入了解更多內容。
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC
7月23:Mt. Gox 比特幣錢包在市場緊縮的情況下轉移了價值 28.2 億美元的 BTC一個引...
悅盈:比特幣68000的空完美落地反彈繼續看跌 以太坊破前高看回撤
一個人的自律中,藏着無限的可能性,你自律的程度,決定着你人生的高度。 人生沒有近路可走,但你走的每...
ZAN Team
文章數量
13粉絲數
0