鄒秀清/ZOU Xiuqing
丁勇/DING Yong
(桂林電子科技大學(xué),廣西桂林541004)
隨著互聯(lián)網(wǎng)行業(yè)的發(fā)展,越來(lái)越多新型的網(wǎng)絡(luò)平臺(tái)融入到了人們的生活,人們?nèi)粘I疃家玫教詫?、京東等交易平臺(tái),使用支付寶、小米錢包、微信等來(lái)支付。這些平臺(tái)都有一套獨(dú)立的注冊(cè)、登錄、認(rèn)證和權(quán)限管理的系統(tǒng),每一個(gè)用戶在系統(tǒng)中都充當(dāng)不同的角色,并擁有不同的權(quán)限,這種中心化系統(tǒng)給人們帶來(lái)的弊端有以下幾點(diǎn):
(1)如果有多個(gè)系統(tǒng)需要進(jìn)行登錄、認(rèn)證,管理員的維護(hù)和管理的成本將會(huì)大幅增加,并隨著規(guī)模的增加,維護(hù)難度會(huì)增加。
(2)用戶必須記住自己的多個(gè)賬號(hào)、密碼,如果賬號(hào)很多,使用起來(lái)將非常不便捷。
(3)容易被黑客攻擊,帶來(lái)?yè)p失。
(4)中心化系統(tǒng)不可信,管理員可以隨時(shí)篡改數(shù)據(jù)。
區(qū)塊鏈技術(shù)是一種利用去中心化共識(shí)的機(jī)制維護(hù)一個(gè)完整的、分布式的、不可篡改的賬本數(shù)據(jù)庫(kù)的技術(shù),它能夠讓區(qū)塊鏈中的參與者在無(wú)需建立信任關(guān)系的前提下實(shí)現(xiàn)一個(gè)統(tǒng)一的賬本系統(tǒng)。近年來(lái),區(qū)塊鏈以集成分布式數(shù)據(jù)存儲(chǔ)、點(diǎn)對(duì)點(diǎn)(P2P)傳輸、新型加密算法和共識(shí)機(jī)制等技術(shù)的特點(diǎn),已越來(lái)越成為許多國(guó)家政府和國(guó)際組織研究討論的熱點(diǎn),依靠互聯(lián)網(wǎng)的產(chǎn)業(yè)也紛紛加大了對(duì)其投入的力度[1],但是目前全球還沒(méi)有政府大力推廣將該技術(shù)應(yīng)用于物聯(lián)網(wǎng)的身份識(shí)別系統(tǒng)。
如今新型的區(qū)塊鏈技術(shù)給人們帶來(lái)了解決方案:區(qū)塊鏈建立了動(dòng)態(tài)的P2P網(wǎng)絡(luò),沒(méi)有了中心化服務(wù),帳本均分布在每個(gè)節(jié)點(diǎn)中,所有的節(jié)點(diǎn)一同維護(hù);帳本上記錄了該區(qū)塊鏈自創(chuàng)建以來(lái)的記下的所有交易記錄,通過(guò)密碼學(xué)的安全機(jī)制,使得所有記錄不可修改、真實(shí)可信;每個(gè)人都是一個(gè)節(jié)點(diǎn),通過(guò)彼此之間的信任來(lái)建立區(qū)塊鏈的信任。區(qū)塊鏈網(wǎng)絡(luò)沒(méi)有傳統(tǒng)的中心管理員,整個(gè)網(wǎng)絡(luò)的運(yùn)作由線上的電腦共同進(jìn)行維護(hù),使得運(yùn)營(yíng)成本大幅降低。
本設(shè)計(jì)組成的框架主要包括四大模塊:數(shù)據(jù)層模塊、網(wǎng)絡(luò)層模塊、共識(shí)層模塊和接口層模塊。通過(guò)接入到同一個(gè)區(qū)塊鏈網(wǎng)絡(luò)中,使用統(tǒng)一的接口層進(jìn)行交互,同時(shí)接口層還能和網(wǎng)絡(luò)層和共識(shí)層通過(guò)底層協(xié)議進(jìn)行交互,網(wǎng)絡(luò)層負(fù)責(zé)發(fā)現(xiàn)區(qū)塊鏈網(wǎng)絡(luò)中的P2P節(jié)點(diǎn)和數(shù)據(jù)的傳輸,共識(shí)層負(fù)責(zé)身份認(rèn)證,數(shù)據(jù)層負(fù)責(zé)存儲(chǔ)數(shù)據(jù)。
1.1.1 區(qū)塊鏈技術(shù)基本原理
假設(shè)Bob要在互聯(lián)網(wǎng)上向Alice轉(zhuǎn)賬,每次轉(zhuǎn)賬都會(huì)產(chǎn)生交易記錄,將所有的交易記錄進(jìn)行連接,生成總帳單,總賬單包含每個(gè)人的余額。記賬時(shí),應(yīng)需保持公平、誠(chéng)信的態(tài)度,使得雙方能夠相互信任;但記賬人可能會(huì)作假,使得雙方的信任程度降低,這是很典型的欺詐行為。區(qū)塊鏈技術(shù)則可以很好地解決這一問(wèn)題,沒(méi)有人可以作假。
現(xiàn)把賬單模型進(jìn)行縮小,規(guī)定:每次更新、修改數(shù)據(jù)必須在原有的賬單中進(jìn)行,并且新賬單包含時(shí)間戳、前一個(gè)賬單的哈希值等數(shù)據(jù)。將這些帳本累加起來(lái)稱為總帳本,總帳本將所有的塊鏈接起來(lái),組成區(qū)塊鏈,圖1表示一條區(qū)塊鏈中的3個(gè)區(qū)塊。
1.1.2 區(qū)塊鏈的去中心化
在2008年的金融危機(jī)中,比特幣的創(chuàng)始人中本聰發(fā)明了比特幣,它成為了第一個(gè)去中心化的數(shù)字貨幣。區(qū)塊鏈?zhǔn)且粋€(gè)分布式網(wǎng)絡(luò),每個(gè)節(jié)點(diǎn)都會(huì)存放所有交易的副本,并自動(dòng)同步。節(jié)點(diǎn)可以是用戶的電腦、手機(jī),或是其他設(shè)備。如圖2所示,區(qū)塊鏈網(wǎng)絡(luò)節(jié)點(diǎn)是扁平化的,每個(gè)節(jié)點(diǎn)的地位相等、公平,并以扁平拓?fù)涞姆绞较蛳噜徆?jié)點(diǎn)進(jìn)行數(shù)據(jù)交互[2]。
假設(shè)Bob想給他人轉(zhuǎn)賬,Bob就得向全網(wǎng)廣播他要轉(zhuǎn)賬的消息,并需全網(wǎng)達(dá)成共識(shí),才能認(rèn)為他的消息是合法的,且每個(gè)節(jié)點(diǎn)都會(huì)保存他轉(zhuǎn)賬信息。全網(wǎng)沒(méi)有中心服務(wù)器,沒(méi)有人能擁有管理的權(quán)力,只要規(guī)則定好了,就必須照著規(guī)則做,沒(méi)有人可以改變,這其實(shí)就是區(qū)塊鏈去中心化的魅力所在。
所有節(jié)點(diǎn)都相當(dāng)于“校驗(yàn)員”,它們無(wú)時(shí)無(wú)刻不在檢查區(qū)塊中的交易信息是否正確,并且在檢查交易的時(shí)候,不斷嘗試產(chǎn)生隨機(jī)數(shù),計(jì)算哈希值,使數(shù)據(jù)具有很強(qiáng)的安全性,黑客無(wú)法入侵,無(wú)法修改賬戶余額。隨著用戶的增加,越來(lái)越多的后續(xù)節(jié)點(diǎn)(用戶)加入到了比特幣網(wǎng)絡(luò)中,共同完成共識(shí)的過(guò)程[3];而整個(gè)過(guò)程中網(wǎng)絡(luò)中每個(gè)節(jié)點(diǎn)的地位是相同的。比特幣不是憑空產(chǎn)生,而是通過(guò)消耗了電力、物力并應(yīng)運(yùn)算而產(chǎn)生的,因此具有價(jià)值,可以兌換成現(xiàn)有的貨幣。
圖2 去中心化的節(jié)點(diǎn)圖
哈希函數(shù)也叫做哈希算法,不論輸入字符串的長(zhǎng)短,生成簽名的長(zhǎng)度都是固定的,因此可以作為一段數(shù)據(jù)的數(shù)字指紋,便于區(qū)分每個(gè)消息。生成的摘要可作為簽名,以確保數(shù)據(jù)的真實(shí)性。賬戶的創(chuàng)建需要一個(gè)非對(duì)稱加密密鑰對(duì),以太坊選擇的是橢圓曲線加密算法(ECC)中的Secp256k1,依據(jù)速度、安全性等參數(shù)確定賬戶的地址,具體的方法如下:
(1)創(chuàng)建一個(gè)隨機(jī)私鑰,由64個(gè)十六進(jìn)制的字符構(gòu)成;
(2)從私鑰中導(dǎo)出公鑰;
(3)從公鑰中導(dǎo)出地址。
使用Secp256k1生成256位公鑰/密鑰,然后編譯成64位長(zhǎng)度的十六進(jìn)制字符串;采用公鑰的Keccak-256哈希算法,得到一個(gè)32字節(jié)的字十六進(jìn)制字符串,接下來(lái)對(duì)該字符串進(jìn)行取截,取字符串的最后20個(gè)字節(jié)(即刪除前12個(gè)字節(jié)),得到了40個(gè)字節(jié)的字符串,在簽名加上0x前綴,就可以得到一個(gè)42個(gè)字節(jié)長(zhǎng)的地址,該地址就是以太坊用戶全網(wǎng)唯一的賬號(hào)。
Merkle樹在區(qū)塊鏈中尤其重要,相當(dāng)于用大量的數(shù)據(jù)塊來(lái)進(jìn)行哈希運(yùn)算。Merkle樹將2個(gè)相鄰的認(rèn)證請(qǐng)求進(jìn)行哈希計(jì)算,逐步堆積到Markle樹根。這種哈希算法的好處就是讓歷史數(shù)據(jù)不可篡改、真實(shí)可信[4]。節(jié)點(diǎn)的值是它相連2個(gè)葉子節(jié)點(diǎn)的哈希,這就導(dǎo)致整個(gè)Merkle樹中的數(shù)據(jù)都是互相關(guān)聯(lián)的,改動(dòng)其中一個(gè)數(shù)據(jù),將會(huì)徹底改變整個(gè)區(qū)塊的結(jié)構(gòu),因此給身份的證明提供了一個(gè)非常簡(jiǎn)潔的機(jī)制。
Merkle樹的最初應(yīng)用是在比特幣中,即使用了Merkle樹來(lái)存儲(chǔ)每個(gè)區(qū)塊的交易。每個(gè)Merkle樹從塊到根都是由哈希的分支組成,如圖3所示。由于Merkle樹采用了非常強(qiáng)的哈希算法,且哈希后的摘要求逆幾乎不可能實(shí)現(xiàn),因此Merkle樹提供了真實(shí)可信的數(shù)據(jù)驗(yàn)證方法。
每個(gè)區(qū)塊頭包含如圖4所示的內(nèi)容。將相連的數(shù)據(jù)區(qū)塊的數(shù)據(jù)進(jìn)行相連,通過(guò)上一區(qū)塊的哈希值和當(dāng)前區(qū)塊的哈希值將所有的區(qū)塊請(qǐng)求進(jìn)行關(guān)聯(lián)。如果修改了其中一個(gè)數(shù)據(jù),將影響所有在當(dāng)前區(qū)塊鏈網(wǎng)絡(luò)上的區(qū)塊,因此數(shù)據(jù)不可能被篡改,所有的認(rèn)證請(qǐng)求不可偽造,極大提高了區(qū)塊鏈的安全性。
ECDSA是數(shù)字簽名算法(DSA)的其中一個(gè)例子。和非對(duì)稱加密算法(RSA)進(jìn)行對(duì)比,在相同的安全強(qiáng)度下,ECDSA可以使用的密鑰更短,從而節(jié)省網(wǎng)絡(luò)和存儲(chǔ)空間,具有較高的研究?jī)r(jià)值[5]。
圖3 Merkle樹的結(jié)構(gòu)
圖4 數(shù)據(jù)區(qū)塊頭的結(jié)構(gòu)
在本設(shè)計(jì)方案中,首先要避免數(shù)據(jù)明文傳輸?shù)臉O大不安全因素,同時(shí)要保證交互雙方的身份真實(shí)性,因此需要利用公鑰加密算法中非對(duì)稱加密的優(yōu)勢(shì)。使用本設(shè)計(jì)方案進(jìn)行數(shù)據(jù)傳輸時(shí),將服務(wù)器的公鑰輸出在客戶端,客戶端使用公鑰加密,在信息交互時(shí)數(shù)據(jù)以密文方式傳給服務(wù)器端,再由相應(yīng)私鑰得到明文數(shù)據(jù)[6]。
Alice將要給Bob發(fā)送一條消息,要求消息包含數(shù)字簽名來(lái)進(jìn)行身份識(shí)別,那么可以定義一組參數(shù)(CURVE,G,n),其中CURVE表示橢圓曲線的點(diǎn)域以及它所使用的幾何方程,G表示橢圓曲線基點(diǎn),大素?cái)?shù)n是橢圓曲線的階數(shù)[7]。接下來(lái)我們介紹數(shù)字簽名的具體過(guò)程和驗(yàn)證數(shù)字簽名的具體過(guò)程。
(1)數(shù)字簽名的過(guò)程
如果Alice要發(fā)出認(rèn)證請(qǐng)求,她希望能對(duì)消息m進(jìn)行簽名,因此將橢圓曲線的參數(shù)設(shè)計(jì)為D=(p,a,b,G,n,h),其中對(duì)應(yīng)的密鑰對(duì)為(k,Q),Q為公鑰,k為私鑰。Alice將按照如下步驟進(jìn)行簽名:
1) 產(chǎn) 生 一 個(gè) 隨 機(jī) 數(shù)d,1≤d≤n-1;
2)計(jì)算dG=(x1,y1),將x1轉(zhuǎn)化為整數(shù)-x1;
3)計(jì)算r=-x1modn,若r=0,則轉(zhuǎn)向第1步;
4)計(jì)算d-1modn;
5)計(jì)算哈希值H(m),并將得到的比特串轉(zhuǎn)化為整數(shù)e;
6)計(jì) 算s=d-1(e+kr)modn,若s=0,則轉(zhuǎn)向第1步;
7)(r,s)即為Alice對(duì)消息m進(jìn)行的簽名。
(2)驗(yàn)證數(shù)字簽名的過(guò)程
如果Bob收到消息m之后,他需要驗(yàn)證消息m的簽名(r,s),在得到橢圓曲線參數(shù)和Q之后,將按以下步驟操作來(lái)驗(yàn)證數(shù)字簽名[8]:
1)首先驗(yàn)證r和s是區(qū)間[1,n-1]上的整數(shù);
2)計(jì)算H(m)并將其進(jìn)行轉(zhuǎn)化變?yōu)檎麛?shù)e;
3)計(jì)算w=s-1modn;
4) 計(jì) 算u1=ewmodn以 及u2=rwmodn;
5)計(jì)算X=u1G+u2Q;
6)若X=0,則拒絕該簽名的有效性,否則將X的x坐標(biāo)x1轉(zhuǎn)化為整數(shù)并計(jì)算
7)當(dāng)且僅當(dāng)v=r時(shí),簽名驗(yàn)證可以通過(guò)。
利用ECDSA算法,將認(rèn)證信息進(jìn)行數(shù)字簽名,確保了每條認(rèn)證消息都是由正確的用戶發(fā)表的,防止他人假冒,還可以保證數(shù)據(jù)的完整性。在整個(gè)認(rèn)證請(qǐng)求中,將不會(huì)有人對(duì)數(shù)據(jù)包進(jìn)行惡意篡改。
每個(gè)節(jié)點(diǎn)用戶再發(fā)起認(rèn)證請(qǐng)求時(shí),都會(huì)利用自己的私鑰簽名,其他節(jié)點(diǎn)收到認(rèn)證請(qǐng)求,也會(huì)一同參與簽名認(rèn)證的操作。如果認(rèn)證成功,將會(huì)將賬單記錄下來(lái),完成認(rèn)證;否則將拒絕認(rèn)證請(qǐng)求。
1.5.1 Gas——以太坊系統(tǒng)計(jì)算工作量的單位
Gas是以太坊系統(tǒng)中執(zhí)行交易所需要的計(jì)算工作量單位。所有的交易不論是轉(zhuǎn)賬交易,還是執(zhí)行智能合約,都要消耗Gas。Gas的價(jià)格由交易的發(fā)起人和礦工的工作量決定,交易打包進(jìn)區(qū)塊中需要礦工們進(jìn)行哈希運(yùn)算,礦工們付出了勞動(dòng),因此需要收取一定的費(fèi)用。如果交易發(fā)起人設(shè)置的Gas價(jià)格過(guò)低,礦工們基本不會(huì)將交易打包進(jìn)區(qū)塊里;如果交易設(shè)定較高的Gas,該交易將會(huì)得到較高的優(yōu)先級(jí)。
1.5.2 以太坊的工作量證明和挖礦原理
工作量證明(PoW)的目的是阻止網(wǎng)絡(luò)攻擊,如當(dāng)今網(wǎng)絡(luò)環(huán)境下常出現(xiàn)的分布式拒絕服務(wù)攻擊(DDoS),就是用來(lái)發(fā)送許多假的請(qǐng)求以耗盡計(jì)算機(jī)網(wǎng)絡(luò)系統(tǒng)資源,導(dǎo)致服務(wù)器宕機(jī),真正的用戶則無(wú)法登錄到中心服務(wù)器上[9]。
PoW被定義為花費(fèi)計(jì)算機(jī)算力來(lái)進(jìn)行數(shù)據(jù)校對(duì)的要求,俗稱“挖礦”。挖礦的目的有以下幾點(diǎn):
(1)驗(yàn)證交易的合法性,避免出現(xiàn)多重交易的情況;
(2)用來(lái)獎(jiǎng)勵(lì)礦工所做出的計(jì)算工作;
(3)維護(hù)以太坊系統(tǒng)的正常安全運(yùn)轉(zhuǎn)。
通過(guò)挖礦的方式解決PoW的數(shù)學(xué)難題具有不可逆的特征。從技術(shù)角度來(lái)說(shuō),挖礦的過(guò)程就是一個(gè)不斷進(jìn)行的哈希運(yùn)算過(guò)程,它通過(guò)嘗試產(chǎn)生隨機(jī)數(shù),找到滿足條件的隨機(jī)數(shù)后立即將區(qū)塊進(jìn)行打包并全網(wǎng)廣播,找到該隨機(jī)數(shù)的節(jié)點(diǎn)也是贏得本輪記賬權(quán)利的節(jié)點(diǎn)。該區(qū)塊將在整個(gè)區(qū)塊鏈網(wǎng)絡(luò)廣播,進(jìn)行共識(shí)的達(dá)成。如果達(dá)成共識(shí),每個(gè)節(jié)點(diǎn)將會(huì)將該區(qū)塊添加到自己的區(qū)塊鏈中,同時(shí)該礦工將會(huì)得到以太幣獎(jiǎng)勵(lì)。
隨機(jī)數(shù)的條件取決于系統(tǒng)設(shè)定的難度,例如:要求整個(gè)區(qū)塊加上隨機(jī)數(shù)計(jì)算出的哈希值要小于給定的值才算成功;而哈希值的產(chǎn)生沒(méi)有規(guī)律可循,只有算力越高的計(jì)算機(jī)才能更快得到符合條件的隨機(jī)數(shù)。
2.1.1 數(shù)據(jù)區(qū)塊和鏈?zhǔn)浇Y(jié)構(gòu)
首先,區(qū)塊是以太坊網(wǎng)絡(luò)的核心,所有的交易、數(shù)據(jù)存儲(chǔ)都是在區(qū)塊頭中進(jìn)行的。不同的區(qū)塊頭之間通過(guò)頭指針(ParentHash)函數(shù)指向前一個(gè)區(qū)塊的頭指針,將它們串聯(lián)起來(lái),形成單項(xiàng)鏈表。
區(qū)塊結(jié)構(gòu)分為區(qū)塊頭和區(qū)塊的數(shù)據(jù)部分這2個(gè)部分,源碼在以太坊的/core/types/block.go中,數(shù)據(jù)層的函數(shù)關(guān)系圖如圖5所示。
圖5 數(shù)據(jù)層函數(shù)關(guān)系圖
其中,區(qū)塊的結(jié)構(gòu)體定義為:
type Block struct
2.1.2 Merkle樹的使用
在以太坊中使用的是Merkle樹的改進(jìn)樹(MPT),也是二叉樹的一種。節(jié)點(diǎn)的值是它相連2個(gè)葉子節(jié)點(diǎn)值的哈希。Merkle樹用于所有交易正確性的驗(yàn)證,而MPT則大大提高了查找效率。樹的構(gòu)造代碼在以太坊源碼的trie/trie.go中,關(guān)鍵代碼如下。
首先是從根節(jié)點(diǎn)進(jìn)行遍歷:
if(t.db==nil){...}//如果數(shù)據(jù)已經(jīng)存在數(shù)據(jù),返回
return t.CommitTo(t.db)//父節(jié)點(diǎn)沒(méi)有數(shù)據(jù),就調(diào)用下面的函數(shù)寫數(shù)據(jù)
查找、插入、刪除都是在trie/trie.go里進(jìn)行使用的。
2.1.3 數(shù)據(jù)存儲(chǔ)的實(shí)現(xiàn)
以太坊的數(shù)據(jù)存放在StateDB中。StateDB是以太坊的數(shù)據(jù)庫(kù),負(fù)責(zé)本地存儲(chǔ)數(shù)據(jù)及業(yè)務(wù),還負(fù)責(zé)連接到底層的數(shù)據(jù)庫(kù),它使用二級(jí)緩存機(jī)制來(lái)存儲(chǔ)賬戶的相關(guān)數(shù)據(jù)。
StateDB的相關(guān)代碼在core/state/statedb.go中,其定義的結(jié)構(gòu)體以及作用為:DataBase類型的DB用于存放數(shù)據(jù),Tire類型的tire用于存放MPT樹,stateObject表示以太坊賬戶,其中在stateObject中也有二級(jí)緩存機(jī)制,主要用來(lái)緩存和更新以太坊帳戶。
整個(gè)以太坊網(wǎng)絡(luò)的運(yùn)作結(jié)構(gòu)如圖6所示。
圖6 以太坊網(wǎng)絡(luò)的運(yùn)作結(jié)構(gòu)
2.2.1 網(wǎng)絡(luò)層傳輸協(xié)議
當(dāng)一個(gè)節(jié)點(diǎn)有新的數(shù)據(jù)區(qū)塊產(chǎn)生,該節(jié)點(diǎn)將會(huì)進(jìn)行全網(wǎng)廣播,其他收到請(qǐng)求的節(jié)點(diǎn)將會(huì)進(jìn)行驗(yàn)證。一個(gè)節(jié)點(diǎn)創(chuàng)建一個(gè)新的區(qū)塊,該新區(qū)塊很快會(huì)被發(fā)到網(wǎng)絡(luò)上所有的節(jié)點(diǎn),然后每個(gè)節(jié)點(diǎn)都要驗(yàn)證這個(gè)新的區(qū)塊,驗(yàn)證其真實(shí)性。經(jīng)驗(yàn)證后,每個(gè)節(jié)點(diǎn)才會(huì)添加這個(gè)新的區(qū)塊到區(qū)塊鏈,區(qū)塊鏈網(wǎng)絡(luò)中的所有節(jié)點(diǎn)達(dá)成共識(shí),一起決定哪個(gè)區(qū)塊有效而哪個(gè)無(wú)效,擅自篡改的區(qū)塊會(huì)被網(wǎng)絡(luò)上其他節(jié)點(diǎn)拒絕[10]。
在節(jié)點(diǎn)之間傳播數(shù)據(jù)時(shí),采用加密網(wǎng)絡(luò)和傳輸協(xié)議(RLPx)加密握手協(xié)議。該協(xié)議在網(wǎng)絡(luò)層的上層,在以太坊網(wǎng)絡(luò)中新的節(jié)點(diǎn)建立后,首先進(jìn)行端口監(jiān)測(cè)偵聽、節(jié)點(diǎn)間連接及通信交互,當(dāng)節(jié)點(diǎn)間都建立了連接,將會(huì)通過(guò)Msg的格式進(jìn)行通信。每次在通信的過(guò)程中,都會(huì)做出如圖7所示的判斷,以確保握手協(xié)議運(yùn)作正常,如果運(yùn)作不正常,將會(huì)失去對(duì)該節(jié)點(diǎn)的連接。
RLPx加密握手協(xié)議的具體流程如圖8所示。
2.2.2 數(shù)據(jù)驗(yàn)證機(jī)制
P2P網(wǎng)絡(luò)中的每個(gè)節(jié)點(diǎn),只要在線,都在隨時(shí)監(jiān)測(cè)偵聽其他節(jié)點(diǎn)的認(rèn)證請(qǐng)求,驗(yàn)證區(qū)塊數(shù)據(jù)的具體一些步驟如下:
(1)負(fù)責(zé)識(shí)別網(wǎng)絡(luò)中廣播的數(shù)據(jù)和區(qū)塊;
(2)如果接收到相鄰節(jié)點(diǎn)發(fā)來(lái)的認(rèn)證,將會(huì)對(duì)認(rèn)證請(qǐng)求進(jìn)行分析,將檢查數(shù)據(jù)的完整性、語(yǔ)法的規(guī)范性、數(shù)字簽名是否正確等方面來(lái)校驗(yàn)交易數(shù)據(jù)是否有效;
圖7 RLPx加密握手協(xié)議的建立
圖8 RLPx加密握手協(xié)議的流程
(3)如果數(shù)據(jù)有效,將會(huì)把數(shù)據(jù)放入存儲(chǔ)池中,即將認(rèn)證請(qǐng)求記錄到本地,同時(shí)向相鄰節(jié)點(diǎn)轉(zhuǎn)發(fā)數(shù)據(jù);
(4)如果數(shù)據(jù)無(wú)效,將會(huì)立即放棄該數(shù)據(jù),確保數(shù)據(jù)不會(huì)在區(qū)塊鏈網(wǎng)絡(luò)中傳播。
2.2.3 P2P網(wǎng)絡(luò)的具體實(shí)現(xiàn)
以太坊的P2P網(wǎng)絡(luò)主要使用以下幾個(gè)工具實(shí)現(xiàn)。
(1)Discover:使用了 Kademlia協(xié)議,用于使用UDP的P2P節(jié)點(diǎn)發(fā)現(xiàn)的協(xié)議;
(2)discv5:用于發(fā)現(xiàn)新節(jié)點(diǎn);
(3)nat:網(wǎng)絡(luò)地址轉(zhuǎn)換工具;
(4)netutil:有關(guān)網(wǎng)絡(luò)連接的工具;
(5)simulations:P2P網(wǎng)絡(luò)測(cè)試工具。
P2P網(wǎng)絡(luò)非常復(fù)雜,如果要使用它,就必須要包含節(jié)點(diǎn)查找、節(jié)點(diǎn)維護(hù)、節(jié)點(diǎn)建立連接的功能。在database.go文件中,newNodeDB函數(shù)用來(lái)存儲(chǔ)節(jié)點(diǎn)數(shù)據(jù),存儲(chǔ)節(jié)點(diǎn)數(shù)據(jù)采用了Keccak-256的簽名哈希算法。以下是一些關(guān)鍵函數(shù)。
(1)查找節(jié)點(diǎn)的函數(shù):func(db*nodeDB)node(id NodeID)*Node;
(2)插入數(shù)據(jù)的函數(shù):func(db*nodeDB)updateNode(node*Node);
(3)刪除數(shù)據(jù)的函數(shù):func(db*nodeDB)deleteNode(id NodeID)。
連接超時(shí)的處理辦法,即如果發(fā)現(xiàn)有個(gè)節(jié)點(diǎn)接收消息的時(shí)間超出了設(shè)定的值,那么就刪除節(jié)點(diǎn)不再連接,關(guān)鍵代碼如下:
2.3.1 PoW的機(jī)制
PoW通過(guò)計(jì)算機(jī)進(jìn)行數(shù)學(xué)運(yùn)算得到記賬權(quán),但是每次要達(dá)成全網(wǎng)共識(shí),都需要全網(wǎng)一起參與運(yùn)算。本設(shè)計(jì)系統(tǒng)作了以下規(guī)定,使認(rèn)證步驟準(zhǔn)確進(jìn)行:
(1)所有連接到以太坊網(wǎng)絡(luò)的地址都應(yīng)該分為已被認(rèn)證的和未被認(rèn)證的;
(2)已認(rèn)證的節(jié)點(diǎn)可以變成沒(méi)有經(jīng)過(guò)認(rèn)證的,沒(méi)有經(jīng)過(guò)認(rèn)證的節(jié)點(diǎn)也可以變成已認(rèn)證的;
(3)一條認(rèn)證請(qǐng)求包括認(rèn)證的地址、認(rèn)證的狀態(tài)等;
(4)認(rèn)證成功之后不能再進(jìn)行第2次認(rèn)證。
2.3.2 共識(shí)記賬的設(shè)計(jì)方案
本設(shè)計(jì)方案的認(rèn)證流程如下:
(1)請(qǐng)求的生成。以太坊的客戶端持續(xù)監(jiān)測(cè)偵聽,如果網(wǎng)站調(diào)用了認(rèn)證請(qǐng)求,那么客戶端將會(huì)向全網(wǎng)進(jìn)行廣播。Alice使用她的私鑰對(duì)認(rèn)證請(qǐng)求進(jìn)行簽名,并在認(rèn)證請(qǐng)求的末尾處添加簽名,以便能夠讓其他節(jié)點(diǎn)來(lái)進(jìn)行校驗(yàn)。
(2)請(qǐng)求的廣播。Alice將認(rèn)證的請(qǐng)求向全網(wǎng)節(jié)點(diǎn)廣播,其他的節(jié)點(diǎn)將會(huì)收到并將共同參與數(shù)字簽名的校驗(yàn)。若正確,則將其納入到礦工自己的區(qū)塊中;若不正確,則丟棄。
(3)區(qū)塊的生成。每當(dāng)間隔一段時(shí)間,所有的節(jié)點(diǎn)通過(guò)挖礦進(jìn)行PoW,通過(guò)解決數(shù)學(xué)難題來(lái)贏得記賬的權(quán)利,此過(guò)程也是所有節(jié)點(diǎn)進(jìn)行區(qū)塊同步校對(duì)的過(guò)程。
(4)區(qū)塊的廣播。如果有節(jié)點(diǎn)通過(guò)算力找到了符合條件的隨機(jī)數(shù),將會(huì)向全網(wǎng)廣播,該節(jié)點(diǎn)將是下個(gè)區(qū)塊的創(chuàng)建者,并會(huì)獲得獎(jiǎng)勵(lì);
(5)區(qū)塊寫入賬本。將對(duì)所有節(jié)點(diǎn)成功解出數(shù)學(xué)難題的廣播答案進(jìn)行驗(yàn)證,如果正確,它會(huì)將該區(qū)塊納入自己的賬本中,每個(gè)節(jié)點(diǎn)同步進(jìn)行;否則,將丟棄該區(qū)塊。
2.3.3 共識(shí)記賬的實(shí)現(xiàn)
共識(shí)層的代碼在consensus/路徑中,本節(jié)具體介紹共識(shí)記賬的實(shí)現(xiàn)。
prepare函數(shù)主要用來(lái)處理區(qū)塊頭部信息,其定義如下:
diff=(parent_diff+(parent_diff/2048 * max(1- (block_timestampparent_timestamp)/10,-99)))+ 2^(periodCount-2)
其中parent_diff表示上一區(qū)塊的難度;block_timestamp表示當(dāng)前區(qū)塊的時(shí)間戳;parent_timestamp表示上一區(qū)塊的時(shí)間戳;periodCount表示區(qū)塊數(shù)量。
結(jié)合官方的文檔,在測(cè)試階段,調(diào)節(jié)區(qū)塊難度的值為一個(gè)較低的值,讓登錄認(rèn)證的交易盡快被礦工打包,避免用戶長(zhǎng)時(shí)間等待,同時(shí)方便調(diào)試和使用。難度設(shè)定需基于創(chuàng)世區(qū)塊(創(chuàng)世區(qū)塊是指區(qū)塊鏈的第1個(gè)區(qū)塊,它是構(gòu)建整個(gè)區(qū)塊鏈系統(tǒng)的基礎(chǔ))。
seal函數(shù)用于處理挖礦的工作,需要一直遞歸調(diào)用,直到解決問(wèn)題,解決問(wèn)題之后退出。seal函數(shù)具有以下幾點(diǎn)作用:
(1)根據(jù)區(qū)塊頭部的信息中的挖礦難度系數(shù)來(lái)處理計(jì)算目標(biāo)值。
(2)選取隨機(jī)數(shù)和區(qū)塊頭的哈希值,進(jìn)行哈希運(yùn)算。如果結(jié)果小于目標(biāo)值,那么表示挖礦成功,自動(dòng)退出;否則,則繼續(xù)循環(huán)進(jìn)行哈希運(yùn)算。
(3)如果從外部收到了這個(gè)塊,表示其他人已經(jīng)挖礦成功并且已經(jīng)得到了塊,那么就會(huì)馬上放棄打包當(dāng)前塊。
(4)Finalize函數(shù)表示挖礦成功之后獎(jiǎng)勵(lì)的事,它可以計(jì)算礦工的獎(jiǎng)勵(lì),使礦工得到獎(jiǎng)勵(lì)。
verifyHeader函數(shù)主要用來(lái)校驗(yàn)區(qū)塊的時(shí)間戳、校驗(yàn)難度值、校驗(yàn)區(qū)塊的gas。
VerifySeal函數(shù)主要用來(lái)驗(yàn)證區(qū)塊頭部的簽名信息。
本設(shè)計(jì)系統(tǒng)使用的是以太坊的go-ethereum客戶端來(lái)連接到自己搭建的以太坊私有網(wǎng)絡(luò),它提供的應(yīng)用程序編程接口(API)可以給本設(shè)計(jì)系統(tǒng)進(jìn)行調(diào)用,并用來(lái)創(chuàng)建新地址,驗(yàn)證數(shù)字簽名、支付和轉(zhuǎn)賬、查看余額等。接口層包含了以太坊智能合約腳本、分布式計(jì)算、驗(yàn)證加密簽名和數(shù)據(jù)存儲(chǔ)的技術(shù)。所有的請(qǐng)求數(shù)據(jù)通過(guò)post傳遞,使用json參數(shù)傳遞。
解析一個(gè)請(qǐng)求的具體的實(shí)現(xiàn)步驟如下:
(1)首先要對(duì)json數(shù)據(jù)進(jìn)行實(shí)例化,使用NewJSONCodec編碼器;
(2)通過(guò)NewJSONCodec編碼器將請(qǐng)求轉(zhuǎn)換為jsonRequest,并且獲取參數(shù)有關(guān)服務(wù)名(service_name)、服務(wù)方法(service_method)和 數(shù) 據(jù) 片 段(params);
(3)通過(guò)服務(wù)名(service_name)和服務(wù)方法(service_method),查找已經(jīng)注冊(cè)的rpc服務(wù);
(4)向rpc服務(wù)進(jìn)行請(qǐng)求,之后的操作都在rpc服務(wù)中進(jìn)行;
(5)rpc返回結(jié)果,接著對(duì)json序列化,返回結(jié)果值。
例如:本設(shè)計(jì)系統(tǒng)使用Ethereum客戶端賬,在向rpc服務(wù)發(fā)送請(qǐng)求時(shí),設(shè)定service_name為指定以太坊的服務(wù)名,并設(shè)定service_method為sendRawTransaction,通過(guò)調(diào)用 rpc服務(wù),返回的結(jié)果是TxnHash字符串的json數(shù)據(jù)。
本設(shè)計(jì)方案最大的創(chuàng)新之處在于身份識(shí)別系統(tǒng)基于以太坊智能合約技術(shù),立足于傳統(tǒng)互聯(lián)網(wǎng)行業(yè)的現(xiàn)狀,解決了中心化管理的麻煩,以及用戶信息容易被篡改、被黑客盜用,中心服務(wù)器被攻擊等事關(guān)國(guó)家信息安全痛點(diǎn)的問(wèn)題。
在本設(shè)計(jì)中,認(rèn)證請(qǐng)求者向系統(tǒng)提出認(rèn)證請(qǐng)求,服務(wù)器節(jié)點(diǎn)在收到請(qǐng)求后,采用認(rèn)證方案對(duì)識(shí)別認(rèn)證者的請(qǐng)求,同時(shí)將認(rèn)證信息加入到認(rèn)證區(qū)塊鏈中。這個(gè)過(guò)程解決了分布式賬本的一致性和安全性問(wèn)題,不需要第三方中介的引入。
該系統(tǒng)具有以下創(chuàng)新特點(diǎn):
(1)去中心化,防止偽造。根據(jù)當(dāng)今互聯(lián)網(wǎng)產(chǎn)業(yè)的需求,本系統(tǒng)使用P2P技術(shù),改善了數(shù)據(jù)的存儲(chǔ)。所有的數(shù)據(jù)通過(guò)分布式存儲(chǔ)保存在各個(gè)節(jié)點(diǎn),每個(gè)用戶都是一個(gè)節(jié)點(diǎn),通過(guò)節(jié)點(diǎn)的共識(shí),完成身份識(shí)別,不依賴第三方。
(2)數(shù)據(jù)校驗(yàn),真實(shí)可信。結(jié)合以太坊改進(jìn)之后的MPT樹,以及通過(guò)RLPx加密握手協(xié)議,并充分利用ECDSA的非對(duì)稱加密的優(yōu)勢(shì),避免了黑客通過(guò)網(wǎng)絡(luò)傳輸作弊的行為。整個(gè)認(rèn)證過(guò)程由節(jié)點(diǎn)們共同完成,使數(shù)據(jù)真實(shí)可信。
(3)安全性高,黑客止步。基于區(qū)塊鏈的去中心化特點(diǎn),每個(gè)節(jié)點(diǎn)的地位都是對(duì)等的,即使某個(gè)或者部分節(jié)點(diǎn)被摧毀都不會(huì)影響整個(gè)系統(tǒng)的安全,也不會(huì)造成數(shù)據(jù)的丟失。黑客如果想篡改數(shù)據(jù),需要攻擊、修改一半以上的節(jié)點(diǎn)數(shù)據(jù),這幾乎是無(wú)法實(shí)現(xiàn)的。
(4)調(diào)用方便,拓展性高。本系統(tǒng)設(shè)計(jì)的接口層,通過(guò)json傳遞參數(shù)到以太坊客戶端,基于接口層方便調(diào)用的特點(diǎn),可快速搭建更多不同開發(fā)語(yǔ)言的網(wǎng)站和程序,同時(shí)客戶端支持多個(gè)網(wǎng)站和程序,并調(diào)用獲取賬號(hào)的信息,實(shí)現(xiàn)了賬號(hào)的統(tǒng)一身份認(rèn)證。
(5)部署簡(jiǎn)單,用途廣泛。本設(shè)計(jì)方案可以部署在企業(yè)、政府機(jī)構(gòu)、教育結(jié)構(gòu)等,例如:在企業(yè)中,多個(gè)部門可以使用同一套以太坊網(wǎng)絡(luò),無(wú)需在每個(gè)部門都進(jìn)行部署,支持跨多個(gè)部門,適合部署在大型企業(yè)中。
本設(shè)計(jì)仍然有很多的可拓展之處,除了身份認(rèn)證,還可以通過(guò)以太坊智能合約開發(fā)更多功能,例如:房屋出租、契約、貸款平臺(tái)等,能給使用者帶來(lái)顯著的安全效益、經(jīng)濟(jì)效益、管理效益、科研效益。