相關(guān)閱讀
純干貨|深度解析以太坊(1):以太坊模型
以太坊的全球“共享狀態(tài)”是由許多能夠通過消息傳遞框架相互作用的小型對象(賬戶)組成的。每個帳戶都有一個相關(guān)的狀態(tài)和一個20字節(jié)的地址。以太坊的地址是一個160位的標(biāo)識符,用于識別任何帳戶。
有兩種類型的帳戶:
1.外部擁有的帳戶,由私鑰控制,并且沒有與之相關(guān)的代碼。
2.合約帳戶,由合約代碼控制,并有與之相關(guān)的代碼。
1?外部擁有賬戶與合約賬戶
了解外部賬戶和合約賬戶之間的根本區(qū)別很重要。外部擁有的帳戶可以通過使用其私鑰創(chuàng)建和簽署交易,將消息發(fā)送到其他外部擁有的帳戶或其他合約帳戶。兩個外部擁有賬戶之間的消息只是一個價值轉(zhuǎn)移。但是從外部擁有賬戶到合約賬戶的消息會激活合約賬戶的代碼,允許它執(zhí)行各種操作(例如轉(zhuǎn)移Token,寫入內(nèi)部存儲,創(chuàng)建新的Token,執(zhí)行一些計(jì)算,創(chuàng)建新的合約等)。
與外部擁有的賬戶不同,合約賬戶不能自行發(fā)起新的交易。相反,合約帳戶只能觸發(fā)交易以響應(yīng)其他交易(從外部擁有的帳戶或其他合約帳戶)。我們將在“ 交易和消息 ”部分中詳細(xì)了解合約到合約的通信。
因此,以太坊區(qū)塊鏈上發(fā)生的任何操作都始終由外部受控帳戶觸發(fā)的交易處理。
2?賬戶狀態(tài)
不管賬戶的類型如何,賬戶狀態(tài)由四個部分組成:
nonce:如果賬戶是一個外部擁有賬戶,nonce代表從此賬戶地址發(fā)送的交易序號。如果賬戶是一個合約賬戶,nonce代表此賬戶創(chuàng)建的合約序號
balance: 此地址擁有Wei的數(shù)量。1Ether=10^18Wei
storageRoot: Merkle Patricia樹的根節(jié)點(diǎn)Hash值(我們后面在解釋Merkle tree)。Merkle tree會將此賬戶存儲內(nèi)容的Hash值進(jìn)行編碼,默認(rèn)是空值
codeHash:此賬戶EVM(以太坊虛擬機(jī),后面細(xì)說)代碼的hash值。對于合約賬戶,就是被Hash的代碼并作為codeHash保存。對于外部擁有賬戶,codeHash域是一個空字符串的Hash值
3?全局狀態(tài)
我們知道以太坊的全局狀態(tài)由帳戶地址和帳戶狀態(tài)之間的映射組成。這個映射存儲在一個稱為Merkle Patricia樹的數(shù)據(jù)結(jié)構(gòu)中。
Merkle Tree(或者也被稱為“Merkle trie”)是由一組節(jié)點(diǎn)組成一種二叉樹,這些節(jié)點(diǎn)包括:
包含底層數(shù)據(jù)的樹底部的大量葉子節(jié)點(diǎn);
一組中間節(jié)點(diǎn),其中每個節(jié)點(diǎn)是其兩個子節(jié)點(diǎn)的散列;
單個根節(jié)點(diǎn),也是由其兩個子節(jié)點(diǎn)的Hash形成的,代表樹的頂部;
樹底部的數(shù)據(jù)是通過將我們想要存儲的數(shù)據(jù)分成chunks塊來生成的,然后將chunks分成buckets,然后取每個buckets的hash值并重復(fù)相同的過程,直到剩余的hash總數(shù)變?yōu)橹挥幸粋€:根hash。
樹需要有一個存儲在里面的每個值的鍵(key)。從樹的根節(jié)點(diǎn)開始,關(guān)鍵字應(yīng)該告訴你哪個子節(jié)點(diǎn)要獲取相應(yīng)的值,該值存儲在葉節(jié)點(diǎn)中。在以太坊的情況下,狀態(tài)樹的鍵/值映射位于地址及其相關(guān)帳戶之間,包括每個帳戶的balance,nonce,codeHash和storageRoot(其中storageRoot本身就是樹)。
同樣的樹結(jié)構(gòu)也用來存儲交易和收據(jù)。更具體的說,每個塊都有一個頭(header),保存了三個不同Merkle trie結(jié)構(gòu)的根節(jié)點(diǎn)的Hash,包括:
狀態(tài)樹
交易樹
收據(jù)樹
在Merkle tries中有效地存儲所有信息的能力在以太坊我們稱之為“輕客戶端”或“輕節(jié)點(diǎn)”。請記住,區(qū)塊鏈由一堆節(jié)點(diǎn)維護(hù)。一般來說,有兩種類型的節(jié)點(diǎn):全節(jié)點(diǎn)和輕節(jié)點(diǎn)。
全節(jié)點(diǎn)通過下載整條鏈來進(jìn)行同步,從創(chuàng)世紀(jì)塊到當(dāng)前塊,執(zhí)行包含在其中的所有交易。通常情況下,礦工存儲全節(jié)點(diǎn),因?yàn)樗麄冊谕诘V過程中需要全節(jié)點(diǎn)。也可以在不執(zhí)行每個交易的情況下下載全節(jié)點(diǎn)。無論如何,一個全節(jié)點(diǎn)都包含整個鏈。
但是,除非一個節(jié)點(diǎn)需要執(zhí)行每個交易或者輕松查詢歷史數(shù)據(jù),否則實(shí)際上不需要存儲整個鏈。這是輕節(jié)點(diǎn)概念的來源。輕型節(jié)點(diǎn)不是下載并存儲完整鏈并執(zhí)行所有交易,而是僅從起始塊到當(dāng)前塊的頭,而不執(zhí)行任何交易或檢索任何關(guān)聯(lián)的狀態(tài)。由于輕節(jié)點(diǎn)可以訪問塊的頭,而頭中包含了3個tries的Hash,所有輕節(jié)點(diǎn)依然可以很容易生成和接收關(guān)于交易、事件、余額等可驗(yàn)證的答案。
這樣做的原因是因?yàn)镸erkle tree中的hash向上傳播 - 如果惡意用戶試圖將假交易交換到Merkle tree的底部,這種更改將導(dǎo)致上面節(jié)點(diǎn)的散列發(fā)生變化,這將改變以上的節(jié)點(diǎn)的散列,等等,直到它最終改變樹的根。
任何想要驗(yàn)證數(shù)據(jù)的節(jié)點(diǎn)都可以使用“Merkle證明”來實(shí)現(xiàn)。Merkle證明包括:
1.要驗(yàn)證的數(shù)據(jù)塊和散列
2.樹的根hash
3.一個“分支”(從 chunk到根這個路徑上所有的hash值)
任何讀取證明的人都可以驗(yàn)證該分支的hash在樹中一直保持一致,因此給定的塊實(shí)際上是在樹中的那個位置。
總之,使用Merkle Patricia樹的好處是,這個結(jié)構(gòu)的根節(jié)點(diǎn)在密碼上依賴于存儲在樹中的數(shù)據(jù),所以根節(jié)點(diǎn)的散列可以用作這個數(shù)據(jù)的安全身份。由于塊頭包含狀態(tài),交易和收據(jù)樹的根hash,所以任何節(jié)點(diǎn)都可以驗(yàn)證以太坊狀態(tài)的一小部分,而不需要存儲整個狀態(tài),這個狀態(tài)的大小可能是無限的。
布尼區(qū)塊鏈
擁抱區(qū)塊鏈未來
打造最有價值的區(qū)塊鏈學(xué)習(xí)&交流社群