前言:如何針對(duì)一個(gè)系統(tǒng)快速建立架構(gòu)層面的理解,在《區(qū)塊鏈技術(shù)指南》一書中關(guān)于“架構(gòu)”的定義有很好的闡述,即“架構(gòu)有兩個(gè)層面的涵義。一個(gè)是靜態(tài)層面的,主要是勾畫系統(tǒng)邊界、結(jié)構(gòu)、組成的組件以及系統(tǒng)之間的關(guān)聯(lián)關(guān)系;另一方面是動(dòng)態(tài)層面,主要是規(guī)范組件的行為以及組件之間的交互協(xié)議”。本文試圖從這兩個(gè)方面比對(duì)及分析比特幣和以太坊架構(gòu)之間差異性、以太坊相對(duì)比特幣演進(jìn)及優(yōu)勢(shì)所在。
一、比特幣區(qū)塊鏈架構(gòu)及要素
下圖所示即為比特幣的區(qū)塊鏈架構(gòu)構(gòu)成,分為前端和節(jié)點(diǎn)后臺(tái)兩個(gè)部分:

這其中有幾個(gè)關(guān)鍵要素:
1、錢包
錢包直接面向比特幣的用戶,用來(lái)保存用戶的私鑰數(shù)據(jù)庫(kù),同時(shí)管理用戶余額和提供基本的支付、轉(zhuǎn)賬交易功能。從部署場(chǎng)景上還可以進(jìn)一步劃分:互聯(lián)網(wǎng)錢包、移動(dòng)錢包、桌面錢包、和紙錢包,這四種錢包依次具有易用性遞減和安全等級(jí)不斷遞增的特點(diǎn)。
因?yàn)樾枰С直忍貛沤灰祝藻X包具有一個(gè)基本的屬性:需要驗(yàn)證用戶相關(guān)的支付交易,根據(jù)易用性可以采用SPV方式(即簡(jiǎn)單支付驗(yàn)證,本文中不展開說(shuō)明)、第三方平臺(tái)或可信任的服務(wù)器端驗(yàn)證。
在技術(shù)上,錢包可以看做是對(duì)比特幣API、節(jié)點(diǎn)后臺(tái)一些功能調(diào)用以及交易流程處理封裝的應(yīng)用實(shí)現(xiàn)。
2.HTTP/JSON RPC API
這是比特幣提供共的外部接口,通過(guò)該接口可以控制比特幣節(jié)點(diǎn),而提供對(duì)應(yīng)功能的是節(jié)點(diǎn)后臺(tái)的HTTP/JSON RPC服務(wù)器。該接口對(duì)于使用不同語(yǔ)言開發(fā)訪問(wèn)比特幣節(jié)點(diǎn)功能的應(yīng)用提供了便利。
3.區(qū)塊鏈管理、交易驗(yàn)證、鄰接節(jié)點(diǎn)管理及共識(shí)
這幾個(gè)要素之間有很強(qiáng)的關(guān)聯(lián)性。首先,新的比特幣節(jié)點(diǎn)初始啟動(dòng)時(shí)需要發(fā)現(xiàn)鄰接節(jié)點(diǎn),并與至少一個(gè)節(jié)點(diǎn)建立連接。連接建立后,如果是初始的比特幣全節(jié)點(diǎn)要啟動(dòng)區(qū)塊鏈管理下載并驗(yàn)證整條區(qū)塊鏈,節(jié)點(diǎn)可以并行從多個(gè)鄰接節(jié)點(diǎn)同時(shí)下載不同區(qū)間的區(qū)塊鏈。在比特幣網(wǎng)絡(luò)中,當(dāng)持續(xù)每10分鐘有新的區(qū)塊產(chǎn)生時(shí),節(jié)點(diǎn)會(huì)去驗(yàn)證及接收新的區(qū)塊,并延伸該節(jié)點(diǎn)所擁有的區(qū)塊鏈,而這一過(guò)程中涉及到了共識(shí)。共識(shí)管理在廣義上則包括:挖礦、區(qū)塊驗(yàn)證和交易驗(yàn)證規(guī)則,挖礦的概念較容易理解:不斷對(duì)區(qū)塊報(bào)頭進(jìn)行哈希處理,每次嘗試改變一個(gè)隨機(jī)數(shù),直到符合一定的條件才產(chǎn)生一個(gè)合格區(qū)塊。這里需要重點(diǎn)理解的是區(qū)塊驗(yàn)證和交易驗(yàn)證。
(1)區(qū)塊驗(yàn)證
區(qū)塊驗(yàn)證的基本流程如下圖所示

除了上述的基本驗(yàn)證以外,還有一個(gè)重要的的概念是重組區(qū)塊鏈,這種情況通常發(fā)生在一個(gè)節(jié)點(diǎn)發(fā)現(xiàn)網(wǎng)絡(luò)中存在一條不屬于當(dāng)前區(qū)塊鏈的更長(zhǎng)的區(qū)塊鏈時(shí),需要斷開現(xiàn)有的區(qū)塊并對(duì)區(qū)塊鏈進(jìn)行重組,該部分后面結(jié)合內(nèi)存池管理及回滾講解。
(2)交易驗(yàn)證
交易驗(yàn)證的條件檢查很復(fù)雜,詳細(xì)可參見《區(qū)塊鏈技術(shù)指南》一書中P68頁(yè)2.區(qū)塊驗(yàn)證中所列舉的條件明細(xì),這其中有一條是比特幣設(shè)計(jì)的精髓:需要依靠腳本來(lái)驗(yàn)證交易的合法性,即每一個(gè)將要花掉的比特幣必須有相應(yīng)的來(lái)源。在實(shí)現(xiàn)上,交易的輸入和輸出都有腳本和數(shù)值組成,并通過(guò)比特幣的腳本引擎在一個(gè)簡(jiǎn)單的堆棧式計(jì)算平臺(tái)上執(zhí)行。但也正是因?yàn)槎褩J降哪_本語(yǔ)言限制了比特幣的擴(kuò)展性,而以太坊在此基礎(chǔ)之上引入了“圖靈完備”,極大擴(kuò)展了功能應(yīng)用(這一點(diǎn)的比對(duì)會(huì)在后續(xù)的部分講到)。
這里存在兩個(gè)腳本:解鎖腳本和鎖定腳本
用于解鎖UTXO(用私鑰去匹配鎖定腳本)的腳本稱為解鎖腳本(Signature script),這也叫交易輸入;
交易輸出則是指向一個(gè)鎖定腳本(PubKey script),這個(gè)腳本表達(dá)了:誰(shuí)的簽名能匹配這個(gè)輸出地址,錢就支付給誰(shuí)。
如最常見類型的比特幣交易腳本(支付到公鑰哈希:P2PKH(Pay-to-Public-Key-Hash))組合:

基本交易驗(yàn)證流程如下所示:
1)解鎖腳本運(yùn)行過(guò)程,即入棧操作

2)鎖定腳本運(yùn)行過(guò)程,即出棧操作

4.內(nèi)存池管理、重組區(qū)塊及數(shù)據(jù)庫(kù)
在比特幣網(wǎng)絡(luò)中,一個(gè)驗(yàn)證過(guò)的交易在被放置到一個(gè)挖到的區(qū)塊之前,首先是放置在節(jié)點(diǎn)內(nèi)存中的一個(gè)交易池中,并且需要按照一定的優(yōu)先級(jí)次序從交易池中進(jìn)行選取。優(yōu)先級(jí)可按照1)交易中的輸入對(duì)應(yīng)的UTXO的“鏈齡”
鏈齡是指在鏈上記錄該交易的區(qū)塊為起點(diǎn)計(jì)算后續(xù)加入的區(qū)塊的深度計(jì)量
2)交易額的大小來(lái)劃分
而鏈齡越大或者交易額越大的交易則優(yōu)先級(jí)較高。
優(yōu)先級(jí)計(jì)算采用以下方式
priority=Sum(value of input*input age)/transaction size
另外,一些比特幣節(jié)還會(huì)維持一個(gè)“孤兒”交易池,即如果一個(gè)交易的輸入相對(duì)應(yīng)的UTXO暫時(shí)不能在鏈上被找到(有可能是因?yàn)檠舆t而未被更新導(dǎo)致),即缺失“父”交易,這些交易會(huì)被暫時(shí)放置到“孤兒”交易池中,等到“父”交易到來(lái)后再重新移到內(nèi)存池中,可參見上面區(qū)塊驗(yàn)證的流程處理。
上述處理涉及區(qū)塊鏈重組及數(shù)據(jù)庫(kù)訪問(wèn),這里簡(jiǎn)單舉例說(shuō)明:
存在A、B區(qū)塊,部分節(jié)點(diǎn)先接收到A區(qū)塊并在此基礎(chǔ)延伸鏈;部分節(jié)點(diǎn)先接收到B區(qū)塊,之后的鏈條發(fā)生分叉,如果B區(qū)塊的鏈條變長(zhǎng),對(duì)于有A區(qū)塊的網(wǎng)絡(luò)節(jié)點(diǎn)會(huì)斷開A區(qū)塊,進(jìn)而連接B區(qū)塊重組區(qū)塊鏈。其中斷開區(qū)塊、重組區(qū)塊涉及UTXO更新,被斷開的區(qū)塊中交易回退到交易內(nèi)存池,同時(shí)“回滾”記錄用來(lái)回滾斷開區(qū)塊中的交易。
除了區(qū)塊基礎(chǔ)數(shù)據(jù)存儲(chǔ)以外,比特幣還引入了數(shù)據(jù)庫(kù)便于交易操作及校驗(yàn),對(duì)應(yīng)數(shù)據(jù)存儲(chǔ)及各功能訪問(wèn)之間的關(guān)系如下:

5.比特幣節(jié)點(diǎn)與P2P網(wǎng)絡(luò)管理
比特幣的節(jié)點(diǎn)按照功能劃分可分為三種
(1)全功能節(jié)點(diǎn),即帶有錢包、RPC服務(wù)端、挖礦以及節(jié)點(diǎn)校驗(yàn)區(qū)塊和交易、鄰節(jié)點(diǎn)間消息傳遞功能的節(jié)點(diǎn)。
(2)基礎(chǔ)全節(jié)點(diǎn),這種節(jié)點(diǎn)相對(duì)全功能節(jié)點(diǎn)進(jìn)行簡(jiǎn)化,僅做區(qū)塊和交易的交易和消息中轉(zhuǎn)。
(3)SPV節(jié)點(diǎn),該節(jié)點(diǎn)主要負(fù)責(zé)對(duì)可信任的節(jié)點(diǎn)的區(qū)塊和交易做校驗(yàn)。該節(jié)點(diǎn)有兩個(gè)特殊屬性:
1)在于鄰接節(jié)點(diǎn)的連接中設(shè)置過(guò)濾器,被稱之為Bloom過(guò)濾器,并只接收包含在錢包里的公鑰地址的交易。
這里引出了兩個(gè)問(wèn)題:
符合什么規(guī)則的節(jié)點(diǎn)可以作為spv節(jié)點(diǎn),譬如可被信任或授權(quán)的?
所包含錢包里的公鑰地址由哪里獲取?
2)執(zhí)行兩個(gè)驗(yàn)證
基本過(guò)程如下所示

比特幣的節(jié)點(diǎn)及網(wǎng)絡(luò)構(gòu)成具有“去中心化”特點(diǎn),即節(jié)點(diǎn)之間的發(fā)現(xiàn)即連接完全自主化,這主要基于P2P網(wǎng)絡(luò)管理具有的基本功能實(shí)現(xiàn)
(1)發(fā)現(xiàn)鄰接節(jié)點(diǎn)
(2)連接并管理與鄰接節(jié)點(diǎn)的socket連接
(3)節(jié)點(diǎn)間交換不同P2P消息
(4)禁止異常行為的鄰接節(jié)點(diǎn)連接,防止Dos攻擊
而這些功能需要基于一個(gè)基礎(chǔ)點(diǎn):一個(gè)新的節(jié)點(diǎn)出現(xiàn)后是如何發(fā)現(xiàn)一個(gè)鄰接節(jié)點(diǎn)并與之連接?
這里有兩種方法:
1)使用“DNS種子”查詢DNS,DNS種子即提供比特幣節(jié)點(diǎn)地址的DNS服務(wù)器
2)直接將一個(gè)已知鄰節(jié)點(diǎn)作為種子節(jié)點(diǎn),通過(guò)他發(fā)現(xiàn)更多的鄰節(jié)點(diǎn),因?yàn)猷徆?jié)點(diǎn)之間會(huì)相互轉(zhuǎn)發(fā)新節(jié)點(diǎn)的地址,并將已知地址發(fā)送給新節(jié)點(diǎn)。
一個(gè)新的比特幣節(jié)點(diǎn)的缺省配置是主動(dòng)連接8個(gè)鄰節(jié)點(diǎn),同時(shí)允許最多125個(gè)鄰節(jié)點(diǎn)發(fā)起連接請(qǐng)求;另一方面,節(jié)點(diǎn)會(huì)去自動(dòng)維護(hù)與已連接節(jié)點(diǎn)之間的連接確保整個(gè)網(wǎng)絡(luò)運(yùn)行的有效性。因此,比特幣的網(wǎng)絡(luò)節(jié)點(diǎn)可以自由加入或離開,真正做到了動(dòng)態(tài)調(diào)節(jié)和自維護(hù)。
6.規(guī)則管理
比特幣節(jié)點(diǎn)必須遵循一定的規(guī)則來(lái)保證其行為同其它節(jié)點(diǎn)的一致性,這包括:
(1)共識(shí)規(guī)則
即所有節(jié)點(diǎn)都必須遵守的規(guī)則
(2)個(gè)性化規(guī)則
即共識(shí)以外的規(guī)則,典型例子如一個(gè)節(jié)點(diǎn)可以拒絕保存、中轉(zhuǎn)大于200KB對(duì)的交易。這里有一個(gè)原則:個(gè)性化規(guī)則基于共識(shí)規(guī)則,之間不能產(chǎn)生沖突。
附參考文章: