BitShares私鏈架設(二)

在上一篇文章裡,我們整理了如何在自己的環境裡啟動一條BitShares的私鏈,這是一條完整的區塊鏈,架構上和交易所上的BitShares公鏈一模一樣,只是私鏈通常是不對外的,因此所有交易和帳號都由你自行控制。

在繼續往下介紹前,有一些區塊鏈應用的基本觀念需要加以說明,世界上第一條區塊鏈是2009年由中本聰建立,也就是現今比特幣(Bitcoin/BTC)底下的那條鏈。你應該也聽過,區塊鏈是完全去中心化的,所有節點共同維護一份交易帳本,彼此之間透過所謂的共識機制(Consensus)來決定以誰的資料為準。中本聰為了解決共識問題,設計了一個數學的解題流程,讓所有節點彼此競爭,最快算出答案的人就可取得記帳權,並得到獎勵,這個機制就是工作量證明(POW,Proof of Work),也就是挖礦。

什麼是挖礦

網路上關於共識機制和挖礦的文章太多了,我不在此重述,有興趣請自行搜尋,工作量證明(POW)這個邏輯到目前為止並沒有嚴重瑕疵,確實可以解決共識問題,但是因為這幾年比特幣價值被炒的太高,連帶讓挖礦獎勵(目前是6.25顆比特幣,約等同於20萬美金)成為投資者眼中的金雞母,最後導致中本聰所設計的數學解題模型變成一種軍備競賽,礦工紛紛投入巨大的設備成本以求贏得每一個區塊的記帳權,這樣惡性競爭的結果就是能源的大量浪費,已失去當初設立工作量證明(POW)這種架構的立意。

既然工作量證明的思維難免會落入比肌肉的惡性循環,那何不採用其他更有效率且不耗能的方法解決共識問題?這就是目前新一代共識機制的想法,而以持有量多少決定記帳權與獎勵的POS(Proof of Stake)就屬於此類。舉例而言,乙太坊(Ethereum)目前正在從POW過度到POS,預期可以減少99.98%的能源消耗,但過程並不順利,POW陣營的人並不願意輕易放棄手中的利益和投入挖礦的成本,POS本身也仍有決定權被大股東(金主)把持的隱憂,我們只能靜觀其變。

對於私鏈來講,以上這些都不是問題,私鏈的節點基本上都是自行控管,也無須對外開放,因此採取哪一種共識機制基本上都沒有什麼差別。POS可能是未來幾年區塊鏈共識機制的核心想法,但其架構上仍太過簡單,記帳權永遠被幾個大股東把持,獎勵也幾乎全部流向這些人的錢包,所謂去中心化的區塊鏈自治精神,自然就無法維持。BitShares的作者Daniel Larimer在設計時就考慮到這一點,所以採取了更新一代的共識機制,叫做DPOS代理權益證明,也就是讓鏈上所有持有者定期投票選舉出所謂見證人(witness)的角色,並由這些人負責記帳,當然也會提供獎勵給他們。如果有惡意竄改交易資料或不穩定的見證人出現,所有持有者都有權在下一輪投票將他的記帳角色收回,並重新選舉出另一個,這就是Delegate的精神,和民主制度下的代議政治,基本上是一樣的。

DPOS

花這些篇幅說明共識機制,並非要賣弄知識或者讓看的人更辛苦,而是真實世界的所有區塊鏈,不管公鏈私鏈,沒有共識機制是無法運作的。我們已經啟動了一個BitShares的節點,並且知道它是採用DPOS的共識機制,那麼這些事情在底下是如何動作的?這才是本篇文章的主題。

記得前一篇啟動第一個節點的兩個設定檔嗎?為了讓共識機制工作,裡面有幾個設定是相關的,我們先回頭看第一個節點執行時的訊息:

1160441ms th_a       main.cpp:230                  main                 ] Started BitShares node on a chain with 102 blocks.
1160441ms th_a       main.cpp:231                  main                 ] Chain ID is 59af7726129cb6bb72bb607724882469a47912acb08319a1e65ecc88b0d6b974
1161002ms th_a       witness.cpp:272               block_production_loo ] Generated block #103 with 0 transaction(s) and timestamp 2022-05-29T07:19:20 at time 2022-05-29T07:19:21
1180000ms th_a       witness.cpp:272               block_production_loo ] Generated block #104 with 0 transaction(s) and timestamp 2022-05-29T07:19:40 at time 2022-05-29T07:19:40
1185000ms th_a       witness.cpp:272               block_production_loo ] Generated block #105 with 0 transaction(s) and timestamp 2022-05-29T07:19:45 at time 2022-05-29T07:19:45
1190000ms th_a       witness.cpp:272               block_production_loo ] Generated block #106 with 0 transaction(s) and timestamp 2022-05-29T07:19:50 at time 2022-05-29T07:19:50
1195001ms th_a       witness.cpp:272               block_production_loo ] Generated block #107 with 0 transaction(s) and timestamp 2022-05-29T07:19:55 at time 2022-05-29T07:19:55
1200000ms th_a       witness.cpp:272               block_production_loo ] Generated block #108 with 0 transaction(s) and timestamp 2022-05-29T07:20:00 at time 2022-05-29T07:20:00

從上面的輸出我們可以知道,這條鏈每5秒會產生一個區塊,這個數值是創建鏈的時候就設定好的,那麼問題來了,這些區塊是由誰產生的,又是由誰負責驗證並將交易寫入的?POS/DPOS沒有挖礦和礦工的概念,每個節點都會產生區塊,並且由所謂的見證人(witness)負責將交易打包寫入,那這些邏輯實際上又是發生在哪裡,怎麼設定或改變呢?

答案就在genesis.json和config.ini這兩個檔案裡,genesis.json顧名思義是創建鏈的初始參數(initial parameter),所以我們必須替這條鏈先建立若干初始見證人(initial witness),一般是單數,BitShares公鏈上是21個,這裡我們只建立3個;如果沒有先把這些帳號(account)建立起來,這條鏈是不會產生區塊的,你可以用記事本打開genensis.json,在檔案末端就會看到這3個初始見證人的資料:

  "initial_active_witnesses": 3,
  "initial_witness_candidates": [
    {
      "owner_name": "w1-0",
      "block_signing_key": "BTS6WqFcNmb8DA8SG2HJDL23TzSKk67HrCf6qTeqXhbCcohi11epm"
    },
    {
      "owner_name": "w1-1",
      "block_signing_key": "BTS6WqFcNmb8DA8SG2HJDL23TzSKk67HrCf6qTeqXhbCcohi11epm"
    },
    {
      "owner_name": "w1-2",
      "block_signing_key": "BTS6WqFcNmb8DA8SG2HJDL23TzSKk67HrCf6qTeqXhbCcohi11epm"
    }
  ],

這裡有兩個對BitShares非常重要的訊息,一個是帳號(account),一個是公鑰(public key),我們必須先對此有一定的了解,才能繼續後面的應用與開發。

非對稱加密(Asymmetric cryptography),或稱公鑰加密(Public-key cryptography)是密碼學的一個演算法,大約是在1974年由Ralph C. Merkle提出,1976年Whitfield Diffie與Martin Hellman以單向函式與單向暗門函式為基礎,實作了第一代的應用基礎,目前廣泛在各種需要加密的場合中均可見其蹤影。中本聰創立比特幣(Bitcoin)時,也是採用非對稱加密作為主要的加密架構,所有交易需要持有者的私鑰簽章,並讓礦工以公鑰驗證其正確性,方可寫入區塊。私鑰必須由資金持有者妥善保存,遺失私鑰除了代表你的錢可能會被偷走外,也代表你永遠無法再動用這些資金,據統計目前大概有20%的比特幣是無法動用的,其中最大的原因就是私鑰遺失。

BitShares在交易安全上,也是採用類似的作法,公鑰驗證交易,私鑰簽章,但是為了開發應用方便,BitShares引入了帳號(account)的抽象概念,讓難以理解和操作的公私鑰有了一個比較簡易的呈現方式。要使用BitShares發幣交易,你必須先註冊(register)一個帳號,這其實就是產生一組公私鑰,並將公鑰(public key)連同帳號名稱匯入區塊鏈,這樣的好處是不用每次交易都要像比特幣一樣,將自己的公鑰打包進交易送上節點,對於交易紀錄和其他功能,用帳號概念也比較容易理解。

回到剛才的截圖,我們在genesis.json裡定義了三個帳號:w1-0/w1-1/w1-2,連帶他們的公鑰,當作初始的見證人,這樣區塊鏈建立時,才能夠產生區塊並驗證交易。

單是這樣就夠了嗎?當然不夠,這些初始見證人必須綁定在某個節點,才能夠執行對應的工作,這就是config.ini裡的相關設定:

required-participation = 0
# set up 3 witness accounts
witness-id = "1.6.1"
witness-id = "1.6.2"
witness-id = "1.6.3"
# import witness key pair
private-key = ["BTS6WqFcNmb8DA8SG2HJDL23TzSKk67HrCf6qTeqXhbCcohi11epm","5JjzogP6V1TciYQHthBLPnmj5cyrYLfwfoDeY6rpG4mcNUd7hDq"]
#

我們在第一個節點綁定了三個見證人,其ID是1.6.1/1.6.2/1.6.3,這裡沒有帳號,而是用BitShares的Object ID代表,並且要將genesis.json裡對應公鑰的私鑰匯入,見證人的驗證動作才會開始。說實話BitShares在這些地方做得很不清楚,讓需要架設私鏈的人很痛苦,不過對公鏈來講,只要第一個區塊開始產生,並且能夠驗證,後面的事情就應該由鏈上的參與持有者透過DPOS規則進行,這些初始化的設定理當漸漸退場,所以我們也無須太過糾結這些為了階段目標設計的功能好不好用。

如果你的BitShares將來希望開放讓持有者成為見證人,那麼這些初始化的設定自然就不符使用,以DPOS的精神來講,成為見證人的方式就是透過選舉,你要先累積一定的資金(並鎖住),然後昭告天下你想要參選,鏈上的使用者如果同意,就會把選票投給你,區塊鏈本身有一個定時執行的程序,會進行見證人改選,在公鏈上是一小時一次,所以下一個小時選舉結束,你的帳號就會出現在見證人清單中,這時候你在你的節點上設定對應的ID和私鑰,就可以開始驗證交易,產生區塊,和領取獎勵,直到某次選舉你落選為止。

(實際完成以上目的的程序比描述複雜很多,日後我會整理一篇文章說明)

回到我們的第一個節點,這三個見證人不是選舉產生的,是在創建鏈的時候直接指定的,這當然違反去中心化區塊鏈的自治精神,但是對於私鏈,這確實是最簡單的作法,反正底下有3個見證人默默的在驗證每筆交易,並寫入新的區塊,只要保管好私鑰,理論上是不會有什麼風險的。那我們如何確認見證人有正確的在工作呢?只有一個節點是不容易看出來的,我們先替這條鏈加上第二個節點吧。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。