9.1 比特幣作為一個只能被添加的記錄

比特幣是一個只能添加而不能刪除的記錄。它是一種可以不斷添加新的數據,但是數據一旦被添加上去,就變得不可修改並且永久保存的數據結構。因此,通過比特幣,我們可以獲得一個時間順序:判斷一個數據是在另一個數據之前還是之後被寫進了記錄的。這個次序是由區塊之間的哈希函數指針,而不是區塊上的時間戳所決定的,因為時間戳可以作假,或者是由於礦工更改時間戳的值使其變得更小(更早),或者是礦工的計算機時鐘沒有同步,更或者是由於網絡延時產生的差異。話雖如此,如果一個區塊的時間戳延遲了好幾個小時,它就會被其他的礦工們拒絕。所以時間戳還是相對準確的。通過下面的示例,我們可以看到,這些特性是有實際用途的。

安全時間戳

比特幣這種只能被添加的記錄特性可以被用來建立一個安全時間戳(secure timestamping)系統。假如,想要證明在時間T我們就知道了x的值,但並不想披露它的具體值。只有在未來很長時間後,當有可能需要證明我們確實知道這個值的時候,才有可能需要去披露它(當然,如果我們在時間T知道x的值,我們在T之後的時間還是知道這個x的值)。而且我們一旦證明了這一點,就需要使這個證據具備永久性。

在第1章中我們看到,可以用哈希函數來鎖定數據x。我們不需要公佈x值本身,取而代之地,只需要在區塊鏈裡公佈這個數據值的哈希函數H(x),即可以來證明我們知道這個X值。這個哈希函數的特性,保證了我們不可能再找到另外一個數據y,其哈希函數結果與x的哈希函數結果一致,也就是說,當y≠x時,H(x)=H(y)是不存在的。我們還可以依賴哈希函數另外一個常用的特性:只要x本身具備比較高的最小信息熵分佈特性(distribution with high min-entropy),也就是說,x是不可預測的,那麼x的哈希函數結果不會透露關於x的任何信息。如果x本身沒有這種不可預測的特性,就像我們在第1章中探討的,我們可以選擇一個有較高的最小信息熵分佈的隨機數r和x組合簽名,然後用H(r|x)作為對外公佈的一個數值約定。

這個設想的核心就是,我們在時間點T只向外公佈哈希函數H(r|x),然後在之後的某個時間點來公佈r和x。任何人看到這個只能做增量的記錄,都會相信在我們發表H(r|x)的時候我們一定知道x,因為沒有除此之外的其他方法可以讓我們產生那些數據。

時間戳的應用

這個安全時間戳到底有什麼用途呢?一個可能的應用就是可以用來證明創意的優先性。假設我們想證明,申請專利的一些創意點子早就在我們頭腦裡存在。我們可以在產生創意的第一時間,就將設計文檔或者示意圖草稿在區塊鏈裡用哈希函數發表出來,但不會向任何人洩露這個創意的具體內容。之後,當我們提交專利申請或是公佈這個想法的時候,我們可以將最初的設計文檔和相關信息發表出來,任何人都可以查證這些文件的函數時間戳,來證實我們在這之前,也就是我們發佈設計文檔的哈希函數約定的時候,就已經有了這個創意(證明我們對這個創意的時間上優先所有權)。

我們還可以用同樣的方法來證明,其他人收到過我們發給他們的信息。假設愛麗絲僱用鮑勃去做一個編程的工作——他們之間的合同規定,鮑勃必須在一定的時間內將他所做的工作內容提交給愛麗絲。雙方都想要獲得一個保證,如果將來對相關工作內容有爭議,比如鮑勃是否按時提交程序或者他提交的內容是否滿足合同要求,雙方都希望可以有相關的事實去證明。為了確保這一點,他們可以互相協商,將鮑勃提交的工作內容共同簽名後,再在區塊鏈上發表它的哈希函數。任何一方如果對提交的時間或者內容撒謊,另一方可以通過披露哈希函數的輸入來重現當時發表的內容,來證明對方是錯的(比如在法庭上)。

安全時間戳功能還有許多其他有意思的應用。有一種完全公鑰簽名方案,被稱為蓋伊·福克斯簽名方案(Guy Fawkes signature scheme),相比較通常的公鑰簽名,只是利用了哈希函數和只能做增量記錄的記錄特性,而不需要任何重量級的加密算法。

對未來預測證明的攻擊

我們目前無法僅僅用時間戳就證明對未來的準確預測,能對未來進行預測(clairooyance),當然非常好。而且從表面上看,這好像可以做到。在一個事件發生之前(比如一個體育比賽或是選舉)發表一個對結果的預言,然後在事件發生之後,再證明在之前就已經預測到了。但這個方法是否真正可行?

在2014年下半年的世界盃決賽階段,有人想用這個辦法來「證明」世界盃的組織方國際足聯(Federation Internationale de Football Association,簡稱FIFA)在搞腐敗。當時有個推特賬號,由於在一些重要比賽之前就可以準確地預測到這些比賽的結果,因而被廣受關注。比如,該賬號準確地預測到德國隊會在加時賽取勝並且馬裡奧·格策(Mario Gotze)會進球。這看起來可以證明,要麼是微博主人有預知未來的能力,要麼是比賽被操縱了。然而事實上,這個博主只是在比賽前發佈了所有可能發生的事件,比如,對於所有的參賽球員,都有一條關於他會進球的微博,以及對於每一種可能的最終比分,都有一條相關的微博等(見圖9.1),然後在比賽結束之前,博主刪除了所有那些不準確的預測,只留下那些準確的「預測」。

圖9.1 試圖對未來進行預測

註:這就是那個虛假的試圖通過預測比賽結果來「證明」世界盃決賽圈的比賽被操控了的推特賬號。其中第一個和第四個在賽後被證明是正確的,其他不准的預測就被刪掉了。

可以用同樣基礎的攻擊方法攻破任何安全時間戳系統。你只需要在事先預埋下所有的結果,然後最終只披露那個正確的結果。這就意味著如果你想證明你有預測能力,就必須去證明你做且只做了一個預測結果,而不是多個預測。但如果你想基於哈希函數揭示結果,是很難實現的,尤其是在比特幣的區塊鏈上,因為安全時間戳系統並不將承諾與任何個人身份識別相關聯。如果你不揭示它們,就會很容易公佈很多種承諾,而那些你從未揭示的承諾很難輕易追溯到你。

過時的安全時間戳

這裡介紹一個簡單的低科技含量的安全時間戳方案:通過刊登廣告,你可以在一份報紙或者其他媒體上登出你預測結果的哈希函數值,相關的舊報紙雜誌會被保存在圖書館裡或者在線備份。這種方法可以提供較高程度的保證,證明你在報紙發出的當天就已經知道這個結果了。以後,當你想要披露你預測的結果時,你可以在同一個報紙上刊登第二份公告。

比特幣裡的安全時間戳

如果我們想用比特幣而不是報紙來實現時間戳的功能,我們應該在哪裡放置約定的哈希值?是在交易中的某個環節,還是直接在一個區塊裡?

人們想出來的第一個也是最簡單的解決辦法是,直接把錢打到數據的哈希函數值,而不是公共鑰匙的函數值。由於你不知道對應地址的私鑰,這樣做會「消耗」這些幣,讓它們銷毀掉,並且永不能被利用。為了降低成本,你可能需要發送微量的幣值,比如1聰(satoshi,0.0000001個比特幣,這是比特幣的最小交易額)。

這個方法雖然很簡單,但消耗比特幣的做法不討人喜歡(即使和交易費相比,這種被消耗的比特幣量級可以忽略不計)。更大的問題是,因為比特幣礦工不知道這些交易開支是永遠不可用的,他們會永遠地追蹤下去。因此整個比特幣社區對這個方法都不太感冒。

另一個較為先進的被稱為承諾幣(CommitCoin)的方法,是將你的數據編碼進私鑰裡。第1章中曾經提到過:「使用ECDSA時,確保隨機性良好來源至關重要,因為不良來源將可能導緻密鑰信息的洩露。這一點不難理解,如果你使用了不良隨機源來生成密鑰,那麼該密鑰就可能不安全。但是ECDSA的古怪就在於,即使你僅僅只是在生成簽名時使用了不良隨機源,而你使用的密鑰完美無缺,你的個人密鑰還是可能會被洩露。」

承諾幣利用了這個特性。我們生成一個新的私鑰把我們的數據約定進行編碼,並對應地生成一個公鑰。然後我們會發送一個微小金額的交易(比如2 000聰)到那個地址,隨後再發送兩筆每次1 000聰的交易回來。最重要的是,當發送回來的時候,我們會用同樣的隨機源來對兩次交易進行簽名。這樣,任何人在區塊鏈裡計算包含被封裝的數據約定的私鑰時,必須使用兩個簽名。

比起把數據約定編碼到公鑰的方法,承諾幣避免了消耗額外的比特幣,而且礦工不再會一直追蹤一個永久不能再被使用的支出。不過這個方法十分複雜。

不能被再次使用的輸出

一直到2015年,比特幣實行時間戳的辦法是用一個OP_RETURN的交易,這個交易的輸出可以被證明,但不能被二次使用(見圖9.2)。這個OP_RETURN指令會立刻返回一個錯誤代碼讓這個腳本永遠不能成功地執行,這樣一來,所封裝的數據就被忽略了。就像我們在第3章看到的,這既可以用做消耗證明,也可以用來編碼任意數據。到2015年,OP_RETURN允許輸出80個字節的數據,這對哈希函數來說是足夠了(SHA-256需要32個字節)。

圖9.2 用OP_RETURN指令的時間戳

註:這是一個「不能被再次使用」的交易輸出腳本,中間封裝了一個數據約定。

這個方法「擠出了」在沒有被使用過交易支出裡的「水分」,因為礦工會精簡OP_RETURN裡的支出。這個數據約定的花費其實就是一個交易費。在整個2015年,一個典型的交易費通常小於1美分。這個交易費可以分攤在針對多個數據的一個約定上,從而使得成本更低。在2015年年末,已經有幾個網站在做這些服務。它們收集不同用戶的一組數據,把這些數據封裝到一個梅克爾樹中,然後發佈一個包含了這個梅克爾樹樹根數據中不能被再次使用的交易支出。這種做法就好比,把當天需要實行時間戳的所有用戶數據封裝到了一個數據約定裡。

非法內容

區塊鏈隨意封裝數據的特性也有不好的地方,可能會被某些人惡意使用。在大多數國家,有些內容,尤其如兒童色情,它的製作和傳播都是非法的,並且會伴隨非常嚴厲的處罰。著作權法也嚴格規定了某些內容的傳播。

當然,不少人已經嘗試這樣做去「危害」或者擾亂比特幣社區。比如,有報道稱有部分色情鏈接被公佈在比特幣的區塊鏈上。這些害群之馬的目的,就是讓下載比特幣區塊鏈到個人硬盤並且運行完全有效節點的行為變得很危險,這也意味著你有可能存儲和傳播了這些非法的信息。

然而,截至目前,還沒有好的辦法來阻止這種寫入任意數據到比特幣區塊鏈的行為,即使我們用P2SH(支付給腳本的哈希值)來防止惡意攻擊行為,也只不過是使交易多花些費用而已,無法完全阻止這種行為。

好在法律不是計算機算法,嘗試用技術的手段對法律進行「黑客攻擊」雖然很誘人,但並不容易。法律是需要人類來解釋的,並融合了其他因素,比如我們的意圖。以美國聯邦法案2252號為例,其中在描述有關擁有、分發傳播和接收兒童色情製品的非法行為時,使用的措辭就用了「明知故犯」這樣包含了意圖的關鍵詞。

另外一個值得注意的是,根據上面我們討論過的字節大小的限制,圖片數據(除非是非常小的圖片)不能直接被寫在區塊鏈的數據塊中,這些數據要麼被存放在只在區塊鏈中保存相應鏈接的外部數據庫中,要麼是用一種冗長的辦法封裝在多個交易之中。最終的結果就是,大多數比特幣用戶都沒有能力在交易中直接解碼並查看數據,更不用說解碼並查看跨越多個交易的數據了。

依附在比特幣上的附著幣

從好的一方面來說,因為我們可以把任何數據都寫進比特幣的區塊,從而在比特幣的系統之上建立起一個全新的貨幣系統,而不需要開發一個新的共識機制。我們只需要簡單地把比特幣用作一個只能被添加的記錄,然後把我們開發新幣所需要的所有數據寫進比特幣的區塊鏈。我們稱這種方法為一個依附在比特幣上的「附著幣」(overlay currencies)。比特幣成為一個底層基礎架構,所有附著幣的數據,通過以不可消費的交易支出的方式寫進比特幣的區塊鏈。

當然,比特幣的礦工不會驗證你寫進區塊鏈的數據,因為他們不知道也並不關心這些數據在你所定義的新的貨幣體系裡是否正當有效。只要你肯付交易費,任何人都可以寫任何東西。不同的是,你必須自己開發更加複雜的邏輯來驗證新貨幣體系裡的交易,然後在每個收發這種新幣的客戶端(也就是錢包軟件)都必須有這套邏輯。

舉例來說,一個附著幣的礦工不能再拒絕雙重支付的交易。相反,每個附著幣的用戶必須檢查區塊鏈裡的歷史記錄。如果有人嘗試重複支付這個幣(已經被用過一次了),那樣第二次的交易就應該被直接忽略。因為這個緣故,在附著幣裡沒有一個輕量級的SPV客戶端。

合約幣(Counterparty)是其中一種比較優秀的附著幣,所有合約幣的交易都被寫入比特幣的區塊鏈,在2014年,大約有0.5%~1%的比特幣交易攜帶了合約幣的數據。同時它支持的功能也比比特幣更多、更豐富,因為合約幣不需要開發新的共識機制,而比特幣的礦工也不需要瞭解合約幣的規則,合約幣的開發者可以集中精力開發一些有趣的功能,比如智能合約、用戶自定義貨幣等。合約幣的API也比比特幣的API豐富很多,因為比特幣的礦工不需要理解或者是批准這些API的開發。

不需要開發新的共識機制就可以創造一個新的數字貨幣,這種可能性是十分誘人的。你甚至不需要去鼓勵新礦工們來加入你的系統,也不需要去改變比特幣就可以增加新的功能特性。但是,這種系統還是依賴於比特幣的,比如,這些附著幣的交易費規則就受制於比特幣。另外,由於附著幣上的節點可能需要處理大量的數據,而比特幣不會幫你去過濾這種交易,這種方法也有可能是低效率的。

《區塊鏈:技術驅動金融》