比特幣的區(qū)塊鏈架構(gòu)主要圍繞支持虛擬貨幣的實(shí)現(xiàn),雖然它有一定的靈活性,但用來支撐虛擬貨幣以外的應(yīng)用場景還顯得非常局限。近年來,區(qū)塊鏈逐漸引起IT業(yè)界的關(guān)注,并逐漸成為獨(dú)立于比特幣的一個平臺架構(gòu),其重要性越來越受到重視。區(qū)塊鏈2.0的概念也隨之產(chǎn)生。其核心理念是把區(qū)塊鏈作為一個可編程的分布式信用基礎(chǔ)設(shè)施,支撐智能合約應(yīng)用,以與過去比特幣區(qū)塊鏈作為一個虛擬貨幣支撐平臺區(qū)別開來。具體說來就是,不僅僅把區(qū)塊鏈作為一個去中心化的虛擬貨幣和支付平臺,而是通過增加鏈上的擴(kuò)展性功能,把區(qū)塊鏈的技術(shù)范圍擴(kuò)展到支撐一個去中心化的市場,交易內(nèi)容可以包括房產(chǎn)的契約、權(quán)益及債務(wù)憑證、知識產(chǎn)權(quán),甚至汽車、藝術(shù)品等。
區(qū)塊鏈2.0提供一套新的協(xié)議(區(qū)塊鏈2.0協(xié)議)支撐新型的去中心化應(yīng)用。如果用互聯(lián)網(wǎng)協(xié)議來做類比,區(qū)塊鏈1.0就相當(dāng)于TCP/IP協(xié)議,而區(qū)塊鏈2.0就相當(dāng)于HTTP、SMTP和FTP等高級協(xié)議。甚至有把區(qū)塊鏈1.0比做電話,而區(qū)塊鏈2.0相當(dāng)于智能電話的比喻。在比特幣后,出現(xiàn)很多被稱為區(qū)塊鏈2.0的平臺,其中,最具代表性的是以太坊平臺。下面簡單介紹一下以太坊架構(gòu)。
以太坊的設(shè)計主要還是以比特幣架構(gòu)為基礎(chǔ)。前面幾章已經(jīng)介紹了以太坊的基本架構(gòu),本章不再詳細(xì)敘述,下面只對和比特幣架構(gòu)不同的幾個主要方面做重點(diǎn)討論。以太坊架構(gòu)圖3-9所示。
1.賬戶設(shè)計
比特幣沒有賬戶的概念。每個用戶的余額都是從他們在區(qū)塊鏈上的UTXO計算出來的。以太坊則有兩種類型的賬戶:一種是外部所有賬戶(EOA),另一種是合約(Contract)賬戶。外部所有賬戶就是我們一般意義上的用戶賬戶,它由私鑰控制。合約是一種特殊的可編程賬戶,合約存在以太坊區(qū)塊鏈上,它是代碼(它的功能)和數(shù)據(jù)(它的狀態(tài))的集合。合約受代碼控制并由外部所有賬戶激活。
以太坊的設(shè)計是將區(qū)塊鏈作為一個通用的管理對象狀態(tài)轉(zhuǎn)換的去中心化平臺,賬戶就是有狀態(tài)的對象。外部所有賬戶的狀態(tài)就是余額,而合約賬戶的狀態(tài)可以是余額、代碼執(zhí)行情況,以及合約的存儲。以太坊網(wǎng)絡(luò)的狀態(tài)就是所有賬戶的狀態(tài),該狀態(tài)由每個區(qū)塊的交易來更新,同時需在全網(wǎng)形成共識。用戶和以太坊區(qū)塊鏈的交互需要通過對賬戶的交易來實(shí)現(xiàn)。
每個以太坊的外部所有賬戶由一對密鑰定義,一個是私鑰,一個是公鑰。區(qū)塊鏈的EOA賬戶由它們的地址來做索引。取公鑰的后20位作為地址,這和比特幣的地址不一樣。每個公私鑰對被編碼存放在一個密鑰文件(Keyfile)中。密鑰文件采用JSON格式,可以用文本編輯器打開來看。密鑰文件的私鑰都是用在建立賬戶時輸入的口令來加密的。密鑰文件存在以太坊節(jié)點(diǎn)的數(shù)據(jù)目錄中的keystore子目錄中。密鑰文件需要經(jīng)常備份,否則如果失掉密鑰文件,賬戶里的以太幣也就無法找回了。
合約賬戶可以執(zhí)行圖靈完備的計算任務(wù),也可在合約賬戶之間傳遞消息,合約編譯成以太坊虛擬機(jī)字節(jié)碼(EthereumVirtual Machine Bytecode),并記錄在區(qū)塊鏈上。
外部所有賬戶可以通過發(fā)送交易到合約來實(shí)現(xiàn)對合同的調(diào)用。這需要提供幾個參數(shù),例如EOA的地址、合約的地址,以及數(shù)據(jù)。數(shù)據(jù)部分包括需要調(diào)用的合約里的方法(method)以及其傳遞的參數(shù)。這個需要用到Application Binary Interface(ABI)來作為傳遞數(shù)據(jù)的編碼和解碼的標(biāo)準(zhǔn)。關(guān)于ABI的詳細(xì)信息可以參考以太坊wiki網(wǎng)頁https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI 。
2.區(qū)塊鏈設(shè)計
比特幣采用Merkle樹來將交易的哈希值按一定算法組成二叉樹狀結(jié)構(gòu)1,頂層節(jié)點(diǎn)的哈希值相當(dāng)于整個交易清單的指紋,可以用來校驗(yàn)交易清單。中本聰采用Merkle樹設(shè)計,也是為了輕量級節(jié)點(diǎn)能通過SPV(簡化支付驗(yàn)證)方式來方便地校驗(yàn)交易。SPV不用下載整個交易清單,而是只需要區(qū)塊報文頭中交易清單頂層節(jié)點(diǎn)的哈希值,以及與自身節(jié)點(diǎn)相關(guān)的交易,然后可以通過向其他節(jié)點(diǎn)查詢其他相鄰交易,就可以完成對某個交易是否包含在區(qū)塊鏈中某個區(qū)塊的驗(yàn)證。 區(qū)塊鏈的核心原理http://www.868qkl.com/shenme/9.html以太坊的區(qū)塊鏈的每個區(qū)塊不但保存著交易清單,還保存最新的狀態(tài)。以太坊作為一個通用的區(qū)塊鏈編程平臺,引入了賬戶概念,由此它也帶來更為復(fù)雜的校驗(yàn)和查詢需求。例如要查詢賬戶的余額或判斷一個賬戶是否存在,光用比特幣的Merkle樹就滿足不了要求。因此以太坊采用Merkle Patricia樹來實(shí)現(xiàn)對交易和狀態(tài)的校驗(yàn)和查詢 [2] 。下面看看交易和狀態(tài)面臨的問題。
以太坊的狀態(tài)包含一個鍵值表(key-value map),其中鍵是地址,值是賬戶里聲明的變量,包括余額、隨機(jī)數(shù)(nonce)、代碼和賬戶的存儲(存儲也以一棵樹的形式來組織)。與交易數(shù)據(jù)只能增不能改不一樣,賬戶的狀態(tài)經(jīng)常被改變,其余額、隨機(jī)數(shù)經(jīng)常變。
另外,新的賬戶也經(jīng)常被插入,鍵在存儲里也被經(jīng)常插入和刪除。因此Merkle樹不適合這種情況,而需要一種可以在插入、更新和刪除操作后快速計算新的樹根哈希值,而不需要重新計算整棵樹的數(shù)據(jù)結(jié)構(gòu)。同時,樹的深度是有限的,即使在有攻擊者試圖通過故意發(fā)很多交易來盡量增加樹的深度的情況下,不然一個攻擊者可以通過操縱樹的深度,以使得每個更新都變得非常慢,來對平臺實(shí)施拒絕服務(wù)攻擊。
還有一個要求是樹的根哈希只是與樹的數(shù)據(jù)有關(guān),而與更新的順序無關(guān)。不同的更新順序或者甚至重新計算整個樹的根哈希值都不會改變樹的根哈希值。Patricia樹是符合這些要求的數(shù)據(jù)結(jié)構(gòu)。
簡單來說,以太坊的賬戶的狀態(tài)由鍵值表(Key-Value Map)來表示,在Patricia樹里,鍵被編碼成向下訪問樹的路徑。在以太坊的Patricia里,每個節(jié)點(diǎn)有16個子節(jié)點(diǎn),所以路徑用十六進(jìn)制來編碼。例如,鍵“dog”的十六進(jìn)制編碼是6461567,所以要訪問鍵“dog”所對應(yīng)的值,就必須先從根節(jié)點(diǎn)開始,向下到第6個節(jié)點(diǎn),然后再由該節(jié)點(diǎn)向下到第4個節(jié)點(diǎn),以此類推,一直到最后。
在區(qū)塊鏈的區(qū)塊報文頭中,不像比特幣那樣僅僅存放一個交易清單的Merkle樹根哈希值,而是存放了3個根哈希值:一個是交易的Merkle根哈希值,另外一個是狀態(tài)的根哈希值,還有一個是收據(jù)的根哈希值。 另外一個和比特幣的不同是,以太坊的區(qū)塊鏈中的每個區(qū)塊保存區(qū)塊鏈號和區(qū)塊難度。
3.PoW機(jī)制
以太坊的PoW(工作量證明)算法叫Ethash算法(是一個經(jīng)過修改的Dagger-Hashimoto算法),該算法主要尋找一個隨機(jī)數(shù)作為輸入,使得運(yùn)算結(jié)果小于一個特定的難度門檻。PoW機(jī)制的前提是,不存在比逐個試更好的找到該隨機(jī)數(shù)的方法,同時驗(yàn)證結(jié)果必須非常方便且成本小。由于哈希運(yùn)算的結(jié)果是均勻分布(Uniform Distribution)的,所以可以保證,通常找到該隨機(jī)數(shù)的時間取決于難度門檻。這樣的話可以通過控制難度來控制在網(wǎng)絡(luò)上找到一個新區(qū)塊的時間。以太坊是通過動態(tài)調(diào)控難度來達(dá)到平均每15s在全網(wǎng)中找到一個新區(qū)塊
的。每15s的“心跳”基本上是全網(wǎng)更新系統(tǒng)狀態(tài)的節(jié)奏,并保證當(dāng)攻擊者的計算能力不超過全網(wǎng)的計算能力的一半時,攻擊者無法改寫交易記錄或進(jìn)行分叉(以便進(jìn)行雙花交易)
。這就是所謂的“51%”攻擊。網(wǎng)絡(luò)上的礦工的挖礦收入期望直接反映他們擁有的計算力,或者哈希速率在整個網(wǎng)絡(luò)中的占比。
比特幣的工作量證明機(jī)制依靠的僅僅是CPU計算難度問題,以太坊的Ethash工作量證明機(jī)制加入內(nèi)存難度,使得它具有抵抗單憑哈希運(yùn)算優(yōu)化的ASIC挖礦機(jī)的屬性。內(nèi)存難度是通過
在算法設(shè)計中要求選擇由隨機(jī)數(shù)和區(qū)塊報文頭決定的一部分固定資源,這些資源一般是幾個GB的數(shù)據(jù),叫“有向無環(huán)圖”(DAG)。每30000個區(qū)塊后需要有一個全新的DAG。這相當(dāng)
于一個125小時的窗口,或5.2天,稱為一個epoch。這個圖需要一段時間才能生成。因?yàn)镈AG只和區(qū)塊鏈深度相關(guān),因此可以提前生成。如果沒有現(xiàn)成的,以太坊的客戶端需要等生成
了DAG后才能產(chǎn)生新的區(qū)塊。這樣的話在每個epoch轉(zhuǎn)換的時候,如果客戶端不預(yù)先生成DAG,網(wǎng)絡(luò)就會出現(xiàn)大規(guī)模的延遲。當(dāng)一個礦工節(jié)點(diǎn)第一次啟動時,需要等DAG生成之后才能開
始挖礦。
以太坊的Go語言實(shí)現(xiàn)程序geth和C語言實(shí)現(xiàn)的挖礦程序ethminer都實(shí)現(xiàn)自動DAG生成,并在epoch轉(zhuǎn)換的過程中維護(hù)兩個DAG。以太坊的Ethash算法可以在較慢的CPU環(huán)境中進(jìn)行哈希運(yùn)
算,但在挖礦節(jié)點(diǎn)上可以通過增加內(nèi)存和帶寬來提升挖礦速度。對內(nèi)存的高要求使得大型礦的礦主沒有太大的比較性超線性收益;對帶寬的高要求使得用堆超快的計算單元來共享存
儲的方法并不能帶來更好的收益。這樣對礦池挖礦來說沒有太多好處,因此以太坊從設(shè)計上希望避免出現(xiàn)像比特幣那樣的礦池算力集中化的問題。
類似比特幣,以太坊的挖礦靜態(tài)收益將隨著時間推移而逐漸減少,目前靜態(tài)收益是每挖到一個區(qū)塊獲得5以太幣。未來礦工的收益將主要依靠發(fā)送交易的用戶支付的“燃料”來獲取
收益。以太坊的礦工獎勵制度比比特幣復(fù)雜。很多參考資料沒有給出具體的獎勵數(shù)額,有些甚至是錯誤的,例如對挖到“叔區(qū)塊”的礦工獎勵的描述,有些資料認(rèn)為是(7/8)
×5=4.375以太幣,其實(shí)這是不準(zhǔn)確的。筆者參考了計算獎金的源代碼,具體的獎金機(jī)制描述如下。
每當(dāng)一個礦工挖到一個區(qū)塊,他將獲得5.0以太幣(Ether)的靜態(tài)收益,同時獲得在區(qū)塊上的“燃料”(gas),價值取決于當(dāng)前的“燃料”價格。另外礦工也獲得一個將“叔區(qū)塊
”(uncle)包含進(jìn)區(qū)塊鏈的額外獎勵,相當(dāng)于每包含一個uncle區(qū)塊將獲得(1/32)×5以太幣的收益。而產(chǎn)生“叔區(qū)塊”的礦工將按下面的公式獲得獎勵:
挖到“叔區(qū)塊”礦工獎勵=(叔區(qū)塊ID+8-當(dāng)前區(qū)塊ID)×5/8
例如,假設(shè)當(dāng)前區(qū)塊ID是1600,叔區(qū)塊ID是1598,那么挖到叔區(qū)塊1598的礦工將獲得(6/8)×5,等于3.75以太幣。如果叔區(qū)塊的ID是1599,那么挖到叔區(qū)塊1599的礦工將獲得
(7/8)×5,也就是4.375以太幣的獎勵。
注意:所謂“叔區(qū)塊”,是指符合難度條件,但區(qū)塊里的交易不被確認(rèn)的區(qū)塊,或叫“廢塊”(Stale)。比如礦工A挖到一個符合難度規(guī)定的合規(guī)區(qū)塊a,而幾乎同時礦工B也挖到符
合標(biāo)準(zhǔn)的區(qū)塊b,但由于網(wǎng)絡(luò)延遲,區(qū)塊b沒有被確認(rèn),成了廢塊,而a成了網(wǎng)絡(luò)共識的區(qū)塊,被包括在區(qū)塊鏈中。由于以太坊產(chǎn)生區(qū)塊的速度比比特幣產(chǎn)生區(qū)塊的速度要快很多,因
此在網(wǎng)絡(luò)繁忙的時候,相對于比特幣系統(tǒng)更容易出現(xiàn)“廢塊”。在比特幣系統(tǒng)中,生產(chǎn)廢塊的礦工只能自認(rèn)倒霉,是沒有獎勵的。而在以太坊中,產(chǎn)生“叔區(qū)塊”的礦工和將“叔區(qū)
塊”包括在區(qū)塊鏈上的礦工都能得到獎勵。這樣產(chǎn)生廢塊的算力也被包括進(jìn)來,有效地增強(qiáng)了安全性,使得攻擊者不容易追上一個帶“叔區(qū)塊”的主鏈。同時通過給“叔區(qū)塊”獎勵
,也避免出現(xiàn)像比特幣那樣計算力高度集中的礦池,因?yàn)榈V池相對來說不像單個挖礦節(jié)點(diǎn)那樣容易產(chǎn)生廢塊。嚴(yán)格說來,“叔區(qū)塊”是在當(dāng)前鏈接區(qū)塊往前推最多6個的“祖先”廢
塊,每個區(qū)塊最多能鏈接兩個“叔區(qū)塊”。
以太坊采用一個與比特幣不同的算法叫GHOST(幽靈)來構(gòu)建區(qū)塊鏈。GHOST的全稱是Greedy Heaviest Observed Subtree,中文直譯是“貪婪最重觀察子樹”。嚴(yán)格來說,以太坊的
區(qū)塊鏈不是一個鏈條,而像一棵樹,它包含前面提到的“叔區(qū)塊”。
在比特幣系統(tǒng)中,礦工按一定的優(yōu)先級把未確認(rèn)的交易打包到新發(fā)現(xiàn)的區(qū)塊上。交易的優(yōu)先級按交易額和鏈齡(指UTXO存在的時間)來決定。交易額越大、鏈齡越高,優(yōu)先級就越高
。交易費(fèi)用是用戶的輸入和輸出之差。如果輸入和輸出之差為零,隨著交易發(fā)生的時間越來越久,其在交易池的優(yōu)先級會逐漸升高。因此一般來說,即使付給礦工零交易費(fèi)用的交易
都有機(jī)會被礦工包含在區(qū)塊鏈上。當(dāng)然個別礦工可以有自己的規(guī)則,可以拒絕零交易費(fèi)的交易。而在以太坊平臺,不提供“燃料”的交易不會被執(zhí)行,也不會被包含在區(qū)塊鏈上。以
太坊的交易費(fèi)用按以下公式計算:
Total cost=gasUsed×gasPrice
其中g(shù)asUsed是執(zhí)行該交易所消耗的燃料,燃料的價格由用戶和礦工決定,一般來說在用戶建一個交易的時候,可以提一個燃料價格。在以太坊發(fā)布的第一版本Frontier(前線)中
,以太坊客戶端的默認(rèn)燃料價格是0.05e12wei,大約是一億分之五個以太幣。礦工一般不會接受低于普遍價的燃料價格。
4.計算和圖靈完備
以太坊作為通用的區(qū)塊鏈平臺,需要提供比比特幣更強(qiáng)大的計算能力。前面說過,從安全角度出發(fā),比特幣的設(shè)計專門選擇一個不具圖靈完備性的腳本引擎,目前能通行的比特幣腳
本指令也不多,但在虛擬貨幣的應(yīng)用場景已經(jīng)是綽綽有余了。而在以太坊上,一個和比特幣非常大的不同點(diǎn)就是選擇了圖靈完備的計算環(huán)境——以太坊虛擬機(jī)(EVM)。這就意味著
在EVM上可以做所有的能想得到計算,包括無限循環(huán)。EVM指令包括一個JUMP的跳轉(zhuǎn)指令,可讓程序跳回前面的程序代碼,也可以像條件判斷語句那樣做條件跳轉(zhuǎn),當(dāng)滿足一定條件時
將程序跳轉(zhuǎn)到另一個地方執(zhí)行。另外,一個合約可以調(diào)用其他合約,這提供了潛在的遞歸調(diào)用的功能。這就很自然地會導(dǎo)致一個問題:一個搞破壞的用戶能否通過強(qiáng)制礦工或全節(jié)點(diǎn)
進(jìn)入死循環(huán)而將他們基本關(guān)掉呢?這個其實(shí)也是一個“停機(jī)問題”,也就是說,通常沒有任何辦法去判定一個程序會否停機(jī)。以太坊怎么解決這個問題呢?它首先要求每個交易要給
出最大的計算步驟,交易的發(fā)起人要提供Gas作為交易費(fèi)以供礦工把交易加進(jìn)區(qū)塊。如果實(shí)際運(yùn)行超過了該最大計算步驟,計算將被終止,而交易費(fèi)會歸挖到區(qū)塊的礦工所有。因此
以太坊采用經(jīng)濟(jì)的方法來保證以太坊平臺的安全。
以太坊網(wǎng)絡(luò)的每個節(jié)點(diǎn)都運(yùn)行EVM并執(zhí)行合約代碼,因此以太坊就像一個并行運(yùn)行的“世界電腦”,在所有的節(jié)點(diǎn)上同時進(jìn)行賬戶的狀態(tài)轉(zhuǎn)換,并形成網(wǎng)絡(luò)層面對所有賬戶狀態(tài)的共
識。雖然這種P2P的運(yùn)行方式并不是最高效的,但卻是最有安全保障的,可以說,這部“世界電腦”永不停機(jī)。
5.EVM高級語言
比特幣不提供高級語言的支持,以太坊則提供高級語言讓用戶編寫智能合約。以太坊的高級語言最后會編譯成在EVM中執(zhí)行的EVM字節(jié)碼(bytecode),部署在以太坊區(qū)塊鏈上。以太
坊提供3種編程語言:Solidity、Serpent和LLL。
·Solidity類似JavaScript語言,是目前以太坊上最流行的智能合約編程語言。
·Serpent類似Python編程語言,它結(jié)合了低級語言的效率和易用的編程方式。Serpent用LLL語言來編譯。
·LLL是Lisp Like Language的簡稱,顧名思義是一個像Lisp的語言。它有些像匯編語言,設(shè)計得非常簡約,基本上就是在EVM上的一個微小的封裝。
另外一個類似C的語言Mutan已經(jīng)基本棄用,不再被維護(hù)。
6.以太坊P2P網(wǎng)絡(luò)
(1)RLPx協(xié)議
以太坊網(wǎng)絡(luò)節(jié)點(diǎn)間的通信采用DΞVp2p線上協(xié)議。節(jié)點(diǎn)間采用RPLx [3] 編碼及認(rèn)證的通信傳輸協(xié)議來傳輸消息包,即提供發(fā)送和接收消息的協(xié)議功能。節(jié)點(diǎn)可以自由地在任何TCP端
口發(fā)布和接受連接,默認(rèn)的端口是30303。目前正式版的RLPx實(shí)現(xiàn)了以下功能:
·單一協(xié)議的UDP節(jié)點(diǎn)發(fā)現(xiàn)
·ECDSA簽名的UDP
·加密握手/認(rèn)證
·節(jié)點(diǎn)持久性
·加密/認(rèn)證TCP
·TCP幀處理
-
區(qū)塊鏈
+關(guān)注
關(guān)注
111文章
15562瀏覽量
105923 -
以太坊
+關(guān)注
關(guān)注
14文章
1838瀏覽量
31954
原文標(biāo)題:區(qū)塊鏈2.0架構(gòu):以太坊區(qū)塊鏈的介紹
文章出處:【微信號:C_Expert,微信公眾號:C語言專家集中營】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論