Aleo收益分配機制GitHub代碼解讀

官方在其最新活躍的代碼開發分支中更新了獎勵機制部分
雖然這一部分不一定是主網上運行的最終確定版
但是我們可以透過目前開發的代碼,了解一下官方對獎勵機制可能的設計.
獎勵機制的代碼在: https://github.com/AleoHQ/snarkOS/blob/feat%2Fexperimental-networking2/consensus/src/rewards/mod.rs
在開始解讀代碼之前, 我們先回答幾個最重要,大家最關心的問題:
Q:礦工還有收益嗎?
A:有,主網上線 10 年內都有挖礦收益, 10年中每年遞減, 直到10年後,出塊獎勵歸零.
Q:礦工一個塊能獲得多少收益
A:第一年在 80 個 aleo 左右, 後續十年,每年遞減
Q:validator 門檻是多少? 能獲得多少收益?
A:100萬 aleo, 每個塊分給 validator 的是 11 個 Aleo (星號)
接下來, 我們帶大家一起詳細的看一下代碼:
先看一下代碼中定義的一些數值:
1 | const NUM_GATES_PER_CREDIT: u64 = 1_000_000; // 1 million gates == 1 credit |
定義兩種代幣 gates/credit 之間的換算關係: 1 credit = 100萬 gates
1 | const STARTING_SUPPLY: u64 = 1_000_000_000 * NUM_GATES_PER_CREDIT; // 1 quadrillion gates == 1 billion credits |
初始供應: 10億枚 aleo
1 | const STAKING_PERCENTAGE: f64 = 0.025f64; // 2.5% |
質押比例, 跟 validator 的收益有關, 後面我們會解讀
1 | const ANCHOR_TIMESTAMP: u64 = 1640179531; // 2019-01-01 00:00:00 UTC |
錨定時間, 應該是主網的啟動時間, 目前先設定為 2019-01-01 00:00:00 UTC
1 | const ANCHOR_TIME: u64 = 15; // 15 seconds |
出塊時間, 是的, aleo 的出塊時間很有可能從 testnet2 的 20s 調整成 15s
接著我們就可以看代碼中的最重要的兩個函數:
1 | /// Calculate the staking reward, given the starting supply and anchor time. |
可以看到, 該函數沒有普通的參數,只有兩個 const 常量參數,所以一旦主網上線, 確定了初始供應和出塊間隔後, 每個塊中的質押獎勵的值就應該是不變的.
獎勵的計算方法為:
獎勵 = (初始供應 * 質押佔比) / 一年總出塊數
其中一年總出塊數的計算是確定出塊間隔後, 用一年的總秒數除以出塊間隔 (15s)
我們帶入目前已經有的一些參數
獎勵 = 10億 aleo 初始供應 * 佔比 2.5% / 一年出塊數: (365 * 24 * 3600 / 15) ~= 11.89
最後向下取整為 11
即每個塊, validator(們) 可以獲得 11 個 aleo,
注:
-
注意我們每個公式中的 aleo 都要乘以 100萬倍換算成 gates, 然後再帶入計算, 得出一個數值
下面也是相同的, 不再做此提示. -
這裡不是說成為 validator 就能每個塊都能獲取這麼多獎勵, 只是說 validator 們能夠從中分到 11 個 aleo, 具體網絡上會有多少 validator, 以及每個塊
中的獎勵如何在 validator 中去分, 歡迎關注我們, 我們會在官網代碼進一步完備後做第一時間的解讀.
1 | pub fn coinbase_reward<const STARTING_SUPPLY: u64, const ANCHOR_TIMESTAMP: u64, const ANCHOR_TIME: u64>( |
礦工獎勵的計算比較複雜, 通過函數定義,我們可以看到, 出塊獎勵是動態變化的, 跟 num_validators: validator 的個數, timestamp: 出塊時的時間戳, block_height 塊高這三個
動態參數有關
我們一步一步來看
首先我們需要了解 anchor_reward:
1 | pub fn anchor_reward<const STARTING_SUPPLY: u64, const ANCHOR_TIME: u64>() -> u64 { |
anchor_reward 是一個錨定的基準值
這個值也是確定了初始供應和出塊間隔後就不再變化了
簡單來說 anchor_reward = 2 * 初始供應 / (十年出塊總數的平方)
我們帶入計算一下 anchor_reward = 2 * 初始供應 10 aleo 億 / (十年出塊: 21024000 的平方) ~= 4.524
最後向下取整為: 4
然後礦工獎勵計算中還涉及一個用來動態調節的函數 factor:
1 | /// Calculate the factor used in the target adjustment algorithm and coinbase reward. |
factor = 分子 / 分母
分子: (當前時間 - 初始時間) - (當前塊高 * 出塊間隔)
可以看到, 分子表示的是理論時間出塊時間的時間差
比如:
aleo 主網的啟動時間設置為 2023-01-01 00:00:00 UTC, 理論上來說, 15s 出一個塊, 那麼出了 24 * 3600 / 15 = 5760 個塊之後, 當前時間應該是
2023-01-02 00:00:00 UTC, 但實際上當前時間可能會有一定的偏差, 比如 2023-01-02 00:00:05 UTC, 慢了 5s.
這里分子算的就是這個偏差
分母: validator 個數 * 出塊間隔
我們化簡下,直接先用分子除以出塊間隔得到以塊為單位的時間差
所以, 這個 factor 實際上是: 塊差 / validator 個數
factor 最終會被引入到出塊獎勵中, 用來引導礦工調整出塊頻率, 同時也用來引導參與 validator 的個數
這裡我們可以看到, 塊差越大, factor 就越大, validator 個數越大, factor 就越小
有了 anchor_reward 和 factor, 我們再回頭看出塊獎勵的代碼:
1 | let block_height_around_year_10 = estimated_block_height(ANCHOR_TIME, 10); |
block_diff 是 (十年出塊總數 - 當前塊高), 噹噹前塊高超過十年出塊總數時, 這個值取 0
通過這個 block_diff 我們就可以看出, 其它條件不變, 塊高越高, 收入越少, 知道出 10 年的塊後, 獎勵歸零
anchor_reward 我們之前已經算過了, 初始供應 10億 aleo, 出塊間隔為 4 的情況下, 這個值為 4
礦工如果想獲得更多的收益, 前面的這些部分都是沒法調節的
最後這一部分 1 / 2^factor
回到前面對 factor 的解讀
- 塊差越大, factor 就越大,礦工出塊收益越小
- validator 個數越大, factor 就越小, 礦工出塊收益就越大
所以 aleo 團隊通過這個 factor 的設計來引導礦工
- 將出塊頻率控制在 15s 作妖, 不要產生較大的塊差
- 積極參與質押,成為 validator
帶入各個參數後, 我們算得
第一年主網啟動時, 礦工收益: 83 Aleo
第二年: 67 Aleo
第三年: 58 Aleo
…
第十年: 8 Aleo
第十一年: 0
注:本文所述的獎勵分配機制為官方 GitHub 代碼解讀而來,並非最終確定版,更多消息請關注 Aleo官方公告!