以太坊區塊鏈架構 <7> 文組也該知道的區塊鏈技術知識
Blockchain Technical Overview <7> Structure of Blockchain (Ethereum)
收看本系列文章的讀者,應該都對於區塊鏈的基本原理和架構有些概念,如果沒有,推薦您先去 Google 搜尋 區塊鏈、比特幣、以太坊這些關鍵字了解一下。我們將在這些基礎概念之上,來談區塊鏈的技術知識。本系列文章並不會談到太深的技術鑽研,而是希望以深入淺出的方式讓每一個想要搞懂區塊鏈技術的人都能在讀完後說出:原來如此!
本系列文章由區塊鏈技術解決方案開發公司:Pelith 編撰。內容皆經過諸位區塊鏈資深研究員及開發者校對與驗證,盡可能確保內容正確無誤,讓讀者能安心吸收正確的區塊鏈技術知識。
上一節 我們帶大家核心地認識了區塊鏈架構的全貌,相信大家都更加了解區塊鏈運作的機制和原理。本篇文章我們將接續上篇來介紹 區塊鏈 2.0 以太坊- Vitalik 如何在中本聰設計的比特幣架構上進行升級與改動,透過首度揭曉的「以太坊區塊鏈架構圖」帶大家完整認識以太坊的運作原理!
區塊鏈 2.0-以太坊 Ethereum
本篇文章的內容會在前面幾章介紹過的概念之上接續進行介紹。若您未讀過前面幾章的內容可能會有些吸收不良,建議您先行閱覽再來閱讀本篇文章。
傳送門:《區塊鏈技術知識》目錄 (建議您依序從 第 1 節 閱讀至 第 6 節)
How Ethereum Blockchain Work
以太坊虛擬機(EVM — Ethereum Virtual Machine)
介紹以太坊區塊鏈架構前必須要介紹一下「EVM」 ,EVM 是以太坊為了讓人人都能成為節點而創造的計算引擎。由於每個節點的軟硬體環境可能都不一樣,為了確保每個節能都能進行一樣的運算,於是各個節點都 透過 EVM 來執行 Ethereum 交易的狀態轉移與智能合約,以確保每一個節點都有相同的執行環境。
前言完畢,緊接著我們便來一探究竟:
以太坊交易的一生
有別於比特幣的 UTXO,以太坊是採用 Account 的架構。
由於以太坊多了智慧合約的設定,將會分成 A. B. C 三個 part 來做說明,
我們先從最單純的 Ether 轉帳交易開始看起:
A. 單純的 Ether 轉帳交易
- 一個使用者(EOA)欲發起一筆交易。
- 透過錢包(管理私鑰的工具)輸入交易資訊
To: 對方接收地址;
Amount: 欲轉移的 Ether 數量;
Gas Price: 單位 Gas 給的手續費;(參閱 第 5 節)
Gas Limit: 普通的 Ether 轉移交易都是 21,000 Gas,不用動;
Input Data: 視是否要在交易中留下文字訊息。 - 以私鑰簽署交易。
- 廣播「加上簽名的交易封包」至鄰近的以太坊節點們。
- 節點接收到新交易時,會先至 State Database 檢查交易發起地址是否具有足額 Ether(Balance)可做轉移,若無則該交易會即刻被丟棄。
- 若檢查後確認有足額,則該交易會被放入到 Tx Pool 中。
(按照 Gas Price 設的多寡由高至低排序) - 等待出塊的同時,各節點會
A. 廣播接收到的交易
B. 接收未在 Tx Pool 內的交易 - 礦工節點們(有在用電腦算力找 nonce 值,拼出塊獎勵的節點)會撈取手續費較高的交易們,進到 EVM 運算並更改狀態值後,將已完成運算的交易們來打包成新區塊(運算中出現錯誤的交易會被丟棄),隨後用電腦算力來計算 nonce 值。
*註:這邊的 nonce 值 跟前面介紹過的 以太坊地址的 nonce 值 不同(以太坊有兩個 nonce:一個是挖礦的;一個是地址的交易序次。)
*註 2:運算的同時便會消耗 Gas。 - 成功找到 nonce 值,出塊的礦工會獲得出塊獎勵及該區塊所有打包交易給的手續費。
- 該礦工節點將新的區塊廣播至全世界的其他節點們。
- 其他節點同步 <8660586 區塊高度(最新的區塊)>、
<State Database>、<Tx Pool> 資料,繼續廣播與接收新交易。 - 礦工節點再從 Tx Pool 中撈取未出塊的交易們運算並打包成新的區塊。
- 以 Remix 或其它開發工具撰寫完成智慧合約。
- 將原始碼編譯為 Bytecode。
- 使用者(EOA)透過錢包(管理私鑰的工具)輸入交易資訊
To: 0x0
Amount: 視是否要將 Ether 打入合約中
Gas Limit: 按照合約繁複程度決定要設多少
Gas Price: 視交易狀況及欲出塊的時間急迫性
Input Data: 放入合約 Bytecode - 以私鑰簽署交易,廣播「加上簽名的交易封包」至鄰近的以太坊節點們。
- 節點接收到新交易時,一樣會先至 State Database 檢查交易發起地址是否具有足額 Ether(Balance)可做轉移(有些情況會把 Ether 打入合約) ,若無足額則該交易會即刻被丟棄。
- 若檢查後確認有足額,則該交易會被放入到 Tx Pool 中。
(按照 Gas Price 設的多寡由高至低排序) - 等待出塊的同時,各節點依舊會
A. 廣播接收到的交易
B. 接收未在 Tx Pool 內的交易 - 礦工節點們撈取起本筆合約部署交易,進到 EVM 運算。
- 將合約程式碼部署至 Program Code ROM,是個部署後便不能進行更動的 Read-Only Memory(唯獨記憶體)。
- 同時,智慧合約亦可以另外使用記憶體(Memory)來儲存合約所需要紀錄的資訊。例如:一個發行 ERC-20 Token 的智慧合約,便可以使用記憶體來 紀錄各個以太坊地址所「持有 Token 數量」,追蹤各個地址的 ERC-20 Token Balance。
- 上方步驟完成後,便會將運算後的結果(合約地址、Gas Used)寫回到該筆交易中。
- 礦工節點們將運算完的交易們 打包成新區塊(運算中出現錯誤 或 Gas 給不夠 的交易會被丟棄),隨後用電腦算力來計算 nonce 值。
- 成功找到 nonce 值,出塊的礦工會獲得出塊獎勵及該區塊所有打包交易給的手續費。
- 該礦工節點將新的區塊廣播至全世界的其他節點們。
- 其他節點同步 <8660586 區塊高度(最新的區塊)>、
<State Database>、<Tx Pool>、<Contract Code ROM>、
<ERC-20 Token Balance> 資料,繼續廣播與接收新交易。 - 礦工節點再從 Tx Pool 中撈取未出塊的交易們運算並打包成新的區塊。
- 透過 DApp 介面或其它方式來呼叫智慧合約進行互動
- 生成以下形式的交易格式:
To: 合約地址
Amount: 視是否要將 Ether 打入合約中
Gas Limit: 按操作合約的繁複程度決定要設多少
Gas Price: 視交易狀況及欲出塊的時間急迫性
Input Data: 放入以 hex 型態表示 的「要呼叫的合約 function 與 參數」 - 以私鑰簽署交易,廣播「加上簽名的交易封包」至鄰近的以太坊節點們。
- 節點接收到新交易時,一樣會先至 State Database 檢查交易發起地址是否具有足額 Ether(Balance)可做轉移(如牽涉到) ,若無足額則該交易會即刻被丟棄。
- 若檢查後確認有足額,則該交易會被放入到 Tx Pool 中。
(按照 Gas Price 給的多寡由高至低排序) - 等待出塊的同時,各節點依舊會
A. 廣播接收到的交易
B. 接收未在 Tx Pool 內的交易 - 礦工節點們撈取起本筆「合約操作交易」,進到 EVM 運算。
- 根據合約地址撈出 Program Code ROM 中的合約程式碼。
- 依照 MethodID (Function Hash) 找到合約中對應的 Function。
- 將相關參數填入進行對應運算。
以 ERC-20 Token 的 Transfer Function 為例,運算時便會更改相關地址的 ERC-20 Token Balance。 - 上方步驟完成後,便會將運算後的結果(新的 Token Balance、Gas Used)寫回到該筆交易中。
- 礦工節點們將運算完的交易們 打包成新區塊(運算中出現錯誤 或 Gas 給不夠 的交易會被丟棄),隨後用電腦算力來計算 nonce 值。
- 成功找到 nonce 值,出塊的礦工會獲得出塊獎勵及該區塊所有打包交易給的手續費。
- 該礦工節點將新的區塊廣播至全世界的其他節點們。
- 其他節點同步 <8660586 區塊高度(最新的區塊)>、
<State Database>、<Tx Pool>、<ERC-20 Token Balance> 等資料,繼續廣播與接收新交易。 - 礦工節點再從 Tx Pool 中撈取未出塊的交易們運算並打包成新的區塊。
至此,我們便核心地介紹完了以太坊區塊鏈的架構。儘管有許多的技術細節我們此時並未完整交代也未深入著墨,但相信對於初學區塊鏈技術讀者來說應該能逐步建立起區塊鏈架構的全貌。未來我們將持續在這基礎上解析更多面向的區塊鏈技術知識,謝謝大家!
下一節,我們將來介紹「為什麼發送 ERC20 Token 需要兩次交易」這個困擾許多人的疑問,在本篇文章中會充分為您解惑,我們將闡明發送 ERC20 Token 背後的技術解析。
以上,若有任何
A. 我寫得不夠清楚的地方
B. 撰寫上改進的建議
C. 希望我能夠撰寫分享的區塊鏈技術知識內容
都非常歡迎在底下留言回覆。希望我的文章能幫助到更多像我一樣想學習區塊鏈技術與知識的朋友。如果您覺得讀完有所收穫,也希望能
*不吝嗇給我 Like / 50 claps
*分享給您的朋友們
謝謝大家!