前提知識儲備
- 為什么要有SPV(Simplified Payment Verification)?
完整的比特幣數(shù)據(jù)庫(也就是區(qū)塊鏈)需要超過 140 Gb 的磁盤空間。因為比特幣的去中心化特性,網(wǎng)絡(luò)中的每個節(jié)點必須是獨立,自給自足的,也就是每個節(jié)點必須存儲一個區(qū)塊鏈的完整副本。隨著越來越多的人使用比特幣,這條規(guī)則變得越來越難以遵守:因為不太可能每個人都去運行一個全節(jié)點。并且,由于節(jié)點是網(wǎng)絡(luò)中的完全參與者,它們負(fù)有相關(guān)責(zé)任:節(jié)點必須驗證交易和區(qū)塊。另外,要想與其他節(jié)點交互和下載新塊,也有一定的網(wǎng)絡(luò)流量需求。
SPV 是一個比特幣輕節(jié)點,它不需要下載整個區(qū)塊鏈,也不需要驗證區(qū)塊和交易。相反,它會在區(qū)塊鏈查找交易(為了驗證支付),并且需要連接到一個全節(jié)點來檢索必要的數(shù)據(jù)。這個機制允許在僅運行一個全節(jié)點的情況下有多個輕錢包。
Full Peer會儲存完整的Block:Block Size + Block Header + Transaction Counter + Transactions,其中占用存儲空間最大的就是Transactions,而Block Header里面包含了這個Block.Merkle Root Path,這個Hash值在計算整個Block的Hash時候會被用到。
SPV (Simplified Payment Verification) Client只存精簡的Block:Block Size + Block Header。根本沒有真實的交易詳細(xì)信息,所以體積小。
SPV交易之間要解決的問題
A用戶向商戶B 發(fā)起了一筆比特幣轉(zhuǎn)賬,并且告知B ,這筆交易的Txid和SPV上面的Block 信息,于是B根據(jù)Txid和Block信息,同時向多個FullPeer去confirm這筆交易是否真的存在。Merkle Tree就是要解決這個問題!
Merkle Tree的一些相關(guān)事情
- Merkle Tree生成原理不解釋 了,參考其它的博客吧,我只寫你搜不到的內(nèi)容。
- Merkle Tree的第一大功能是:在生成區(qū)塊的時候,對所有的交易按照樹形結(jié)構(gòu)生成了一個摘要信息(Root Node.path),這就是壓縮值,這讓SPV的實現(xiàn)奠定了基礎(chǔ)。
Merkle Tree在交易確認(rèn)時候的作用

SPV向一個Full Peer發(fā)送 Block信息和 TXID,查詢這筆Txid是否存在在這個Txid里面(假設(shè)是HK交易),F(xiàn)ullPeer根據(jù)Block.Hash值,先找到這個Block,然后遍歷Block的Transactions數(shù)組,可以理解為遍歷Transaction.Txid是否一樣,如果沒有,就直接返回SPV交易不存在,如果有的話,那么就要根據(jù)下圖的信息,傳輸HL、HIJ、HMNOP 和 HABCDEFGH的值
所以SPV收到Peer的一串值的時候,就可以根據(jù)這些值,計算出在這個Block的MerkleRootNode.data了(也叫RootPath),如果和自己的SPV里面的RootPath一樣,那么說明這筆交易在區(qū)塊鏈中真實存在
精華
為什么計算RootPath要用Merkle Tree,而不用List呢?
我們在計算Block Hash的時候,可以把所有的Transactions的Txid,拼接起來,對拼接值進行 Sum256,得出一個 RootPath,因為這種方式的數(shù)學(xué)上的運算量是最小的,而Merkle Tree需要重重計算Hash值。為什么FullPeer在Check到這筆交易存在在Block中是,要返回HL、HIJ、HMNOP 和 HABCDEFGH的值,而不是直接返回RootPath呢?要知道RootPath本身就存在了的消息頭里面的,都不需要進行運算的,而且一個RootPath傳輸?shù)捏w積更小。
為什么SPV要向多個節(jié)點同時發(fā)起交易是否存在的confirm請求?
Merkle Tree的優(yōu)勢在于:在傳輸空間和數(shù)據(jù)不可篡改上都做到很好
為什么不支持返回RootPath,因為只返回一個RootPath是沒有辦法讓SPV相信這個結(jié)果是真實的,因為比特幣的系統(tǒng)中,要FullPeer是可能造假的。可能Txid不存在,但是Peer卻告訴SPV存在,SPV無法驗證這個結(jié)果是否可靠。但是通過傳輸HL、HIJ、HMNOP 和 HABCDEFGH的值卻可以驗證,這個交易是真實存在的,因為RootPath的計算是不可逆的,可以通過結(jié)合這些相鄰節(jié)點的Hash值,計算出RootPath,這個計算值如果和SPV里面的值是一樣的,就可以證明這個交易真實存在,且不是Peer造假的,因為哈希加密是不可逆的,Peer是無法偽造一些假的 HL、HIJ、HMNOP 和 HABCDEFGH的值來讓這些值和 當(dāng)前Txid求出RootPath的。
為什么不用數(shù)組,因為樹形結(jié)構(gòu)的話,只要返回4個Hash值(HL、HIJ、HMNOP 和 HABCDEFGH)就可以確認(rèn)該筆交易是否可靠,但是如果是數(shù)組的話,則需要把整個數(shù)組的全部Hash值都傳給SPV,否則就沒有辦法計算RootPath。
SPV要向多個節(jié)點發(fā)起confirm請求,是為了降低造假的可能性。比如同時向10個Full Peer去查詢這筆交易,9個Peer都說不存在,而1個Peer返回存在,那么該交易一定存在,且9個Peer的數(shù)據(jù)是造假的,因為Peer是無法偽造HL、HIJ、HMNOP 和 HABCDEFGH的值。
參考資料
http://www.itdecent.cn/p/bfda51cd340d
http://www.itdecent.cn/p/1abffeac87fc