簡化付款確認
可以在不運行完整網(wǎng)絡節(jié)點的情況下驗證支付。用戶只需要保存最長的工作證明鏈的塊頭副本,他可以通過查詢網(wǎng)絡節(jié)點獲得這個副本,直到他確信自己擁有最長的鏈,并獲得將事務鏈接到它所標記塊的Merkle分支。他不能自己檢查事務,但是通過將其鏈接到鏈中的某個位置,他可以看到一個網(wǎng)絡節(jié)點已經(jīng)接受了它,并在它進一步確認網(wǎng)絡已經(jīng)接受它之后添加塊。
因此,只要誠實的節(jié)點控制網(wǎng)絡,驗證是可靠的,但是如果網(wǎng)絡被攻擊者制服,驗證就更容易受到攻擊。雖然網(wǎng)絡節(jié)點可以自己驗證事務,但是只要攻擊者能夠繼續(xù)控制網(wǎng)絡,簡化的方法就會被攻擊者編造的事務所欺騙。防止這種情況發(fā)生的一種策略是,當網(wǎng)絡節(jié)點檢測到無效的塊時,接受來自網(wǎng)絡節(jié)點的警報,提示用戶的軟件下載整個塊,并提醒事務確認不一致性。經(jīng)常收到付款的企業(yè)可能仍然希望運行自己的節(jié)點,以獲得更獨立的安全性和更快的驗證。
如果大部分CPU功率合謀說謊,那么網(wǎng)絡顯然不再安全。如果使用51%的攻擊,那么這個簡單的方法將很容易被愚弄,人們將希望擁有完整的區(qū)塊鏈。
隱私
一個典型的模型是,身份與通過受信任的第三方然后在交易對手處結(jié)束的交易相關(guān)聯(lián)。在這個模型中,網(wǎng)絡的其他部分不知道雙方之間進行的某些交易。
在比特幣協(xié)議模型中,身份是一個單獨的部分,交易以分類賬的形式通過公眾進行。
作為一個額外的防火墻,應該為每個事務使用一個新的密鑰對,以防止它們鏈接到一個公共所有者。但是,存在這樣一種風險:如果密鑰的所有者被公開,鏈接可能會顯示屬于同一所有者的其他事務。
使用區(qū)塊鏈
區(qū)塊鏈提供了可公開編寫的全局僅追加日志。參與區(qū)塊鏈網(wǎng)絡的節(jié)點遵循塊頭協(xié)議來決定哪個節(jié)點可以編寫下一個塊并收取特定的事務費。在每一輪的領(lǐng)導人選舉中,只有一個節(jié)點可以寫入一個塊。區(qū)塊鏈中的節(jié)點維護它的完整和更新版本。獨立驗證和添加到區(qū)塊鏈的挖掘過程包括運行計算密集型軟件來解決復雜的數(shù)學問題,這種困難被稱為“工作證明”(proof-of-work, POW)。POW基于加密哈希函數(shù)。為了使塊可以接受,它的頭哈希必須在前面加上一定數(shù)量的0,其中哈希是時間段內(nèi)所有事務的Merkle根、前一個塊和nonce的組合。 Merkle根是通過哈希值數(shù)據(jù)、將結(jié)果與另一對數(shù)據(jù)配對并再次將所有事務數(shù)據(jù)都包含在最后一個哈希中而形成的。礦工搜索‘ nonce ’,它的前綴塊頭有足夠的0來滿足POW條件。一旦POW被解決,新的塊將通過網(wǎng)絡傳輸。然而,在使用區(qū)塊鏈構(gòu)建系統(tǒng)時存在一些挑戰(zhàn),比如數(shù)據(jù)存儲的限制、寫入速度慢、帶寬有限等。
哈希函數(shù)是將任意大小的輸入數(shù)據(jù)轉(zhuǎn)換為固定大小的輸出數(shù)據(jù)。數(shù)字簽名是公鑰密碼學(也稱為非對稱密碼學)的派生,公鑰密碼學使用兩個不同但在數(shù)學上相連的密鑰,一個是私有的(這是秘密的),另一個是公共的(與他人共享的)。
代碼
要深入理解區(qū)塊鏈技術(shù),我們需要通讀實現(xiàn)它的代碼。
區(qū)塊鏈的基本概念非常簡單:一個分布式數(shù)據(jù)庫,它維護一個不斷增長的有序記錄列表。比特幣和以太坊等流行的區(qū)塊鏈項目就是這種情況。術(shù)語“區(qū)塊鏈”通常與事務、智能合約或加密貨幣等概念緊密相關(guān)。
這使得理解區(qū)塊鏈成為一項困難的任務。尤其是source-code-wisely。在這里,我將介紹一個超級簡單的區(qū)塊鏈,它是我用200行Javascript實現(xiàn)的,名為NaiveChain。
塊結(jié)構(gòu)
第一個邏輯步驟是決定塊結(jié)構(gòu)。為了使事情盡可能簡單,我們只包括最必要的:索引、時間戳、數(shù)據(jù)、哈希和以前的哈希值。
塊哈希
塊需要哈希值以保持數(shù)據(jù)的完整性。SHA-256接管塊的內(nèi)容。應該注意的是,這個哈希值與“挖掘”無關(guān),因為沒有要解決的工作問題。
生成一個塊
要生成一個塊,我們必須知道前一個塊的哈希值,并創(chuàng)建所需內(nèi)容的其余部分(=索引、哈希值、數(shù)據(jù)和時間戳)。塊數(shù)據(jù)是由最終用戶提供的。
存儲塊
內(nèi)存中的Javascript數(shù)組用于存儲區(qū)塊鏈。區(qū)塊鏈的第一個塊總是所謂的“起源快”,它是硬編碼的。
驗證塊的完整性
在任何給定的時間,我們必須能夠驗證一個在完整性方面是否有效。尤其是當我們從其他節(jié)點接收新塊并必須決定是否接受它們時,更是如此。
選擇最長的鏈
在給定的時間內(nèi),鏈中應該始終只有一個顯式的塊集。在發(fā)生沖突的情況下(例如兩個節(jié)點都生成72個塊),我們選擇塊數(shù)最長的鏈。
與其他節(jié)點通信
節(jié)點的一個重要部分是與其他節(jié)點共享和同步區(qū)塊鏈。以下規(guī)則用于保持網(wǎng)絡同步。
· 當一個節(jié)點生成一個新的塊時,它向網(wǎng)絡廣播它
· 當節(jié)點連接到新的對等點時,它查詢最新的塊
· 當節(jié)點遇到一個索引大于當前已知塊的塊時,它要么將該塊添加到當前鏈中,要么查詢完整的區(qū)塊鏈。
不使用自動對等發(fā)現(xiàn)。必須手動添加對等點的位置(= url)。
控制節(jié)點
用戶必須能夠以某種方式控制節(jié)點。這是通過設置HTTP服務器來完成的。
與其他節(jié)點通信
節(jié)點的一個重要部分是與其他節(jié)點共享和同步區(qū)塊鏈。以下規(guī)則用于保持網(wǎng)絡同步。
· 當一個節(jié)點生成一個新的塊時,它向網(wǎng)絡廣播它
· 當節(jié)點連接到新的對等點時,它查詢最新的塊
· 當節(jié)點遇到一個索引大于當前已知塊的塊時,它要么將該塊添加到當前鏈中,要么查詢完整的區(qū)塊鏈。
不使用自動對等發(fā)現(xiàn)。必須手動添加對等點的位置(= url)。
控制節(jié)點
用戶必須能夠以某種方式控制節(jié)點。這是通過設置HTTP服務器來完成的。
可以看出,用戶可以通過以下方式與節(jié)點進行交互:
列出所有塊
使用用戶提供的內(nèi)容創(chuàng)建一個新塊
列表或添加對等點
最直接的控制節(jié)點的方法是使用Curl:
從節(jié)點獲取所有塊
curl http://localhost: 3001 /塊
體系結(jié)構(gòu)
應該注意的是,節(jié)點實際上公開了兩個web服務器:一個用于用戶控制節(jié)點(HTTP服務器),另一個用于節(jié)點之間的對等通信(Websocket HTTP服務器)。