作者:Nico Preti
來源:https://btctranscripts.com/bitcoinplusplus/layer-2/exploring-p2p-hashrate-markets-v2
原文為作者在 Bitcoin++ 的 Layer2 專題大會上的演講的轉錄稿,由 sahil-tgs 通過 review.btctranscripts.com 轉錄。
引言
各位好,我叫 Nico,是 Rigly 的聯合創始人,我們是一家點對點的哈希率市場。這場演講的結構是這樣的:首先,我們先聊聊什麼是 “哈希率”、協調挖礦任務在網絡中分發的協議;然後,稍微介紹一下哈希率市場的發展歷程;最後,我們如何可以利用 Layer 2 來打造哈希率市場,這也是我們出現在這場會議上的理由。
哈希函數和哈希率
那麼,什麼是 “哈希率” 呢?
你看,這是一個哈希函數的輸出。哈希函數就是,你把一個 “原像(preimage)” 投進去,它會輸出一個映像(哈希值)。
在比特幣的區塊瀏覽器查看區塊的時候,你會看到頂部有一個哈希值,它的十六進制形式以一連串的 0 開頭。這個設計源自 Adam Back 的 “Hashcash” 項目。比特幣的哈希率也都基於這種 hashcash 算法。
關於它是怎麼工作的,你可以訴諸一種簡單的數學:我們有 0 的 k 次冪(0^k)。屏幕上右邊的這個輸出(或者說映像),我們希望它以一定數量的 0 開頭。因此,0^k 基本上就是難度,以開頭要有多少個 0 為度量單位。
如果用代數來表示,那麼我們可以寫成一個函數,表示 X 的哈希值(H(x));以 x 為輸入,希望輸出的開頭是一串 0 。這個函數的更好的表示方法是,你有一種哈希函數(H(s, c) ),它的 “服務字符串” 是 s,而 c 是一個計數器。這個計數器會遞增。服務字符串是給這個哈希函數賦予實際意義的東西;不然的話你就只是在哈希一堆亂七八糟的東西,你的確可以證明,這個數字進入這個哈希函數之後就會得到這個輸出,但這沒有任何實際意義。所以服務字符串就是效用,在我們這裡就是比特幣區塊。這個服務字符串是我們準備在整個網絡中確認的交易所彙集而成的一個區塊頭。
Hashcash 項目使用 SHA-1,輸出是 160 比特,我記得曾經將 k 設為 20,也就是你要嘗試 100 萬次才能找出一個正確的原像。比特幣使用 256 比特,輸出大得多,你要嘗試的次數也多得多。Hashcash 與比特幣的一個重大區別在於,Hashcash 在難度中使用 2 的 k 次冪(2^k),意味著在一個難度週期中,難度要麼倍增、要麼減半;而在比特幣中,我們需要更加精準地調控每一個週期(2016 個區塊)的難度。所以,我們將 k 變成一個浮點數,這樣在調整難度時可以更加精確。每隔 2016 個區塊,我們就要調整接下來一個週期的難度,最終變化的是這個浮點數。
最終我們要幹什麼呢?完整的數學表達是這樣的,首先,你拿 s 作為服務字符串、x 作為你的隨機起點(對於絕大部分礦工來說,這實際上會變成你可以影響默克爾根的 coinbase 交易,這個我們後面再說,但那也可以當成一種隨機起點,因為每個礦工都在不停改變 coinbase 交易)。然後,不是讓哈希值等於 0,而是小於某個難度目標(H(s,x,c) < 2^(n-k))。目標等於 2^(n-k) …… 這就是它的工作原理背後的一些數學描述。
挖礦過程概述
在比特幣中,我們將區塊頭作為我們要哈希的東西(服務字符串)。作為一個礦工,你只需要給我一個區塊頭,然後我就能開始挖礦。那麼區塊頭裡有什麼呢?這問題其實非常重要。
通常來說,人們在剛接觸比特幣的時候會了解到,但隨後就會逐漸忘卻。它會埋到你的腦海深處,你甚至不會記得區塊裡有什麼。但它很重要:
首先,我們有
Version,就是你在運行的軟件的版本號;然後是上一個區塊的哈希值(
hashPrevBlock),正是因為留存了這個東西,區塊才前後相接、形成了一條區塊鏈;再然後是
hashMerkleRoot,就是我剛剛說過的,區塊內的所有交易以一棵樹的形式哈希成一個默克爾根;還有當前區塊的時間戳(
Time),它每隔幾秒就會改變一次;所以這裡也有幾個比特的隨機性空間;還有
Bits,它是用十六進制來表示的難度;最後,是
Nonce,就是那個計數器。這個 nonce 字段實際上是非常非常小的,只有 32 比特,你使用現在的礦機,很快就能遍歷這個空間。所以,為了成功挖出區塊,我們不得不訴諸所謂的extranonce字段,它就放在coinbase 交易裡面;改變了 coinbase 交易你就會影響默克爾根。
各位可能有所不知,今天,我們用來衡量礦機性能的指標,是 “TH(terahashes)”,是 10 的 12 次方(次哈希運算)。如果談論的是一群礦機,比如說一個礦場,那就用 “PH(petahashes)”(10 的 15 次方)。最後,如果討論的是整個網絡的哈希率總和,我們通常用 “EH(exahashes)”(10 的 18 次方)為單位。目前,我認為整個網絡的哈希率達到了 350 EH 。現在,標準的礦機每秒運行 100 TH,而中等規模的礦場每秒運行 10 PH 。
(譯者注:作者在這裡才算真正談到衡量哈希率(哈希速度)的指標,比如普通的礦機是 100 TH/s ,每秒運行 100 T 次哈希運算。)
挖礦協議
然後是挖礦協議。在前面,我們解釋了哈希率或者說挖礦是怎麼會是,但在網絡中,我們如何將這麼多機器、礦場組織起來?這就有更多東西要說了。
目前,我們使用 “Stratum V1” 協議。我敢肯定你們都聽過 “Stratum V2”,這是目前非常熱的一個話題,不過已經有點超出這個演講的範圍了。我會在這裡那裡補充一點信息、告訴你兩者的主要區別,但現在,你只需記住,我們討論的是 Stratum V1 。
礦工和礦池通常只使用 TCP 連接。所以,在礦池,我們會打開一個 TCP 端口,供礦工連接,而通信形式是 JSON RPC(以 JSON 格式表達的指令)。這是非常直接的。消息的類型可以在屏幕上看到:mining.subscribe、mining.authorize、mining.set_target、mining.notify 和 mining.submit。這幾乎就是 Stratum 協議的全部了。它是非常簡單的。我還增加了一些背景知識在這兒。
“訂閱(subscribe)” 是雙方要完成的第一件事,這就像是,礦工表示:我在這兒,我已經準備好挖礦了,請在你的礦池裡給我登記,並給我一個工作 ID 。同時,它也開始發送 extranonce 信息。這是 Stratum 協議的非常重要的部分,在它剛剛出現的 2013、 2014 年,真的是一項創新。(順帶說一句,Stratum 協議的其中一位作者也坐在觀眾席中)。好了,有了 extranonce 信息,我們就能將礦工需要用礦機完成的絕大部分工作都本地化,不需要跟礦池來回通信。這能夠節約許多開銷,如果你每迭代一次 PoW 運算都要跟礦池通信、獲得信息,那就不得了了。所以,礦池發回 extranonce 信息,然後說,你就從這裡開始,然後自己迭代運算。這就是礦工開始訂閱的時候,雙方的通信往返。
另一件事情是 “授權(authorization)”。你在礦池登記了一個 “員工(worker)”,這個員工有了一個礦池賬戶,但是你可能有許多個員工,每個都對應著多臺機器。所以,當你授權一個員工時,你相當於是說,我的這個員工已經準備好接受任務了。這是在客戶端和服務端之間發生的 —— 所謂客戶端,我們說的是實際挖礦的機器 —— 然後礦池會發回共享的難度目標。
在礦池裡面,我們根據 “shares(份額、分數)” 來組織挖礦,它的基礎是將難度設定在網絡所要求的挖出新區塊的難度試下。基本上,要為每一臺機器設置不同的難度,這樣礦池才能每 2 ~ 5 秒收到機器的一個 share 。礦池基本上就是在跟礦機說,你有多少哈希率?好,你大概有這麼多,那麼我會為你設置難度,也許是 1 或 2,這樣我每隔 2 ~ 5 秒就能從你這裡得到一些信息。它會調整,對吧?那這有沒有用呢?當然有用。
礦機知道了自己要挖礦的難度之後,它將需要獲得實際用於挖礦的信息。這些信息就是之前我們解釋過的那些 —— 需要放在區塊頭中的信息。
礦機需要獨自處理的主要事情就是在這個 extranonce 字段上挖礦。它得到的主要信息,就像我在 “訂閱” 部分說的,extranonce1 和 extranonce2_size 。extranonce1 是一個固定的變量,而 extranonce2_size 是可以由具體的一臺礦機來迭代的是 extranonce 字段的長度。然後,礦機獲得了 coinbase 交易的開頭,就是礦池接收挖礦獎勵的地址;然後是 coinbase 交易的結尾,就是一些額外的信息(或者說填充物)。 礦機就會迭代這個 Extranonce2 字段,直到找到一個目標哈希值,或者說一個輸出哈希值,它低於 share 的難度目標。具體做法是將這些字段前後拼接起來(coinbase1 + extranonce1 + extranonce2 + coinbase2),然後將它們(跟其它交易)層層哈希成默克爾根。在每一個區塊中,它的 coinbase 交易都是這個默克爾樹最左邊的葉子。為了計算默克爾根(Merkle root) —— 這就是 Stratum V1 和 Stratum V2 的主要區別,在 V1 中,你不會得到完整的樹,你只會得到一些分支,憑藉這些分支,你可以計算出這個樹根。你已經有 coinbase 交易了,那麼礦池會給你這筆交易,從而你們能計算出它們的哈希值;然後你會得到跟它相鄰的這個哈希值,從而計算出再上一層的哈希值;以此類推,最終你會計算出 Merkle root,它顯然是你的服務字符串中最重要的部分。
就這樣,你能算出一個 Merkle root,你會不斷(修改 coinbase 交易從而)不斷迭代它,然後將其餘元素加進去、形成一個區塊頭。當你找到一個 share 要求的哈希值,你的軟件會把它發給礦池。然後是等待憑藉這些 shares 獲得支付。循環往復。
理解礦池
然後是礦池。我不會講完這一整張圖,但它確實總結了礦池的方方面面,這張圖會放到 Revlit 上,各位如果想引用它,悉聽尊便。
【聽眾因為圖片在礦池的處理中心使用 “KAFKA” 字樣而提出疑問,作者解釋這只是一種軟件,各家礦池可能有所不同。不譯】
礦池的清賬模式
礦池有許多種清賬模式。得到使用的兩種主要模式是 :PPLNS,根據最新一定數量的 shares 給礦工清賬; FPPS,每一個 share 都得到完全支付。
主要區別在於,在 PPLNS 中,每當礦池找到一個區塊,你(礦工)就會得到支付。比如說,Braiins(曾用名 “Slush Pool”)就使用這種模式。每當礦池找到一個區塊,那麼就根據在找到區塊之前發放給礦工的最後一些 shares,來衡量他們為找到這個區塊而貢獻的哈希率,然後給他們支付。只考慮最新一批 shares 的部分原因是不希望礦工切換礦池 —— 只有在找到區塊的這段時間裡在礦池挖礦的礦工,才會得到獎勵。
至於 FPPS,你得到保證,基本上,只要礦池沒有破產,你的 shares 都會得到支付。所以,無論你一天生產了多少 shares ,你都能憑藉自己生產的 shares(或者說你給礦池作的貢獻),從流動性池子中獲得支付。這跟礦池有沒有找到區塊無關。
清賬風險
想必各位都會馬上提出一個問題:要是這個礦池,一天裡面沒有找到任何區塊,那會怎麼樣呢?連續兩天、三天,更長時間 …… 那在 FPPS 礦池裡面要如何清賬?沒什麼,這就是運行一家 FPPS 礦池的風險 —— 你可能不得不先給礦工清賬,而不會立即獲得足夠多比特幣來覆蓋你的之處。相反,在 PPLNS 礦池中,你基本上是把風險推給礦工。你連續幾天挖不倒區塊也沒關係,礦池只會在挖出區塊的時候給礦工支付。礦池實際上是不承擔風險的,礦工不得不承擔連續幾天得不到付賬的風險。
礦池風險的案例
【聽眾】:有沒有哪個礦池是真的破產的呢?
有。不過後來他們被一家更大的礦池收購了。或者說,一家金融機構介入了,基本上接管了,也付清了賬單。我這說的是 “Poolin”,他們把一部分礦池資金跟自己做的部分 DeFi 投資混在了一起。所以當 “三箭資本(Three Arrows Capital)” 倒下的時候,他們的許多礦池資金是跟投入 DeFi 協議的資金綁定的。一夜之間,Poolin 的所有礦工應得的收益都變成了比特幣欠條 —— 這是站在礦池的角度說的。如果是從用戶的角度看,那就像是,你說 “我想取出自己的比特幣”,結果對方說 “不不不,現在你只能得到比特幣欠條”。這是一個典型的案例。我也曾在礦池工作,講出這個案例沒有惡意。
挖礦市場
好了,到了本場演講的主菜了,這些圍繞挖礦的市場是怎麼運作的?出現了礦池之後,本質上,礦池就是一種市場,你擁有哈希率,你把它賣給礦池;礦池反過來,利用匯集起來的哈希率來挖礦,然後根據哈希率的比例來分發收益給礦工 —— 這就像一種市場。那我們能不能再往前走一步呢?
挖礦硬件的進步
這個想法是原創的,來自比特幣白皮書:PoW 本質上是一個 CPU 就能投一票。中本聰最初是這麼認為的。但能用 CPU 來挖礦的日子已經過去很久了。我們很快就從 CPU 轉向了 GPU(圖形計算芯片),然後幾乎同一時間出現了 FPGA(現場可編程門陣列)挖礦,最後,出現了 ASIC(特定應用集成電路)。我認為(20)12、13 年就出現 ASIC 挖礦了。
現代挖礦行業的挑戰
從那時候開始,你就需要購買非常專業、價格不菲的硬件來挖礦了。沒辦法用家用硬件來挖礦了。又過了幾年,就算你買到了這樣的專業硬件,還需要找到非常便宜的電力,才能賺到錢。即使你買到了 ASIC,放在家裡,那也不會賺到太多錢。而且實際上不太可行,或者說很難長期持續。現在,甚至就算你拿到了非常便宜的電力,你也需要一定的規模以及大量基礎設施,才能降低運營成本。所以現在,挖礦真的挺不容易的。即使對那些大礦工來說,也非常艱難。
顯然,挖礦行業一直有非常強的中心化趨勢,我們在 Twitter 上能看到這些新聞,而且我聽說在比特幣圈子裡有許多的批評,因為現在,像 Foundry 和比特大陸(Bitmain)這樣的礦池,可以輕鬆控制整個網絡 70 ~ 80% 的哈希率。就只是兩家而已,對吧。
當然,你是可以切換礦池的,而且,它並不必然成為比特幣的一種生存威脅,但如果我們能夠嘗試分散這種風險,肯定會更好,對吧?而我說的風險,一大部分實際上是資本風險。今天,為了運行挖礦企業、獲得一定的規模,你需要先投入非常非常多的現金。你可以去看任何一家公開的大型挖礦企業的資產負債表,你會發現他們的體量都非常大,是跟這些項目有關的設備和資本品的大買家。這不可避免會有很多債務,這在當前的市場上是非常弱勢的,因為沒有人願意借錢給比特幣企業,覺得這風險太高了,所以最終貸款的利率會非常高。也許你能找到一些新的貸款方式,比如使用 ASIC 來擔保,Khnighted 公司就提供這樣的貸款,在挖礦公司倒閉之後,他們可以拿到所有的礦機;但是他們沒有地方能轉賣這些礦機,因為恰逢這些公司都破產了。這樣的事情在去年發生了很多,我相信你們都聽說了。
基本上,礦工們沒有很好的辦法來對沖任何一種風險。沒有礦工能夠嘗試和鎖定收益的流動性市場。考慮到礦工的業務形式和電力的價格,這些收益會在接下來半年、一年、兩年乃至三年裡逐步產生。如果他們預測比特幣價格會上漲、難度也可能增加,從而哈希率的價格會下降,那麼他們本應可以訂立一種金融合約,在一條遞減曲線上鎖定一個價格,每月付(假設)2% 或 3% 的期權費,然後在難度調整超過 1% 的時候行使合約權利。這樣我的收益就鎖定了。這樣的合約在世界上所有其他主要的大宗商品上都有,但在比特幣的挖礦行業沒有。而且,作為一個礦工,尤其在我們處理這樣的資本結構時,它是非常重的負擔,負債率很高,這就讓它成了非常難以成功的業務。
我們一直在思考這個問題,我們的其中一個想法是:也許我們是在錯誤的地方尋找流動性、在錯誤的地方分散風險。我們為什麼要去找那些傳統的金融機構?他們只想從貸款中儘可能多收錢。為什麼我們不直接去找那些有限制資金的人 —— 我的意思是有比特幣的人 —— 他們顯然非常在意網絡的安全性,也對網絡安全性的分散化有興趣。為什麼我們不利用這些限制的資金來分散這種類型的安全風險呢?
你可能會認為,“託管礦機” 和 “雲挖礦”也是這樣的嘗試;完全不是,不過我們可以放他們一馬,在最寬容的意義上說是。給不瞭解的人解釋一下,礦機託管是指,你買下一臺礦機,然後別人會把它放在他們的礦場裡面跑這臺機器,他們會給你支付,或者將算力投入你指定的礦池。雲挖礦,則是你買下一個帶有時限的哈希率合約。就我所知,通常這些哈希率不會實際交付;但我也聽說有例外。基本上,區別在於,在雲挖礦裡面,你不會買下一臺機器,而只會買一些據說是讓你可以挖礦的合約。 但通常來說,這對你而言都非常抽象。
所以,主要問題在於,這一切根本不符合我們在比特幣中堅持的原則,對吧。你得到的是一個完全不對稱的信任模式。你必須完全信任這個人:首先,你要先掏出一大筆錢,從一個自稱是服務商的人那裡來買礦機;你得信任這個人不會哄抬礦機的價格,因為完全是由他們 “代理” 的;你得信任礦場的運營者會維持運營;最後,你還得信任,哪怕價格下跌,或者出現了什麼意外,你的礦機依然會為你服務。你什麼選擇也沒有,對吧?你的礦機可能放在另外一個你聽都沒聽過的國家,只有上帝才知道你在哪裡挖礦。所以,通常,不需要很長時間,這場戲就會露餡。它要麼是個騙局,要麼是個徹底的騙局。
雲挖礦,你幾乎總是被宰。我從來沒聽過哪一份雲挖礦合約是賺錢的。相反,通常你是血本無歸。至於礦機託管,就像我說的,這是不對稱的信任模式,每個人都能宰你,不僅如此,你還要承擔溢價,他們在每一個層面都能吞你的錢。
所以,我們能夠嘗試和避免這些情形的辦法是在礦工和買家之間建立直接的連接。直接嘗試創建一個市場,雙方是可以直接協商的。
在那之前,還要多講一句,我們已經有了一些哈希率期貨市場。FTX 去年已經推出了這樣的市場。Luxor 推出了一個更加合規的市場,那是一種不可交割的期貨(non-deliverable future),你可以說它是一種互換(swap),那就傳統得多了。它們的問題在於,我們並沒有看到很多流動性。而且再說一遍,我認為,他們有些走回去了。就像我說的,為什麼要去找這些傳統的金融機構借錢呢?他們通常根本不瞭解比特幣,也沒有任何激勵去理解和嘗試承擔比特幣的風險,他們只想著利用一個事實再多榨一些油水出來:你需要錢,又沒有別人願意借給你錢,所以我可以按照非常高的利率借給你。
當然,它還變成了這樣一種局面:沒有人真的嘗試在傳統金融市場上購買這些哈希率期權合約。其它考慮是:好了,如果你真的要求交付,那會怎麼樣?沒辦法真正交付給你呀。那麼合約的持續期呢?在大部分時候,如果你到 NiceHash 和 Mining Regret tools 這樣的市場去看,你會發現合約的持續期都非常短,所以,如果你只是想賭個漲跌,那是可以的,但它持續時間太短了,無法做到你買一個東西、放在那裡讓它自己運行這樣。至於不交割的期貨,或者或互換合約,你知道的,你只是在買一種傳統金融工具,不是用代碼來保障的東西。
【演講者在經過提醒後表示自己會加快速度講完。】
點對點的哈希率
所以,我們的模式是,我們建立了拍賣機制來發現價格。我們使用多簽名腳本來給哈希率的賣家支付,而且支付只有在哈希率交付之後才會發送;我們通過一個代理(proxy)來交付哈希率。因此,我們可以看到最終交付了多少哈希率。
我們畫了一些圖來解釋整個模式。所以,我們在中間幫助建立這樣的小型合約;買家用底部的橙色畫出,他們的資金放在鏈上的多簽名錢包裡;交付則是通過礦池賬戶來實現。所以,來自礦工的哈希率被投放到一個礦池,最終,當這個礦池挖出一個區塊時,支付會進入一個礦池賬戶。然後,合約就會發揮作用。最後,你真的可以將資金從你的礦池賬戶轉移到另一個地方。這樣一來,我們就真的能夠保證交付會發生,並且我們有一個代理,可以讀到有多少哈希率交付給了這個礦池賬戶。
我們已經有一個樣品在運行了,你可以使用這個 QR 碼來註冊,稍後我會再給一個鏈接。這基本上就是我們的模式的流程,不過,我們有一個事件驅動的系統,只要你一給我們發送支付,我們就切出一部分當前在別的地方挖礦的哈希率到你的礦池賬戶(你可以提前登記你的礦池賬戶)。
閃電網絡
最後一頁關於閃電網絡。我們希望能夠通過閃電網絡來發送礦池支付。問題在於 —— 我不知道你們有沒有聽過 Jade(硬件簽名器),它也可以運行哈希運算。這裡的想法是,(當前的哈希率價格是)每 TH/s 價值 10 聰。我們能夠通過閃電網絡來發送這麼小的支付碼?我們能夠讓每一焦耳的熱量、浪費的電力都變成哈希計算嗎?目前,這是做不到的,但是通過閃電網絡,也許可以。
問題在於,就像 Lisa 指出的,如果讓礦池通過閃電網絡給礦工付賬,那會遇到非常嚴重的流動性問題,因為這是在同一個方向上不斷流出資金,你會很快用盡這些通道的流動性,這不是閃電通道的理想工作模式。我們需要讓支付在兩個方向上流動。現在,使用我們的模型,流動性確實是雙向移動的。我們讓購買哈希率的付款一次性在一個方向上推過去,然後你每天得到哈希率交付、得到礦池支付,資金就是反方向流動。這樣就可以平衡這些通道。
於是問題變成了,這些礦池在什麼位置上、我們怎麼納入新的 coinbase 交易?這是一個 “通道拼接” 技術有望解決的問題,我們可以拼接一個新的 UTXO 到現有的通道餘額中。最終關閉的狀態跟合約條款上預計的狀態只會有細微的差別。所以,我們假設你是一個買家,希望用百分之 x 的保證金來賭你自己贏,那麼通道關閉的狀態將反映你是賭贏了還是對手(礦工)賭贏了。
最後,另一種可能相對容易做到這件事的辦法,是使用一個 Fedipool 而不是閃電網絡。我這裡就不再展開。同時,我們也希望加入 Nostr 協議。我們認為,使用靜態的 ID 來發放支付是很有前景的。你們可以試試樣品,這是 QR 碼。希望我們在那裡相見。
(完)





