N3的合約運行時隨機數(shù)|Neo專欄

除了直接用鏈上數(shù)據(jù)來計算隨機數(shù)的方案外,當前給智能合約提供隨機數(shù)的方案主要是以外部回調(diào)這種昂貴的機制為智能合約提供基于可驗證隨機函數(shù)(VRF)計算出的隨機數(shù),比如已經(jīng)為區(qū)塊鏈項目提供了三百多萬隨機數(shù)的Chainlink,對于每一個特定的用戶請求來返回一個相應的可驗證的隨機數(shù)。在ETH2.0中也有專門關(guān)于安全隨機數(shù)的協(xié)議,就是用可驗證延遲函數(shù)(VDF)來計算隨機數(shù),或者計算隨機數(shù)種子,并且為了保證延遲函數(shù)的準確性,以太坊基金會還和IPFS一起合作在研發(fā)專門用來計算可驗證延遲函數(shù)的設備。
但是基于回調(diào)機制的隨機數(shù)方案本身存在一些問題。比如延遲很高,需要等待至少兩個區(qū)塊時間才能獲取到一個隨機數(shù);鏈上開銷很高,需要額外的交易來把隨機數(shù)寫入?yún)^(qū)塊鏈;手續(xù)費昂貴,用戶需要支付兩筆交易的手續(xù)費,并且還要支付隨機數(shù)服務費;信任問題,回調(diào)機制往往需要引入可信的第三方來生成隨機數(shù)。因此為了解決以上問題,我們需要能夠為智能合約在運行時提供隨機數(shù)。
合約運行時隨機數(shù)系統(tǒng)架構(gòu)
為N3我們設計了一種為智能合約在運行時提供隨機數(shù)的解決方案,該系統(tǒng)結(jié)構(gòu)框圖如圖 1所示,由防范MEV攻擊的交易列表生成單元和基于BLS的隨機數(shù)生成單元組成。
在初始化階段,共識節(jié)點執(zhí)行 BLS 閾值設置過程以生成 BLS私鑰并廣播相應的 BLS 公鑰。在每一輪共識周期之前,共識節(jié)點從整個網(wǎng)絡里收集交易,并驗證簽名,然后將有有效簽名的交易按照先入先出的順序推入交易池中,而無效的交易將被丟棄直接丟棄。在新的共識周期開始時,每個共識節(jié)點生成一個交易列表,其中包含從交易池中彈出的交易哈希值,然后簽署由交易哈希值構(gòu)成的交易列表。與此同時,共識節(jié)點生成一個BLS簽名,使用在初始化階段生成的BLS私鑰對前一個區(qū)塊的哈希值進行簽名。一旦節(jié)點完成生成交易列表和BLS簽名的工作,節(jié)點就會向共識網(wǎng)絡廣播一條包含這兩組數(shù)據(jù)的消息。

圖1 運行時智能合約隨機數(shù)系統(tǒng)結(jié)構(gòu)圖
防御MEV攻擊的交易列表生成單元。在運行時為智能合約提供隨機數(shù)的最大挑戰(zhàn)之一是 MEV 攻擊,它允許攻擊者提前預測甚至直接獲取隨機數(shù)。并且一旦隨機數(shù)泄露,攻擊者可以比其他智能合約用戶獲得不公平的優(yōu)勢。因此,在我們甚至可以為智能合約生成隨機數(shù)之前,解決MEV攻擊至關(guān)重要。
MEV攻擊之所以存在,是因為交易順序在一定程度上幾乎可以被任何人操縱。對于議長節(jié)點,即生成新塊的節(jié)點,它可以控制交易順序。它可以從區(qū)塊交易列表中刪除一個有效的交易,臨時構(gòu)造一個新的交易并將其插入到區(qū)塊交易列表中,或者簡單地改變交易順序。即使是普通用戶也可以通過改變交易費用來發(fā)動MEV 攻擊,例如三明治攻擊。因此為了解決 MEV 攻擊,我們必須解決交易排序的公平性問題。

圖2 存在MEV攻擊的隨機數(shù)生成器

圖3 抵抗MEV攻擊的隨機數(shù)生成器
交易排序算法在以下情況下實現(xiàn)公平排序:
除了算法本身沒有人可以決定交易的排序;
沒有人可以臨時的構(gòu)造交易,并把交易插入?yún)^(qū)塊交易列表中;
沒有人可以從區(qū)塊交易列表中刪除有效交易;
區(qū)塊交易列表的公平性對共識節(jié)點是可驗證的。
當議長共識節(jié)點收到來自其他共識節(jié)點的節(jié)點交易列表時,它嘗試聚合來自共識節(jié)點的節(jié)點交易列表最終交易列表, 聚合出的區(qū)塊交易列表對其他公式節(jié)點來說是可驗證的,因此議長共識節(jié)點在生成區(qū)塊交易列表時無法作惡。該單元共有兩個組成模塊。一個是FIFO的交易緩存池,另一個是公平排序的交易列表聚合器。
FIFO交易緩存池是一個先進先出的交易緩存池,存在于每個共識節(jié)點中。緩存池本質(zhì)上是一個交易隊列,節(jié)點從網(wǎng)絡中獲取到的交易將從隊列的尾部推送入緩存池,然后從隊列前端彈出交易,從而實現(xiàn)對,交易實現(xiàn)先入先出的排序邏輯。此外,在把交易推入緩存池之前,節(jié)點會驗證交易的數(shù)字簽名以及節(jié)點本身的賬戶余額。只有那些通過了簽名驗證并且有足夠的余額支付手續(xù)費的交易,才會被推入緩存池中。而那些驗證失敗的交易,將會直接被丟棄。在每輪共識開始的時候,節(jié)點會從緩存池中獲取一定數(shù)量的交易并將這些交易打包成節(jié)點交易列表。這些節(jié)點交易列表將會被廣播到網(wǎng)絡中。議長節(jié)點將會監(jiān)聽網(wǎng)絡中的這些包含了節(jié)點交易列表的信息。
交易列表聚合器。實現(xiàn)公平的交易排序是防御MEV攻擊的關(guān)鍵所在,而交易列表聚合器,則是每個節(jié)點都可以收集網(wǎng)絡中的交易。原則上每個節(jié)點都有交易節(jié)列表聚合器且在每一輪共識周期里都以可以對來自于網(wǎng)絡中的交易列表進行聚合,但是為了簡化系統(tǒng)復雜度,在每一輪共識周期里,只有議長節(jié)點需要從網(wǎng)絡中收集交易列表并且聚合。在實現(xiàn)聚合器的時候有幾個前提假設。首先假設所有在共識網(wǎng)絡中所有的正常節(jié)點,都可以正常的與其他節(jié)點進行通信,也就是說正常節(jié)點都可以收到其他正常節(jié)點的交易列表。此外,還假設,如果一筆交易是正常的并且滿足被打包的條件,那么它將一定會被所有的正常節(jié)點包含在交易列表里。當滿足以上兩個假設條件的情況下,我們可以說所有正常的節(jié)點的交易列表將是差不多的。
有一個方案為基于拜占庭容錯共識機制的解決方案,因此我們假設正常的節(jié)點將會超過總共識節(jié)點數(shù)量的2/3。也就是說,如果一筆交易滿足所有被打包的條件,并且不是來自于一個惡意的攻擊者,那么我們會在超過2/3個節(jié)點交易列表中看到這筆交易。而且由于我們假設正常節(jié)點的網(wǎng)絡狀態(tài)不受干擾,因此我們也可以假設,這筆來自正常節(jié)點的交易,將在所有超過2/3個正常節(jié)點交易列表中,擁有著幾乎相同的交易排序。
基于以上分析,我們在聚合節(jié)點交易列表的時候,先判斷一筆交易是否同時存在于超過2/3個節(jié)點共識交易列表中。我們只會考慮聚合那些同時存在于超過2/3個節(jié)點共識交易列表中的交易,同時考慮到整個系統(tǒng)中還有不超過1/3的惡意節(jié)點。這些惡意節(jié)點,可能會惡意地構(gòu)造交易列表。如果我們將這些來自于惡意節(jié)點的交易列表也考慮到最終的聚合系統(tǒng)中,那么我們的系統(tǒng)將會把這些惡意的攻擊帶入到我們最終的聚合結(jié)果中。因此在聚合這些交易列表的時候,我們還需要對其離群值進行判斷。因為我們沒有辦法直接的去判斷哪些節(jié)點交易列表來自于正常節(jié)點,哪些節(jié)點交易列表來自于惡意節(jié)點,因此我們只能整體的對交易的排序來進行離群值的計算。
在我們的方案中,我們從超過2/3個節(jié)點交易列表中獲取到一筆交易的所有的下標,然后然后計算每個下標與其他下標之間的距離,當一筆交易在某一個節(jié)點,交易列表的下標。與其在其他節(jié)點交易列表中的下標的距離過遠時,我們將認定其為離群值。由于沒有辦法去判斷整個聚合過程中有多少惡意節(jié)點的參與,因此我們將離群值的數(shù)量定義為不超過1/3的節(jié)點數(shù)量。例如當我們一共有七個共識節(jié)點的時候,我們在聚合交易列表的時,只需要獲取五個節(jié)點交易列表,而在計算聚合結(jié)果的時候,我們還要從這五個節(jié)點交易列表中,計算出不超過1/3個惡意節(jié)點的數(shù)量,也就是說兩個離群值,因此我們在最終聚合的時候,將會是有三個節(jié)點交易列表參與到最終的區(qū)塊交易列表聚合。而最終的區(qū)塊交易列表將會和由生成他它的節(jié)點取關(guān)列表,一起被廣播到整個網(wǎng)絡中,其他的共識節(jié)點在收到這個信息的時候,也可以根據(jù)相同的邏輯自己去生成區(qū)塊交易列表來驗證來自于議長節(jié)點的區(qū)塊交易列表是否為真。由于該方案具有可驗證性,并且聚合結(jié)果來自于整個共識網(wǎng)絡。該方案實現(xiàn)了可驗證的,并且具有公平性的交易列表。
由于本方案的區(qū)塊交易排序算法不是按交易費排序,而是使用FIFO機制來管理交易池中的交易并且使用將以列表聚合的機制來生成最終的區(qū)塊交易列表,使得攻擊者無法通過支付大量交易費來改變交易順序。在區(qū)塊交易列表的聚合過程中,每筆交易的排序由其在節(jié)點交易列表中整體位置計算決定而來,因此沒有人可以決定它。
區(qū)塊交易列表生成之后,共識節(jié)點還會對生成的區(qū)塊交易列表進行驗證,如果交易的排序或交易數(shù)未通過驗證,那么本輪共識節(jié)點會失敗,并觸發(fā)視圖更改,從而進行下一輪新的共識。
BLS的隨機數(shù)生成單元。在區(qū)塊鏈這種去中心化的環(huán)境中生成一個公平的隨機數(shù)是非常困難的。它與傳統(tǒng)的服務器-客戶端模式不同。我們沒有一個中心化的服務器,可以為我們生成隨機數(shù)。與此相反,區(qū)塊鏈網(wǎng)絡中的節(jié)點是平等的,相互之間沒有信任的存在,任何節(jié)點,都可能是一個惡意的節(jié)點。因此,我們沒有辦法依賴于任意一個節(jié)點去為我們生成隨機數(shù)。雖然我們可以在可信執(zhí)行環(huán)境中生成隨機數(shù),例如SGX,可是研究證明可信執(zhí)行環(huán)境存在著各種各樣的側(cè)信道攻擊使得可信執(zhí)行環(huán)境本身并不安全。
在運行時為智能合約生成隨機數(shù)則更加艱難。因為隨機數(shù)本身將會被用來作為執(zhí)行的輸入?yún)?shù)。隨機數(shù)這個值本身將會被直接用來影響智能合約以及交易的執(zhí)行結(jié)果。因此我們認為隨機數(shù)不應該由任何人個人決定,否則決定隨機數(shù)的人可以利用這種力量產(chǎn)生一個對自己最有利的價值。而且隨機數(shù)不應該被公眾知道,無論如何都不能改變交易狀態(tài),這樣就沒有人可以利用這個數(shù)字。隨機數(shù)應該是可驗證的、無偏見的和唯一的。最重要的是,隨機數(shù)應該是不可預測的。
我們認為一個公平的隨機數(shù)算法應該滿足以下幾個條件:
不可預測性:不能有任何人能夠提前得知隨機數(shù)的結(jié)果。
不可預測性:對于給定的輸入,該隨機數(shù)算法的輸出應該在保持均勻分布。
針對區(qū)塊鏈智能合約的環(huán)境:一個公平的隨機數(shù)算法應當保證當隨機數(shù)生成之后,沒有人可以用它來作惡。
經(jīng)過謹慎選擇,本方案使用的是基于BLS聚合簽名算法的隨機數(shù)生成方案。隨機數(shù)生成共分為兩個步驟。在每一輪共識開始的時候,每個節(jié)點將使用自己本地的BLS私鑰來對上一輪共識結(jié)果的區(qū)塊的哈希值進行簽名,并把簽名的結(jié)果結(jié)果廣播到整個共識網(wǎng)絡中。所有的共識節(jié)點將會在網(wǎng)絡中監(jiān)聽來自于別的共識節(jié)點的BLS簽名,當簽名的數(shù)量收集到一定的閾值的時候,就可以用來對這些簽名進行聚合,聚合的結(jié)果會作為隨機數(shù)的生成種子。當一個共識節(jié)點從共識網(wǎng)絡接收到足夠多的BLS簽名時,它會調(diào)用BLS聚合算法將這些BLS簽名聚合成一個最終的簽名,并且這個最終的簽名被用作隨機數(shù),因為所有共識節(jié)點運行相同的BLS算法,因此所有共識節(jié)點生成的隨機數(shù)是相同的。
考慮到整個網(wǎng)絡是基于拜占庭容錯共識算法,我們將BLS簽名聚合的閾值設為超過所有共識節(jié)點數(shù)量的1/3。舉例說明,當我們的網(wǎng)絡中有七個共識節(jié)點的時候,那么我們只需要收集到三個共識節(jié)點的簽名,就可以聚合成最終的簽名,也就是我們的隨機數(shù)種子。之所以考慮到設置節(jié)點數(shù)量為超過1/3,是因為如果我們把閾值設為小于共識節(jié)點的1/3,那么惡意節(jié)點將會可以聯(lián)合起來,構(gòu)造虛假的聚合簽名。
單節(jié)點執(zhí)行邏輯
該方案為一種去中心化的智能合約隨機數(shù)解決方案,在本方案執(zhí)行的時候,邏輯由系統(tǒng)內(nèi)的共識節(jié)點一起協(xié)作完成?;贐FT類的共識算法,本方案的共識節(jié)點分為兩類,一種是普通的共識節(jié)點,另一種是負責區(qū)塊生成的議長(primary)共識節(jié)點。

圖4 單節(jié)點執(zhí)行流程圖
在共識周期的間隙,共識節(jié)點將會持續(xù)從網(wǎng)絡中獲取到來自于用戶的交易,并把這些交易放到自己的交易緩存池中。在每一輪共識開始的時候,所有的共識節(jié)點都將會生成自己本地的BLS簽名,并且生成自己的節(jié)點交易列表。如果這個交易節(jié)點是普通的共識節(jié)點,那么他將在發(fā)送完自己的BLS簽名和節(jié)點交易列表之后,將會開始對網(wǎng)絡進行監(jiān)聽,以獲取來自于其他共識節(jié)點的BLS簽名,并且如果收到的簽名數(shù)量超過了閾值,將會直接進行簽名的聚合。而如果當前節(jié)點是一個議長節(jié)點,那么他將會從網(wǎng)絡中不停地監(jiān)聽這些包含了BLS簽名和節(jié)點交易交列表的消息并且判斷這些消息的數(shù)量是不是超過了閾值。當議長節(jié)點收到了超過2/3的節(jié)點交易列表之后,它將會啟動交易列表的聚合過程,同時也會聚合BLS簽名。
當議長節(jié)點完成了對BLS簽名和對節(jié)點交易列表的聚合之后,會生成一個最終的BLS簽名以及一個區(qū)塊交易列表,基于這些數(shù)據(jù)他將會生成一個新區(qū)塊提案并發(fā)布到整個網(wǎng)絡中。普通的共識節(jié)點將會收到新區(qū)塊的提案,并對這個提案進行驗證,主要是驗證區(qū)塊交易列表是否真實以及BLS簽名是否真實.如果一個新的區(qū)塊提案通過了驗證,那么當前的共識節(jié)點將會確認新的區(qū)塊提案,否則共識節(jié)點將會發(fā)起投票以更新視圖并開啟新的共識。
完整共識流程
但是基于回調(diào)機制的隨機數(shù)方案本身存在一些問題。比如延遲很高,需要等待至少兩個區(qū)塊時間才能獲取到一個隨機數(shù);鏈上開銷很高,需要額外的交易來把隨機數(shù)寫入?yún)^(qū)塊鏈;手續(xù)費昂貴,用戶需要支付兩筆交易的手續(xù)費,并且還要支付隨機數(shù)服務費;信任問題,回調(diào)機制往往需要引入可信的第三方來生成隨機數(shù)。因此為了解決以上問題,我們需要能夠為智能合約在運行時提供隨機數(shù)。

圖 5 完整共識流程
由于該方案是基于拜占庭容錯共識協(xié)議,為了增強隨機數(shù)算法的公平性, 我們對現(xiàn)有的共識協(xié)議做出了改進。如圖三所示, 本方案的共識是基于實用拜占庭容錯共識算法更改而來。在傳統(tǒng)的實用拜占庭容錯共識協(xié)議的基礎之上,我們增加了兩個步驟。一個步驟是用于收集各個節(jié)點的BLS簽名以及用于防范MEV攻擊的節(jié)點交易列表,另一個步驟只是對收集到的BLS簽名和節(jié)點交易列表進行聚合。當我們已經(jīng)有了合法的BLS簽名以及區(qū)塊交易列表之后,我們就可以按照原本的實用拜占庭容錯的共識算法,由議長節(jié)點將新區(qū)塊的提案來廣播到整個網(wǎng)絡中并發(fā)送pre-prepare的消息來通知其他的節(jié)點來對新區(qū)塊的提案進行驗證。而共識節(jié)點將會將其驗證的結(jié)果廣播到整個網(wǎng)絡中以作為回復。當共識節(jié)點收到超過2/3個其他共識節(jié)點的回復之后,新區(qū)塊就會被確認。相較于拜占庭協(xié)議,我們只是在協(xié)議開始的時候,增加了兩個步驟,完全不會影響整個共識協(xié)議原本的安全假設.
性能評估
為了評估性能,我們使用FAST-BLS來做BLS的簽名和聚合,用Fisher–Yates shuffle來做交易列表的公平排序。此外我們還實現(xiàn)了幾個智能合約來對隨機數(shù)的調(diào)用開銷做測試,尤其是我們實現(xiàn)了一個合約來模擬基于回調(diào)機制的操作流程,并且與運行時隨機數(shù)的調(diào)用過程進行比較。
?BLS聚合時間?

?運行時隨機數(shù)和回調(diào)機制下的隨機數(shù)方案GAS手續(xù)費消耗的比較?

?幾種使用運行時隨機數(shù)的合約GAS消耗?

?公平排序的時間開銷?

?運行時隨機數(shù)相較于回調(diào)機制下的隨機數(shù)方案少寫入?yún)^(qū)塊鏈的數(shù)據(jù)量?

All in One · All in Neo
Neo是一個由社區(qū)驅(qū)動的開源平臺。利用區(qū)塊鏈技術(shù)與數(shù)字身份,開發(fā)者可以通過智能合約實現(xiàn)資產(chǎn)管理數(shù)字化與自動化。Neo致力于通過分布式網(wǎng)絡建設下一代互聯(lián)網(wǎng)基礎設施,為區(qū)塊鏈技術(shù)大規(guī)模落地奠定基礎,以實現(xiàn)智能經(jīng)濟的宏大愿景。
自2016年上線至今,Neo主網(wǎng)已穩(wěn)定運行超過五年。全新版本Neo N3已于2021年發(fā)布,提供了更高吞吐量、更強穩(wěn)定性與安全性,帶來了優(yōu)化的智能合約系統(tǒng)及功能豐富的基礎設施集合,旨在賦能開發(fā)者并加速企業(yè)級區(qū)塊鏈創(chuàng)新。


