<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 比特幣網絡 ## 8.1 P2P網絡架構 比特幣采用了基于互聯網(Internet)的點對點(peer-to-peer)網絡架構。點對點,或者叫P2P是指位于同一網絡中的每臺計算機都彼此平等,身份對等,各個節點共同提供網絡服務,不存在任何“特殊”節點。網絡節點以“扁平”的拓撲結構相互連通。 網絡中不存在任何服務器端、中央化的服務、以及層級結構。點對點網絡中的節點同時提供和消費服務,互惠互利。點對點網絡也因此具有可靠性、去中心化,以及開放性。早期的互聯網就是點對點網絡架構的一個典型用例:IP網絡中的各個節點完全平等。當今的互聯網架構具有分層架構,但是IP協議仍然保留了扁平拓撲的結構。除了比特幣,規模最大也最成功的點對點技術應用是在文件分享領域,Napster是該領域的先鋒,BitTorrent是其架構的最新演變。 比特幣所采用的點對點網絡架構不僅僅是拓撲結構選擇。比特幣被設計為一種點對點的數字現金系統,它的網絡架構既是這種核心特性的反映,也是該特性的基石。去中心化控制是核心設計原則,它只能通過維持一種扁平化、 去中心化的點對點共識網絡來實現和維護。 “比特幣網絡”是運行比特幣點對點協議的一系列節點的集合。除了比特幣點對點協議之外,比特幣網絡中也包含其他協議,例如Stratum協議就被應用于挖礦、以及輕量級或移動端比特幣錢包。網關路由服務器提供這些協議,使用比特幣點對點協議接入比特幣網絡,并把網絡拓展到運行其他協議的各個節點。例如,Stratum服務器通過 Stratum協議將所有的Stratum挖礦節點連接至比特幣主網絡、并將Stratum協議橋接至比特幣點對點協議。我們使用“擴展比特幣網絡(extended bitcoin network)”指代所有包含比特幣點對點協議、礦池挖礦協議、Stratum 協議以及其他連接比特幣系統組件相關協議的整體網絡結構。 ## 8.2 節點類型及角色 盡管比特幣點對點網絡中的各個節點地位對等,但是根據所提供的功能不同,各節點可能具有不同的角色。比特幣節點是路由、區塊鏈數據庫、挖礦、錢包服務這些功能的集合。全節點(full node)包括如圖8-1所示的四個功能: ![圖8-1一個包含四個完整功能的比特幣網絡節點:錢包、礦工、完整區塊鏈、網絡路由節點](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0801.png) 圖8-1 具有所有四個功能:錢包,礦工,完整的區塊鏈數據庫和網絡路由的比特幣網絡節點 所有節點都包含參與網絡的路由功能,并且還可能包含其他功能。每個節點都參與驗證并傳播交易及區塊信息,發現并維持與對等節點的連接。在圖8-1中,路由功能由名為“網絡路由節點”的橙色圓圈或字母“N”表示。 一些節點保有一份完整的、最新的區塊鏈副本,這樣的節點被稱為“全節點”。全節點能夠自主權威驗證所有交易,而不需借由任何外部參照。另外還有一些節點只維護了區塊鏈的子集,并使用一種名為*“簡易支付驗證simplified payment verification,SPV”*的方式來驗證交易,這樣的節點被稱為“SPV節點”,又叫“輕量級節點”。在上圖的全節點示例中,全節點區塊鏈數據庫功能由一個稱為“完整區塊鏈”的圓圈或字母“B”表示。在圖8-3中,SPV節點沒有此藍色圓圈,以示它們沒有區塊鏈的完整副本。 挖礦節點通過運行在專用硬件設備上的工作量證明(proof-of-work)算法,相互競爭創建新的區塊。一些挖礦節點同時也是全節點,保有區塊鏈的完整副本;還有一些參與礦池挖礦的節點是輕量級節點,它們必須依賴礦池服務器維護的全節點進行工作。上圖中,挖礦功能如圖中名為“礦工”的黑色圓圈,用字母“M”表示。 用戶錢包也可以作為全節點的一部分,這在比特幣PC客戶端中比較常見。越來越多的用戶錢包,特別是那些運行在智能手機等資源受限設備上的用戶錢包,都是SPV節點。在圖8-1中,名為“錢包”的綠色圓圈字母“W”代表錢包功能。 在比特幣P2P協議中,除了這些主要的節點類型之外,還有一些服務器及節點也在運行著其他協議,例如專用礦池挖礦協議、輕量級客戶端訪問協議等。 圖8-2描述了擴展比特幣網絡中最為常見的節點類型。 ![圖8-2描述了擴展比特幣網絡中最為常見的節點類型](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0802.png) 圖8-2描述了擴展比特幣網絡中最為常見的節點類型。 ## 8.3 擴展比特幣網絡 運行比特幣協議的比特幣主網由大約5000-8000個運行著不同版本比特幣參考客戶端(Bitcoin Core)的監聽節點、以及幾百個運行著各類比特幣點對點協議的其他實現例如Bitcoin Classic, Bitcoin Unlimited, BitcoinJ, Libbitcoin, btcd, and bcoin等的節點組成。比特幣點對點網絡中的一小部分節點也是挖礦節點,它們競爭挖礦、驗證交易、并創建新的區塊。許多連接到比特幣網絡的大型公司運行著基于Bitcoin Core客戶端的全節點客戶端,它們具有區塊鏈的完整副本及網絡節點,但不具備挖礦及錢包功能。這些節點是網絡中的邊緣路由器,允許在上面構建各種其他服務,例如交易所、錢包、區塊瀏覽器、商業支付處理等。 如前文所述,擴展比特幣網絡既包括了運行比特幣點對點協議的網絡,又包含運行專用協議的網絡節點。連接到比特幣點對點主網上,還有許多礦池服務器以及協議網關,它們把運行其他協議的節點連接起來。這些節點通常都是礦池挖礦節點(參見[【第八章 挖礦】](https://github.com/tianmingyun/MasterBitcoin2CN/blob/master/ch08.md))以及輕量級錢包客戶端,后者通常不具備區塊鏈的完整備份。 圖8-3描述了擴展比特幣網絡中多種類型的節點、網關服務器、邊緣路由器、錢包客戶端以及它們相互連接所需的各類協議。 ![圖8-3 具有多種節點類型、網關及協議的擴展比特幣網絡](https://github.com/bitcoinbook/bitcoinbook/raw/develop/images/mbc2_0803.png) 圖8-3 顯示各種節點類型,網關和協議的擴展比特幣網絡 ## 8.4 比特幣傳輸網絡 雖然比特幣點對點網絡服務于各種各樣類型節點的一般需求,但是對于比特幣挖礦節點的特殊需求,它的網絡延遲就顯得太高了。 比特幣礦工參與的是時效性很強的競爭,以解決工作證明問題,延長區塊鏈((參見[【第八章 挖礦】](https://github.com/tianmingyun/MasterBitcoin2CN/blob/master/ch08.md))。在參與這項競爭的同時,比特幣礦工必須盡可能縮短從傳播一個獲勝區塊到開始下一輪競爭之間的時間。挖礦中,網絡延遲與利潤率直接相關。 *比特幣傳輸網絡*是一種嘗試最小化礦工之間區塊傳輸延遲的網絡。最初的比特幣傳輸網絡[Bitcoin Relay Network](http://www.bitcoinrelaynetwork.org/) 是由核心開發人員Matt Corallo在2015年創建的,目的是在極低延遲的礦工之間實現區塊的快速同步。該網絡由幾個專門的節點組成,這些節點托管在世界各地的Amazon Web Services基礎設施上,用于連接大多數礦工和采礦池。 這個最初的比特幣傳輸網絡在2016年被取代,同樣是Matt Corallo創建的*Fast Internet Bitcoin Relay Engine* 或者 [*FIBRE*](http://bitcoinfibre.org/)。 FIBER是一種基于UDP的傳輸網絡,可以節點網絡內傳輸區塊。 FIBRE實現了*壓縮區塊優化*,以進一步減少數據傳輸量和網絡延遲。 康奈爾大學研究的另一個傳輸網絡(仍在提案階段)是 [*Falcon*](http://www.falcon-net.org/about)。 Falcon使用“直通路由”而不是“存儲轉發”來減少延遲,方法是在接收到區塊時就開始部分傳輸,而不是等到接收到完整的區塊。 傳輸網絡不是替代比特幣的點對點網絡。相反,它們是重疊網絡,在具有特殊需求的節點之間提供額外的連接,就像高速公路不能替代鄉村道路,而是交通繁忙的兩點之間的捷徑,仍然需要通過小路連接高速公路。 ## 8.5 網絡發現 當新的網絡節點啟動后,它必須發現網絡中的其他比特幣節點才能參與。要啟動這個過程,新節點必須在網絡上發現至少一個現有節點并連接到該節點。其他節點的地理位置在哪兒都沒有關系,比特幣網絡拓撲結構沒有地理位置的定義。因此,可以隨機選擇任何現有的比特幣節點。 為了連接到一個已知的對等點,節點會建立一個TCP連接,通常連接到端口8333(通常被稱為比特幣使用的端口),或者如果指定了另一個端口,則連接到另一個端口。在建立連接時,該節點會通過發送一條包含基本認證內容的version消息開始“握手”通信過程(見圖8-4)。這一過程包括如下內容: ? nVersion 定義了客戶端所“說”的比特幣點對點協議所采用的版本(例如:70002)。 ? nLocalServices 一組該節點支持的本地服務列表,當前僅支持NODE_NETWORK ? nTime 當前時間 ? addrYou 從該節點看到的遠程節點的IP地址 ? addrMe 本地節點所發現的本機IP地址 ? subver 指示當前節點運行的軟件類型的子版本號(例如:”/Satoshi:0.9.2.1/”) ? BaseHeight 當前節點區塊鏈的區塊高度 (version網絡消息的例子請參見[GitHub](http://bit.ly/1qlsC7w) ) 版本消息始終是任何對等節點發送給另一個節點的第一條消息。 接收版本消息的本地對等節點將檢查遠端節點報告的nVersion,并確定遠端對等節點是否兼容。 如果遠程對等節點兼容,則本地節點將確認版本消息,并通過發送一個verack建立連接。 新節點如何找到對等節點? 第一種方法是使用一些“DNS種子”來查詢DNS,DNS種子就是提供比特幣節點IP地址列表的DNS服務器。 其中一些DNS種子提供了穩定的比特幣偵聽節點的IP地址靜態列表。 一些DNS種子是BIND(Berkeley Internet Name Daemon)的自定義實現,它從爬蟲程序或長時間運行的比特幣節點收集的比特幣節點地址列表中返回一個隨機子集。 Bitcoin Core客戶端包含五種不同DNS種子的名稱。 不同DNS種子的所有權的多樣性和實現的多樣性為初始引導過程提供了高水平的可靠性。 在Bitcoin Core客戶端中,DNS種子選項是否啟用由選項開關 -dnsseed控制(默認設置為1,使用DNS種子)。 或者,一個剛剛啟動的節點,對網絡一無所知,必須被賦予至少一個比特幣節點的IP地址,之后才可以通過進一步的引見建立連接。 命令行參數-seednode可用于連接到一個節點,僅用于將其用作引見種子。 在使用初始種子節點完成引見后,客戶端將斷開連接并使用新發現的對等節點。 ![圖8-4對等節點之間的初始握手](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0804.png) 圖8-4 對等節點之間的初始握手 一旦建立一個或多個連接后,新節點發送一條包含自身IP地址的addr消息給其相鄰節點。相鄰節點再將此條addr消息依次轉發給它們各自的相鄰節點,從而保證新節點被其他節點知道、更好連接。另外,新接入的節點可以向它的相鄰節點發送getaddr消息,要求它們返回其已知對等節點的IP地址列表。通過這種方式,節點可以找到需連接到的對等節點,并向網絡發布它的消息以便其他節點查找。圖8-5描述了這種地址發現協議。 ![圖8-5地址廣播及發現](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0805.png) 圖8-5 地址傳播和發現 一個節點必須連接到幾個不同的對等節點,以便建立進入比特幣網絡的不同路徑。路徑不是持久性的,節點可以隨時加入或者離開,因此節點必須在失去舊連接時繼續發現新節點,并在其他節點啟動時提供幫助。節點啟動時只需要一個連接,因為第一個節點可以將它引見給它的對等節點,而這些節點又會進一步提供引見。一個節點,如果連接到大量的其他對等節點,這既沒必要,也是對網絡資源的浪費。在啟動完成后,節點會記住它最近成功連接的對等節點,以便當重新啟動后它可以迅速與先前的對等節點網絡重新建立連接。如果先前的網絡的對等節點對連接請求無應答,該節點可以使用種子節點重新啟動。 在運行Bitcoin Core客戶端的節點上,您可以使用 getpeerinfo 命令列出對等節點: $ bitcoin-cli getpeerinfo ``` { "addr" : "85.213.199.39:8333", "services" : "00000001", "lastsend" : 1405634126, "lastrecv" : 1405634127, "bytessent" : 23487651, "bytesrecv" : 138679099, "conntime" : 1405021768, "pingtime" : 0.00000000, "version" : 70002, "subver" : "/Satoshi:0.9.2.1/", "inbound" : false, "startingheight" : 310131, "banscore" : 0, "syncnode" : true }, { "addr" : "58.23.244.20:8333", "services" : "00000001", "lastsend" : 1405634127, "lastrecv" : 1405634124, "bytessent" : 4460918, "bytesrecv" : 8903575, "conntime" : 1405559628, "pingtime" : 0.00000000, "version" : 70001, "subver" : "/Satoshi:0.8.6/", "inbound" : false, "startingheight" : 311074, "banscore" : 0, "syncnode" : false } ``` 用戶可以通過提供 -connect=<IP地址> 選項來指定一個或多個IP地址,從而實現手動指定IP地址列表,取消自動節點管理功能。如果采用此選項,節點只連接到這些指定的節點IP地址,而不會自動發現并維護對等節點之間的連接。 如果已建立的連接沒有數據通信,所在的節點會定期發送信息以維持連接。如果節點的某個連接長達90分鐘沒有任何通信,它會認為自己已經從網絡斷開,開始查找一個新的對等節點。因此,網絡可以動態地調整節點變化和網絡問題,并且可以根據需要在沒有任何中央控制的情況下進行有機的增長和收縮。 ## 8.6 全節點 全節點是指維持包含全部交易信息的完整區塊鏈的節點。更加準確地說,這樣的節點應當被稱為“完整區塊鏈節點”。在比特幣發展的早期,所有節點都是全節點;當前的 Bitcoin Core 客戶端也是完整區塊鏈節點。但在過去的兩年中出現了許多新型客戶端,它們不需要維持完整的區塊鏈,而是作為輕量級客戶端運行。在下面的章節里我們會對這些輕量級客戶端進行詳細介紹。 完整區塊鏈節點維護完整的、最新的包含全部交易信息的比特幣區塊鏈副本,這樣的節點可以獨立地進行建立并校驗區塊鏈,從第一區塊(創世區塊)一直建立到網絡中最新的區塊。完整區塊鏈節點可以獨立權威驗證任何交易,而不需要借助任何其他節點或其他信息來源。完整區塊節點通過比特幣網絡獲取包含交易信息的新區塊更新,在驗證無誤后將此更新合并至本地的區塊鏈副本中。 運行完整區塊鏈節點可以給您一種純粹的比特幣體驗:不需借助或信任其他系統即可獨立地對所有交易信息進行驗證。 很容易判斷是否正在運行完整節點,因為它需要超過100 GB的持久存儲(磁盤空間)來存儲完整的區塊鏈。如果您需要很大的磁盤空間、并且同步比特幣網絡耗時2至3天,那么您運行的正是全節點。這就是擺脫中心化權威、獲得完全的獨立自由所要付出的代價。 盡管目前還有一些使用不同編程語言及軟件架構構建的其他的完整區塊鏈客戶端存在,但是最常用的仍然是Bitcoin Core客戶端,它也被稱為“Satoshi客戶端”。比特幣網絡中超過75%的節點運行著不同版本的Bitcoin Core客戶端。它在版本消息中發送的子版本字符串中被標識為“Satoshi”,就像前面看到的getpeerinfo命令顯示的,例如/Satoshi:0.8.6/。 ## 8.7 交換“庫存” 一個全節點連接到對等節點之后,首先做的就是嘗試構建完整的區塊鏈。如果該節點是一個全新節點,它就不包含任何區塊鏈信息,它只知道一個區塊——在客戶端軟件中靜態內置的創世區塊。新節點需要從0號區塊(創世區塊)開始下載數十萬區塊的全部內容,跟網絡同步、并重建完整區塊鏈。 同步區塊鏈的過程從發送version消息開始,這是因為該消息中含有的BestHeight字段包含了一個節點當前的區塊鏈高度(區塊數量)。節點可以從它的對等節點中得到版本消息,了解雙方各自有多少區塊,從而可以與其自身區塊鏈所擁有的區塊數量進行比較。對等節點們會交換一個getblocks消息,其中包含他們本地區塊鏈的頂端區塊哈希值(指紋)。如果某個對等節點識別出它接收到的哈希值并不屬于頂端區塊,而是屬于一個非頂端區塊的舊區塊,那么它就能推斷出:其自身的本地區塊鏈比其他對等節點的區塊鏈更長。 擁有更長區塊鏈的對等節點比其他節點有更多的區塊,可以識別出哪些區塊們是其他節點需要“補充”的。它會識別出第一批可供分享的500個區塊,通過inv(inventory)消息把這些區塊的哈希值傳播出去。缺少這些區塊的節點便可以通過各自發送的getdata消息來請求得到完整區塊信息,用包含在inv消息中的哈希值來識別被請求的區塊,檢索缺失的區塊。 在下例中,我們假設某節點只含有創世區塊。它收到了來自對等節點的inv消息,其中包含了區塊鏈中后500個區塊的哈希值。于是它開始向所有與之相連的對等節點請求區塊,并通過分攤工作量的方式防止單一對等節點被批量請求所壓垮。該節點會追蹤記錄其每個對等節點連接上“正在傳輸”(指那些它已經發出了請求但還沒有接收到)的區塊數量,并且檢查該數量有沒有超過上限( MAX_BLOCKS_IN_TRANSIT_PER_PEER )。用這種辦法,如果一個節點需要更新大量區塊,它會在上一請求完成后才發送對新區塊的請求,從而允許對等節點控制更新速度,不至于壓垮網絡。每一個區塊在被接收后就會被添加至區塊鏈中,這一過程詳見[【第九章區塊鏈】](https://github.com/tianmingyun/MasterBitcoin2CN/blob/master/ch09.md)。隨著本地區塊鏈的逐步增加,越來越多的區塊被請求和接收,整個過程將一直持續到該節點與全網絡完成同步為止。 任何時候節點如果離線,都會將本地區塊鏈與對等節點進行比較,并檢索任何丟失的區塊。如果一個節點只離線幾分鐘,可能只會缺失幾個區塊;當它離線長達一個月,可能會缺失上千個區塊。但無論哪種情況,它都會從發送 getblocks 消息開始,收到一個inv響應,接著開始下載缺失的區塊。庫存和區塊傳播協議如圖8-6所示。 ![節點通過從對等節點讀取區塊來同步區塊鏈圖8-6](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0806.png) 圖8-6節點通過檢索來自對等節點的區塊同步區塊鏈 ## 8.8 簡易支付驗證 (Simplified Payment Verification (SPV) )節點 并非所有的節點都有能力存儲完整的區塊鏈。許多比特幣客戶端被設計成運行在空間和功耗受限的設備上,如智能手機、平板電腦、嵌入式系統等。對于這樣的設備,通過簡化的支付驗證*(SPV,simplified payment verification)*的方式可以使它們在不必存儲完整區塊鏈的情況下進行工作。這種類型的客端被稱為SPV客戶端或輕量級客戶端。隨著比特幣的普及,SPV節點逐漸變成比特幣節點(尤其是比特幣錢包)所采用的最常見的形式。 SPV節點只需下載區塊頭,而不用下載包含在每個區塊中的交易信息。由此產生的不含交易信息的區塊鏈,大小只有完整區塊鏈的1/1000。SPV節點不能構建所有可用于消費的UTXO的全貌,這是由于它們并不知道網絡上所有交易的完整信息。SPV節點驗證交易時所使用的方法略有不同,這個方法需依賴對等節點“按需”提供區塊鏈相關部分的局部視圖。 打個比方來說,每個全節點就像是一個在陌生城市里的游客,他帶著一張包含每條街道、每個地址的詳細地圖。相比之下,SPV節點更像是只知道這座陌生城市一條主街道名字的游客,只能隨機詢問陌生人轉彎方向。雖然兩種游客都可以通過實地考察來驗證一條街是否存在,但沒有地圖的游客不知道那個街道位于哪里,也不知道附近還有什么其他街道。沒有地圖的游客在“教堂街23號”的前面,并不知道這個城市里是否還有其他“教堂街23號”,也不知道面前的這個是否是要找的那個。對他來說,最好的方式就是向足夠多的人問路,并且希望不會有人搶劫他。 簡易支付驗證是通過參考交易在區塊鏈中的深度,而不是高度,來驗證它們。一個擁有完整區塊鏈的節點會構造一條驗證鏈,這條鏈是由沿著區塊鏈按時間倒序一直追溯到創世區塊的數千區塊及交易組成。而一個SPV節點會驗證所有區塊的鏈(但不是所有的交易),并且把區塊鏈和與自己有關的交易鏈接起來。 例如,一個全節點要檢查第300,000號區塊中的某個交易,它會把從該區塊開始一直回溯到創世區塊的300,000個區塊全部都鏈接起來,并建立一個完整的UTXO數據庫,通過確認該UTXO是否還未被支付來證實交易的有效性。SPV節點則不能驗證UTXO是否還未被支付。相反地,SPV節點會在該交易信息和它所在區塊之間用merkle路徑(見[【9.7 Merkle 樹】](https://github.com/tianmingyun/MasterBitcoin2CN/blob/master/ch09.md#97-merkle-樹))建立一條鏈接。然后SPV節點一直等待,直到序號從300,001到300,006的六個區塊堆疊在該交易所在的區塊之上,并通過確立交易的深度是在第300,006區塊~第300,001區塊之下來驗證交易的有效性。事實上,如果網絡中的其他節點都接受了第300,000區塊,并通過足夠的工作在該塊之上又生成了6個區塊,就是代理其證明該交易不是雙重支付。 如果一個交易實際上不存在,SPV節點不會誤認為該交易存在于某區塊中。SPV節點會通過請求merkle路徑證明以及驗證區塊鏈中的工作量證明,來證實交易的存在性。可是,一個交易的存在是可能對SPV節點“隱藏”的。SPV節點毫無疑問可以證實某個交易的存在性,但它不能驗證該交易不存在(譬如同一個UTXO的雙重支付),這是因為SPV節點沒有一份關于所有交易的記錄。這個漏洞會被針對SPV節點的拒絕服務攻擊或雙重支付攻擊所利用。為了防御這些攻擊,SPV節點需要隨機連接到多個節點,以增加至少連接一個可靠節點的概率。這種隨機連接的需求意味著SPV節點也容易受到網絡分區攻擊或Sybil攻擊,這種情況更多是,SPV節點被連接到虛假節點或虛假網絡中,沒有連接到可靠節點或真正的比特幣網絡。 在絕大多數的實際情況中,具有良好連接的SPV節點是足夠安全的,它在資源需求、實用性和安全性之間維持恰當的平衡。當然,如果要保證萬無一失的安全性,最可靠的方法還是運行完整區塊鏈的節點。 >**提示** 完整的區塊鏈節點驗證交易的時候是通過檢查整個鏈中在該交易之下的數千個區塊來保證這個UTXO沒有被支付。而 SPV節點是通過檢查在其上面的少數區塊將它壓在下面的深度來驗證交易。 SPV節點使用的是一條getheaders消息,而不是getblocks消息來獲得區塊頭。響應的對等節點將用一條headers 消息發送多達2000個區塊頭。這一過程和全節點獲取所有區塊的過程沒什么區別。SPV節點還在與對等節點的連接上設置了過濾器,用以過濾從對等節點發來的未來區塊和交易數據流。任何有關的交易都是通過一條getdata的請求來讀取的。對等節點生成一條包含交易信息的tx消息作為響應。區塊頭的同步過程如圖8-7所示。 ![圖8-7 SPV節點同步區塊頭](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0807.png) 圖8-7 SPV節點同步區塊頭 由于SPV節點需要讀取特定交易從而選擇性地驗證交易,這樣就又產生了隱私風險。與全區塊鏈節點收集每一個區塊內的全部交易所不同的是,SPV節點對特定數據的請求可能無意中透露了錢包里的地址信息。例如,監控網絡的第三方可以跟蹤某個SPV節點上的錢包所請求的全部交易信息,并且利用這些交易信息把比特幣地址和錢包的用戶關聯起來,從而損害了用戶的隱私。 在引入SPV/輕量級節點后不久,比特幣開發人員添加了一個名為*布隆過濾器bloom filters*的功能來解決SPV節點的隱私風險。 Bloom過濾器允許SPV節點通過使用概率而不是固定模式的過濾機制接收交易的一個子集,無需精確地泄露他們感興趣的地址。 ## 8.9 布隆過濾器 布隆過濾器是一種基于概率的過濾方法,允許用戶無需精確指定來描述特定模式。它給用戶提供了一種有效的方式表示搜索模式同時又保護他們的隱私。在SPV節點里,這一方法被用來向對等節點請求發送匹配特定模式的交易,同時又不會泄露地址,密鑰和搜索的交易。 用我們之前的例子,一位手中沒有地圖的游客需要詢問去特定“地方教堂街23號”的路線。如果她向陌生人問到這條街, 不經意之間,就暴露了自己的目的地。布隆過濾器則會這樣問,“附近有帶‘堂’字的街道嗎?”這樣的問法會較少泄露目的地的信息。這種方法,這位游客可以仔細指定自己的地址,比如“以‘堂街’結尾”或者“‘教’字開頭的街道”。通過改變搜索的精度,她可以或多或少地透露信息,代價是獲得更多或更少的具體結果。如果她問的不太具體,會得到更多可能的地址和更好的隱私,但很多結果是無關的。如果她要求的非常具體,她得到的結果較少,但會失去隱私。 布隆過濾器可以讓SPV節點指定交易的搜索模式,可以基于準確性或私密性進行調節。一個非常具體的布隆過濾器會生成更準確的結果,但代價是透露SPV節點感興趣的模式,從而揭示用戶錢包擁有的地址。反之,如果過濾器只包含簡單的關鍵詞,將會產生更多交易的更多數據,其中許多與節點無關,但節點會保持更好的隱私。 ### 8.9.1 布隆過濾器如何工作 布隆過濾器通過一個由N個二進制數字(bit字段)的可變長度數組以及可變數量的M個哈希函數實現的。這些哈希函數的輸出值始終在1和N之間,該數值與二進制位數組相對應。并且該函數為確定性函數,也就是說任何一個使用相同布隆過濾器的節點通過該函數都能對特定輸入得到同一個的結果。布隆過濾器的準確性和私密性能通過改變長度(N)和哈希函數的數量(M)來調節。 在圖8-8中,我們用一個小型的16位數組和3個哈希函數來演示布隆過濾器的應用原理。 ![圖8-8 一個由16位數組和三個哈希函數組成的簡易Bloom過濾](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0808.png) 圖8-8 一個簡單的布隆過濾器的例子,16位的字段和3個哈希函數 布隆過濾器數組里的每一個位的初始值都為零。要將模式添加到布隆過濾器,每個哈希函數都要依次哈希這個模式。該輸入經第一個哈希函數運算后得到了一個在1和N之間的數,它在該數組(編號依次為1至N)中所對應的位被置為1,這樣把哈希函數的輸出記錄下來。接著再進行下一個哈希函數的運算,把另外一位置為1;以此類推。當全部M個哈希函數都運算過之后,一共有M個位的值從0變成了1,這個搜索模式也被“記錄”在了布隆過濾器里。 圖8-9顯示了向圖8-8里的簡易Bloom過濾器添加模式“A”。 ![圖8-9向簡易Bloom過濾器添加關鍵詞“A”](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0809.png) 圖8-9 向簡易布隆過濾器添加模式“A” 增加第二個模式就是簡單地重復之前的步驟。模式依次通過各哈希函數運算之后,相應的位改變為1,布隆過濾器記錄下該模式。需要注意的是,當布隆過濾器里添加了更多的模式時,對應的某個哈希函數的輸出值的位可能已經是1了,這種情況下,該位不會再次改變。也就是說,隨著更多的模式指向了重復的位,布隆過濾器隨著位1的增加而飽和,準確性也就開始降低了。該過濾器之所以是基于概率的數據結構,就是因為模式的增加會導致準確性的降低。 準確性取決于模式的數量以及數組大小(N)和哈希函數的多少(M)。更多位的數組和更多的哈希函數會記錄更多的模式以提高準確性。而小的數組及有限的哈希函數只能記錄有限的模式從而降低準確性。 圖8-10顯示了向該簡易布隆過濾器里增加第二個模式“B”。 ![圖8-10向簡易Bloom過濾器里增加第二個關鍵詞“B”](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0810.png) 圖8-10 向該簡易布隆過濾器里增加第二個模式“B” 為測試某一模式是否被記錄在某個布隆過濾器中,我們將該模式逐一代入各哈希函數中運算,并將所得的結果與原數組進行對比。如果所有的結果對應的位都變為了1,則表示這個模式*有可能*已被該過濾器記錄。因為這些字節1也有可能是其他模式運算的重疊結果,所以這一結論并不確定,但是是相當可能的。簡單來說,Bloom過濾器正匹配代表著“可能是”。 圖8-11是一個驗證模式“X”是否在前述Bloom過濾器中的圖例。相應的比特位都被置為1,所以這個關鍵詞很有可能是匹配的。 ![圖8-11 驗證關鍵詞“X”是否存在于Bloom過濾器中。若結果為或然正匹配,則表示“可能是”](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0811.png) 圖8-11 在布隆過濾器中測試模式“X”的存在。結果是概率正匹配,意思是“也許” 另一方面,如果我們代入模式計算后的結果任何某位為0,說明該模式并沒有被記錄在過濾器里。負匹配的結果不是可能,而是一定。也就是說,負匹配代表著“一定不是”。 圖8-12是一個驗證模式“Y”是否存在于簡易布隆過濾器中的圖例。圖中某個結果字段為0,該字段一定沒有被匹配。 ![圖8-12 驗證關鍵詞“Y”是否存在于Bloom過濾器中。若結果為必然負匹配,則表示“一定不是”](https://github.com/bitcoinbook/bitcoinbook/blob/develop/images/mbc2_0812.png) 圖8-12 在bloom過濾器中測試模式“Y”的存在。 結果是明確的否定匹配,意思是“絕對沒有!” ## 8.10 SPV節點如何使用布隆過濾器 布隆過濾器用于過濾SPV節點從其對等節點接收的交易(和包含它們的區塊),僅選擇SPV節點感興趣的交易,而不會泄露其感興趣的地址或密鑰。 SPV節點將初始化“過濾器”為“空”,在該狀態下,布隆過濾器將不會匹配任何模式。然后,SPV節點通過從其錢包控制的任何UTXO中提取公鑰哈希,腳本哈希和交易ID,然后列出所有感興趣的地址,密鑰和哈希值。 SPV節點再將其中的每一個添加到布隆過濾器,如果這些模式存在于交易中,則布隆過濾器將“匹配”,而不會透露這些模式內容。 然后,SPV節點將向對等節點發送一個filterload消息,其中包含本連接上使用的布隆過濾器。在對等節點上,針對每個傳入交易檢查布隆過濾器。全節點根據布隆過濾器檢查交易的幾個部分,尋找匹配,包括: * 交易ID * 每個交易輸出的鎖定腳本的數據組件(腳本中的每個密鑰和哈希) * 每個交易輸入 * 每個輸入簽名數據組件(或見證腳本) 通過檢查所有這些組件,可以使用布隆過濾器來匹配公鑰哈希,腳本,OP_RETURN值,簽名中的公鑰或任何將來的智能合約或復雜腳本的組件。 在建立過濾器之后,對等節點會將按照布隆過濾器測試每個交易的輸出。只有與過濾器匹配的交易才會發送到節點。 作為對節點的getdata消息的響應,對等節點將發送一條merkleblock消息,該消息僅包含與過濾器匹配的區塊的區塊頭和每個匹配交易的默克爾樹路徑(參見[【9.7 Merkle 樹】](https://github.com/tianmingyun/MasterBitcoin2CN/blob/master/ch09.md#97-merkle-樹))。然后,再發送包含過濾器匹配的交易的tx消息。 當全節點向SPV節點發送交易時,SPV節點會丟棄任何誤報,并使用正確匹配的交易來更新其UTXO集和錢包余額。隨著它更新自己的UTXO集視圖,它還會修改布隆過濾器,以匹配任何引用其剛剛發現的UTXO的交易。然后,全節點使用新的布隆過濾器來匹配新交易,并重復整個過程。 設置布隆過濾器的節點可以通過發送filteradd消息將模式交互式添加到過濾器。要清除布隆過濾器,節點可以發送一個filterclear消息。由于無法從布隆過濾器中刪除模式,因此如果不再需要該模式,則節點必須清除并重新發送新的布隆過濾器。 [BIP-37 (Peer Services)](http://bit.ly/1x6qCiO)中定義了SPV節點的網絡協議和布隆過濾機制。 ## 8.11 SPV節點和隱私 實現SPV的節點的隱私性比全節點弱一些。全節點接收所有交易,因此不會泄露它的錢包中是否使用某個地址。 SPV節點接收與其錢包中的地址相關的經過過濾的列表。因此,它降低了所有者的隱私。 布隆過濾器是減少隱私損失的一種方式。沒有它們,SPV節點將不得不明確地列出它感興趣的地址,造成嚴重的隱私違規。然而,即使使用過濾器,監控SPV客戶端流量的對手或直接連接它的點對點網絡中的節點也可以隨時隨地收集足夠的信息來了解SPV客戶端的錢包中的地址。 ## 8.12 加密和認證連接 比特幣的大多數新用戶假想比特幣節點的網絡通信是加密的。其實,比特幣的最初實現完全是明文通信。雖然這不是全節點的主要隱私問題,但SPV節點是一個很大的問題。 作為增加比特幣點對點網絡隱私性和安全性的方法,有兩種解決方案可以提供通信加密:通過BIP-150/151的*Tor傳輸和P2P認證和加密*。 ### 8.12.1 Tor網絡傳輸 Tor代表*洋蔥路由網絡The Onion Routing network*,是一個軟件項目和網絡,通過提供匿名,不可追蹤和隱私的隨機網絡路徑實現數據的加密和封裝。 Bitcoin Core提供了多種配置選項,允許運行通過Tor網絡傳輸流量的比特幣節點。此外,Bitcoin Core還可以提供Tor隱藏服務,允許其他Tor節點通過Tor網絡直接連接到您的節點。 從Bitcoin Core版本0.12開始,如果能夠連接到本地Tor服務,節點將自動提供隱藏的Tor服務。如果您安裝Tor并且運行Bitcoin Core進程賬戶具有足夠權限的用戶訪問Tor的認證cookie,那么就能自動運行。使用debug標志打開Bitcoin Core對于Tor服務的調試,如下所示: `$ bitcoind --daemon --debug=tor` 你在日志中看到“tor:ADD_ONION success”,表示Bitcoin Core已經向Tor網絡添加了隱藏的服務。 您可以在Bitcoin Core文檔(docs / tor.md)和各種在線教程中找到有關運行Bitcoin Core作為Tor隱藏服務的更多說明。 ### 8.12.2 點對點認證和加密 BIP-150和BIP-151兩個比特幣改進方案在比特幣網絡中增加支持了點對點認證和加密。這兩個BIP定義了可由兼容的比特幣節點提供的可選服務。 BIP-151為啟用BIP-151的兩個節點之間的所有通信實現協商加密。 BIP-150提供可選的對等身份認證,允許節點使用ECDSA和私鑰驗證彼此的身份。 BIP-150要求在認證之前,兩個節點按照BIP-151建立了加密通信。 截至2017年1月,BIP-150和BIP-151未在Bitcoin Core中實施。但是,這兩個提案已由至少一個名為bcoin的比特幣替代客戶端實施。 BIP-150和BIP-151允許用戶運行連接到受信任的全節點的SPV客戶端,使用加密和身份驗證來保護SPV客戶端的隱私。 此外,可以使用身份驗證來創建可信比特幣節點的網絡,防止中間人攻擊。最后,點對點加密如果廣泛部署,將加強比特幣對流量分析和隱私侵權監控的抵抗力,特別是在互聯網使用受到嚴格控制和監控的極權主義國家。 標準定義在[BIP-150 (Peer Authentication)](https://github.com/bitcoin/bips/blob/master/bip-0150.mediawiki)?and?[BIP-151 (Peer-to-Peer Communication Encryption)](https://github.com/bitcoin/bips/blob/master/bip-0151.mediawiki). ## 8.13 交易池 比特幣網絡中幾乎每個節點都會維護一份未確認交易的臨時列表,被稱為*內存池memory pool, mempool,* 或*交易池transaction pool*。節點們利用這個池來追蹤記錄那些被網絡所知曉、但還未被區塊鏈所包含的交易。例如,錢包節點會利用這個交易池來記錄那些網絡已經接收但還未被確認的、屬于該用戶錢包的傳入支付。 隨著交易被接收和驗證,它們被添加到交易池并通知到相鄰節點,從而傳播到網絡中。 有些節點的實現還維護一個單獨的孤兒交易池。如果一個交易的輸入引用的是一個未知的交易,比如找不到其父交易,該孤兒交易就會被暫時儲存在孤兒交易池中直到父交易到達。 當一個交易被添加到交易池中,會同時檢查孤兒交易池,看是否有某個孤兒交易引用了此交易的輸出(是其子交易)。任何匹配的孤兒交易會被進行驗證。如果驗證有效,它們會從孤兒交易池中刪除,并添加到交易池中,延續以這個父交易開始的鏈。鑒于新加入交易池的交易不再是孤兒交易,前述過程重復遞歸尋找進一步的后代,直至所有的后代都被找到。通過這個過程,父交易的到達觸發了一個相互依賴的交易鏈的級聯重建,在整個鏈的下游將孤兒和他們的父交易重新聯合起來。 交易池和孤兒交易池(如有實施)都是存儲在本地內存中,并不是存儲在永久性存儲設備里。更準確的說,它們是隨網絡傳入的消息動態填充的。節點啟動時,兩個池都是空的,隨著網絡中新交易不斷被接收,兩個池逐漸被填充。 有些比特幣客戶端的實現還維護一個UTXO數據庫,也稱UTXO池,是區塊鏈中所有未花費交易輸出的集合。“UTXO 池”的名字聽上去與交易池相似,但它代表了不同的數據集。UTXO池不同于交易池和孤立交易池的地方在于,它在初始化時不為空,而是包含了從創世區塊以來的數以百萬計的所有未花費交易輸出條目。UTXO池可能會被安置在本地內存,或者作為一個包含索引的數據庫表安置在永久性存儲設備中。 交易池和孤兒交易池代表的是單個節點的本地視角。取決于節點的啟動時間或重啟時間,不同節點的兩池內容可能有很大差別。相反地,UTXO池代表的是全網的自發共識,因此,不同節點間UTXO池的內容差別不大。此外,交易池和孤兒交易池只包含未確認交易,而UTXO池只包含已確認輸出。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看