區塊鏈系列 - 以太坊工作原理 (上)
各位可能或多或少都已經聽過比特幣、區塊鏈、以太坊、NFT、雪崩協議、DEFI等許多五花八門的名詞,但你真的理解這一切是如何運作的嗎?我認為這一切應用都是基於最重要的 "以太坊",本文將盡力的跟大家聊聊以太坊是如何工作以及它的原理是什麼?
以太坊本質上是一個公開的資料庫,上面有許多的交易紀錄,這些紀錄被永久的保存在網路上;不需要任何中央機關 (政府、銀行) 認可,由所有的網路節點 (電腦) 共同維護;以太坊提供了一個框架以供網路中的任何"點對點交易",同樣不需要透過任何中央機關。
我相信大家看了以上的定義仍然會感到非常困惑,本文接下來將會盡其所能的解釋一切。我的目標是以技術的角度解釋以太坊原理,盡量避開複雜的數學原理和公式。即使你不是軟體工程師,也能看懂。如果某些部分技術性太強且難以理解,那完全沒關係!真的沒有必要了解每一個小細節。我建議只專注於在廣泛的層面上理解即可。讓我們開始這趟旅程吧!!!^^
區塊鏈定義
"Cryptographically secure transactional singleton machine with shared-state",讓我們分解一下:
- "Cryptographically secure" 意味著數字貨幣的創建是由複雜的數學算法保護,這些演算法非常難以破解。 想想各種防火牆。它們幾乎不可能欺騙系統(例如,創建虛假交易、刪除交易等)
- "Transactional singleton machine" 意味著有一個機器的規範實例負責系統中創建的所有事務。 換句話說,每個人都相信一個單一的全域事實。
- "With shared-state" 意味著存儲在這台機器上的狀態是共享的,對所有人開放。
以太坊區塊鏈範例說明
以太坊區塊鏈本質上是一個基於交易的狀態機。 在計算機科學中,狀態機是指將讀取一系列輸入並根據這些輸入轉換到新狀態的東西。
以太坊從 "創世狀態" 開始。當任何交易被執行時,創世狀態就會轉換到某個最終狀態。 在任何時間點,這個最終狀態都代表了以太坊的當前狀態。
以太坊的狀態有數百萬筆交易。 這些交易被分組為 "區塊"。 一個區塊包含一系列交易,每個區塊都與其前一個區塊鏈接在一起。
要從一種狀態轉換到下一種狀態,交易必須是有效的。 為了使交易被認為是有效的,它必須經過一個稱為挖礦的驗證過程。 挖礦是指一組節點(電腦)消耗它們的計算資源來創建一個有效交易塊。
網絡上任何自稱為礦工的節點都可以嘗試創建和驗證區塊。 來自世界各地的許多礦工試圖同時創建和驗證區塊。 每個礦工在向區塊鏈提交區塊時都會提供一個數學 "證明",這個證明起到了保證的作用:如果證明存在,則該區塊就是有效的。
對於要添加到主區塊鏈的區塊,礦工必須比任何其他競爭礦工更快地證明它。 通過讓礦工提供數學證明來驗證每個區塊的過程被稱為 "POW 工作證明"。
驗證新區塊的礦工因完成這項工作而獲得一定的價值獎勵。 那價值是什麼? 以太坊區塊鏈使用一種稱為“以太”的數字貨幣。 每次礦工證明一個區塊時,都會生成並獎勵新的以太幣。
你可能想知道:什麼保證每個人都"共識"在一個 "唯一"的區塊鏈認可全局狀態? 我們如何確定不存在另外一組礦工創建屬於他們 "自己"的區塊鏈?
剛剛,我們將區塊鏈定義為具有共享狀態的事務單例機器。 使用這個定義,我們可以理解正確的當前狀態是一個單一的全局狀態,每個人都必須接受。擁有多個狀態(或鏈)會破壞整個系統,因為不確定到底哪個狀態是正確的。 如果區塊鏈分叉,你可能在一個鏈上擁有 10 個幣,在另一個鏈上擁有 20 個幣,在另一個鏈上擁有 40 個幣。 在這種情況下,你將無法確定哪個鍊是最“有效的”。
為了確定哪條路徑最有效並防止出現多條鏈,以太坊使用了一種稱為 "GHOST protocol" 的機制。
"GHOST" = "Greedy Heaviest Observed Subtree"
簡單來說,GHOST 協議說我們必須選擇在其上完成最多計算的路徑。 確定該路徑的一種方法是使用最近塊的塊號,它表示當前路徑中的塊總數。 塊數越高,路徑越長,到達葉子節點的挖礦工作量就越大。 使用這種推理,我們可以就當前狀態的規範版本達成一致。
以太坊系統組成包括:
- accounts
- state
- gas and fees
- transactions
- blocks
- transaction execution
- mining
- proof of work
Account
以太坊的全球“共享狀態”由許多能夠通過消息傳遞框架相互交互的 "賬戶"組成。 每個帳戶都有一個與之關聯的狀態和一個 20 bytes 的地址,用於識別任何帳戶。
有兩種類型的帳戶:
外部帳戶:由私鑰控制並且沒有與之關聯的程式碼。
合約賬戶:由其合約程式碼控制,並具有與之關聯的代碼。
外部賬戶 vs 合約賬戶
外部賬戶可以使用私鑰來創建和簽署交易向其他外賬戶或合約賬戶發送消息。兩個外部賬戶之間的消息只是價值轉移。 但是從外部擁有的賬戶到合約賬戶的消息會激活合約賬戶的代碼,允許其執行各種操作(例如轉移代幣、寫入內部存儲、鑄造新代幣、執行一些計算、創建新合約等)。與外部賬戶不同,合約賬戶不能自行發起新交易。 相反,合約賬戶的交易只有在收到其他交易外會產生。 我們將在"交易和消息" 部分了解有關合約到合約調用的更多資訊。
因此,在以太坊區塊鏈上發生的任何交易總是由外部賬戶發起的。
帳戶狀態
帳戶狀態由四個組件組成,無論哪種帳戶類型(外部和合約)都存在:
nonce:如果賬戶是外部擁有的賬戶,這個數字代表從賬戶地址發送的交易數量。 如果賬戶是合約賬戶,nonce 就是該賬戶創建的合約數量。
balance:該地址擁有的wei數。 每個以太幣有 1e+18 Wei。
storageRoot:Merkle Patricia 樹的根節點的哈希值(我們稍後會解釋 Merkle 樹)。 該樹對該賬戶的存儲內容進行哈希編碼,默認為空。
codeHash:該賬戶的 EVM(以太坊虛擬機 — 稍後詳述)代碼的哈希值。 對於合約賬戶,這是經過哈希處理並存儲為 codeHash 的代碼。 對於外部賬戶,codeHash 字段是空字符串的哈希值。
全局狀態
好的,所以我們知道以太坊的全局狀態由帳戶地址和帳戶狀態之間的映射組成。 此映射存儲在稱為 Merkle Patricia 樹的數據結構中。 Merkle 樹(或也稱為“Merkle trie”)是一種由一組節點組成的二叉樹,其中:
- 包含底層數據的底部大量葉節點
- 一組中間節點,其中每個節點是其兩個子節點的哈希
- 單個根節點,也由其兩個子節點的哈希形成,表示樹的頂部
- 我們將原始數據切分成桶,再切分成塊。
- 從底部取哈希一路向上,最終組合成根哈希。
每個塊都有一個 "header",它存儲三個不同 Merkle trie 結構的根節點的哈希,包括:
1. 狀態樹
2. 事務樹
3. 收據樹
區塊鏈有兩種類型的節點:全節點和輕節點。
全節點下載從創世塊到當前頭塊的完整區塊鏈,執行其中包含的所有交易。 礦工存儲了完整的全節點,因為挖掘過程中需要。 也可以在不執行每筆交易的情況下下載全節點。 無論如何,任何全節點都包含整個區塊鏈。
輕節點只下載每個區塊的 header ,從創世塊到當前塊,不執行任何交易或檢索任何相關狀態。 但是它們仍然可以輕鬆生成和接收有關交易、事件、餘額等的可驗證答案。
之所以可行,是因為 Merkle 樹中的哈希值向上傳播 — 如果惡意用戶試圖將虛假交易交換到 Merkle 樹的底部,這種變化將導致上面節點的哈希值發生變化,從而改變上面節點的哈希值。
任何想要驗證一段數據的節點都可以使用稱為“Merkle proof”的東西來做到這一點。 包括:
- 等待驗證的數據塊及其哈希
- 樹的根哈希
- "分支"(所有夥伴哈希沿著塊到根的路徑往上走)
任何人都可以驗證該分支的哈希在樹的整個過程中是一致的,因此給定的塊實際上符合在樹中的那個位置。
總之,使用 Merkle Patricia 樹的好處是該結構的根節點在加密上依賴於存儲在樹中的數據,因此根節點的哈希可以用作該數據的安全身份。 由於區塊頭包含狀態、交易和收據樹的根哈希,因此任何節點都可以驗證以太坊的一小部分狀態,而無需存儲整個狀態。