區(qū)塊鏈隨機數(shù)的安全性闡述
本文將從EOS DApp 攻擊事件出發(fā),以科普角度闡述安全隨機數(shù)的標準及現(xiàn)行公鏈上隨機數(shù)的生成機制。
自去年6月EOS主網(wǎng)上線之后,陸續(xù)發(fā)生DApp的智能合約被黑客入侵的事件,其中泛隨機數(shù)攻擊事件占了大多數(shù),以下是攻擊事件列表:
以上19起EOS DApp攻擊事件,總共造成了超過100萬美元的損失,其中14起為隨機數(shù)攻擊,另外5起為回滾攻擊,這些攻擊都直接或間接地與隨機數(shù)有關(guān),可稱為泛隨機數(shù)攻擊。隨著這些攻擊事件的發(fā)生,區(qū)塊鏈上隨機數(shù)的安全性也越來越被廣泛關(guān)注。
什么是「安全」的隨機數(shù)?
先想想我們對隨機數(shù)的要求是什么,生活中很多地方會用到隨機數(shù),當它至關(guān)重要時,我們才會要求它「公正」、「安全」。例如樂透彩開獎時,樂透公司讓大家的檢驗方式是租一個頻道,預(yù)先讓第三方背書數(shù)組公正的彩球,公開在頻道上取一組彩球,將彩球放到抽獎箱中打亂,再一顆一顆吸出彩球得到號碼,用意就是為了讓大家相信抽簽的過程是公正的。
然而,這也未必能真正達到公正,比如說,這第三方和樂透公司共謀時,可以在彩球裝上磁鐵,最后只有有磁鐵的彩球會被吸出來,讓這看似隨機的過程其實并不隨機。
至此,我們先做一個小結(jié)論,一個好的隨機數(shù)應(yīng)該要滿足以下三個特質(zhì):
· 無法被操縱或預(yù)測(不能用磁鐵改變抽中的彩球)
· 可以被公眾驗證其隨機性(大家可以相信開球過程是真的隨機)
· 無需信任第三方(不需要找律師確認彩球沒問題)
除了現(xiàn)實生活中的樂透開獎之外,開發(fā)程式時也常會需要隨機數(shù),譬如競猜、Du博、隨機分配任務(wù)等,我們先有了隨機數(shù)的概念后,再來看目前區(qū)塊鏈上的隨機數(shù)有什么問題。
區(qū)塊鏈上的隨機數(shù)是怎么來的?
目前EOS 跟Ethereum 都沒有提供官方的隨機數(shù)生成服務(wù),如果開發(fā)者需要在智能合約上使用隨機數(shù)的話,他們有兩個選擇 — — 自己產(chǎn)生隨機數(shù)或是仰賴第三方oracle。
Ethereum 官方推薦使用Oraclize (一個第三方的oracle 服務(wù))來產(chǎn)生隨機數(shù),但去中心化的區(qū)塊鏈要仰賴中心化的第三方提供隨機數(shù),完全就是本末倒置。而且對于一個熱門的DApp 來說,頻繁的調(diào)用第三方的oracle 是很昂貴的,可能還會增加完成步驟所需的transaction 數(shù),而造成DApp 的latency 增加,所以大多數(shù)開發(fā)者都傾向自己產(chǎn)生隨機數(shù)。
問題來了,在官方不提供隨機數(shù)生成服務(wù)的狀況下,公鏈上的開發(fā)者只能自行根據(jù)公鏈上能取到的各種變量來作為隨機數(shù)種子,而這些變量往往來自于區(qū)塊的訊息,這么做很容易讓有心人士可以去預(yù)測隨機數(shù)。
舉例來說,前陣子被攻擊的EOSDice 就是采用了tapos_block_prefix() 跟tapos_block_num() 這兩個變量作為隨機數(shù)種子,而它們正是下注transacTIon的「前一個區(qū)塊」的資訊。
聰明的讀者可能已經(jīng)發(fā)現(xiàn)哪里不對勁了,隨機數(shù)的種子居然在下注前就已經(jīng)形成了!駭客正是看出了這個規(guī)則,才能預(yù)測出「必定中注」的隨機數(shù),在不公平的狀況下贏走莊家的錢。
EOSDice在第一次黑客事件后,旋即修正了隨機數(shù)生成的方式,開發(fā)者改用雙重的deferred acTIon延遲了開獎的時間,使得reference block變成下注時還未生成的區(qū)塊,如此一來就無法事先取得區(qū)塊資訊。但道高一尺魔高一丈,駭客直接寫了一個合約去模擬EOSDice合約的行為,只要兩種合約運行在同一個區(qū)塊,就會refer相同的block,進而得到相同的區(qū)塊資訊,于是乎EOSDice又被駭了第二次…
由于公鏈上的區(qū)塊資訊是公開的,現(xiàn)行在智能合約中采用「區(qū)塊資訊」生成隨機數(shù)的做法,其安全性不管再怎么設(shè)計都會有其極限。一個好的隨機數(shù)生成方式不應(yīng)該仰賴第三方oracle ,且必須滿足「不可被預(yù)測」的特質(zhì),就這點看來, EOS 跟Ethereum 都還還做得不夠好。
當EOS的技術(shù)長Daniel Larimer被開發(fā)者問到隨機數(shù)安全性的問題時,他提出了一個「信任區(qū)塊生產(chǎn)者」的方案— —區(qū)塊生產(chǎn)者在打包交易時,在某個特定時機獲取特定訊息,以此作為隨機數(shù)種子來生成偽隨機數(shù)。雖說這是一個鏈上的解決方案,但這種做法其實跟仰賴oracle的本質(zhì)并無不同,一樣都是由一個中心化的第三方來提供隨機數(shù),EOS的DPoS制度已經(jīng)賦予少數(shù)區(qū)塊生產(chǎn)者極大的權(quán)力,若他們還能直接參與隨機數(shù)生成的過程,那中心化的風險就更高了。
如果公鏈隨機數(shù)的安全性問題一直存在,那么任何需要「公平隨機數(shù)」的程式邏輯就無法安心地運行在公鏈上,這對整個區(qū)塊鏈生態(tài)系的發(fā)展都有不利的影響。