全球最大的比特幣交易平臺MT.GOX正陷入破產邊緣,這無疑給還在火熱的中國比特幣市場潑了一盆冷水。不過冷靜思考一下,這瀕臨倒閉的背后原因是什么?是不是無法避免?本文作者Ken Shirriff 就結合2011年Mt.Gox出現的問題分析一下這個全球最大的比特幣交易平臺的技術問題。
在2011年10月份的時候,Mt.Gox因為突發事故導致超過2609個比特幣的損失。(當時2609個比特幣的總價值是8000美元。如果是現在的話,這2609個比特幣價值約超過150萬美元。)不過當時在比特幣論壇上就有相關的猜想,具體原因沒有官方說明。所以說,這次Mt.Gox被盜事件也不是空穴來風,主要原因還是軟件上的漏洞給黑客份子以可乘之機。當然這也暴露了Mt.Gox對之前事故的疏忽和軟件編程錯誤之嚴重。
問題結癥在哪?
當你向一個地址發送比特幣的時候,在比特幣交易過程中所要發生的事情遠比你想象的復雜得多。交易程序里包含一個微型計算機程序,而這個程序是由Bitcoin Script語言編寫的,它的任務主要是執行這個比特幣能否交易的出去進行判斷。這個程序還能檢查公開密鑰是否和你發送比特幣的地址相吻合,如果實名驗證是有效的,那樣就能證實發送者是比特幣的真正擁有者,交易也就可以順利進行。
你可能會想知道為什么比特幣交易平臺要使用這么一個復雜的系統來進行交易信息驗證。其實他們的想法是,通過這種編程語言編寫出來的程序,比特幣就會允許多種不同類型的交易方式,例如第三方交易或者是更加復雜的合同交易。
這里可以講述的更詳細一點,一種典型的ScriptPubKey編程語言看起來就像這樣:
這些就是將比特幣發往指定地址(1P9LHy6K2c9cwbfSfdaaoYVAprqUYtcFnB,十六進制形式是 f2e633...)的程序。如果想要用這個地址兌換比特幣的話,賣家必須提供這個地址的公開密鑰1P9L...,同時在交易協議上簽名(這主要是證明他們擁有私人密鑰)。走過這些程序之后,首先是要復制提供的公開密鑰,計算160位散列,并驗證公開密鑰是否和所提供的公鑰地址相等同。然后檢查實名驗證的有效性。如果一切順利,比特幣就可以交易了。如果有問題,交易就會被拒絕。
但是不難發現,在Mt.Gox一些失敗的交易中,程序里出現了一個很小但很致命的錯誤:
我們可以看到在項目地址的散列中,交易行中有一個0字節,表現為OP_0,還增加了一個空的字節數組。因為160位散列不可能匹配一個空數組,所以這個腳本不可能成功地執行任務,因此比特幣也不可能被交易出去。
為什么Mt.Gox允許蹩腳的比特幣交易存在?
也許你很想知道為什么Mt.Gox平臺允許有些比特幣交易無法完成。至于準確的答案無法考究,或許我們可以猜測:因為眾口難調,比特幣交易平臺所制定的交易規則根本無法讓所有的買賣雙方感到滿意。比特幣的設計理念就是用Bitcoin Script語言編寫一個可以給人們帶來更靈活、更便利的虛擬產物,即使是這樣,在條件不成熟的情況下還是會搬起石頭砸自己的腳,正如現在遇到的事情一樣。另外,如果僅僅因為一個復雜的語法問題就拒絕一筆比特幣交易的話,這是很危險的,因為用戶會質疑比特幣的有效性,無疑會引起混論。
計算機科學家們可能會在這個時候說是因為“計算機設備停機問題”導致了現在這種結局。然而,這根本就說不通,因為Bitcoin Script沒有循環體,程序是不會停下來的。
如果你沒有私人密鑰而去使用一個地址的話,那么丟掉比特幣是很常見的事情,并且也沒有軟件能夠檢查出這一缺陷。但是有一個很奇怪的現象就是有些交易故意向一個有問題的地址發送少量的比特幣,這樣就能在blockchain里面隱藏文本和圖片了。這個漏洞應該不算小吧!?
另一個很有趣的腳本Bug
上面只是分析了基于比特幣交易層面上的問題,不過還有另外較為有趣的可以丟失比特幣的bug,有些交易記錄里包含毫無意義且不可修改的腳本錯誤:
原來這些腳本都是ASCII文本腳本,本來是應該將贖回腳本放入交易當中的,可是有些P2Pool淘幣者一不小心將文字腳本放了進去,這就導致相關的比特幣由于這個錯誤而不知不覺就沒了。
總結
由于軟件編程錯誤導致比特幣丟失是一件并不復雜的事情,Mt.Gox在之前就已經因為同樣的錯誤使得數千個比特幣丟失。但是Mt.Gox并沒有吸取教訓對自身技術進行改進加固,所以說這次Mt. Gox因交易系統存在缺陷令黑客盜取大量比特幣,最終崩潰是一件不足為奇的事情。(編譯/薛梁 責編/付江)
原文:RighTo