這週接到台北大學剛畢業的同學的提問,好高興。問題問得很好。主要詢問談區塊鏈技術時,幾個易混淆的詞。在此一一回覆。
「以太坊(Ethereum)」口語上使用時,通常是指「以太坊區塊鏈 (Ethereum blockchain)」。我們用這些詞來稱呼整個系統。講「以太坊 p2p 網路(Ethereum peer-to-peer network)」,主要是想描述硬體的部分。硬體是指所有那些有跑客戶端軟體全節點的電腦們。基本上可以想像是,一大群不認識的網友的電腦們。例如,有可能是一個工程師,他在家裡跑一個全節點的一台主機,或可能就只是一台有跑全節點的筆電。整個系統是由世界各地許多電腦互相連線所形成。這些電腦會互相分享資料,最後資料會達成一致。
「區塊鏈(Blockchain)」這個詞,其實就是歷史資料的部分。一個區塊是裝了一堆交易。代表了交易資料的順序。這個順序是重要的。每個區塊有編號,並且會指向前一個區塊是誰。所以區塊鏈會形成一個所有歷史上發生過的交易的順序。而「以太坊 World State 」或稱「以太坊 World State Trie」則是現在當下的狀態資料:包含所有帳戶的餘額、所有智慧合約程式編譯後的位元碼(bytecode)、以及所有智慧合約所定義的變數當下的數值。
為什麼要強調 p2p 網路?因為區塊鏈並不是由單一一台電腦所形成。許多區塊鏈的行為之所以複雜,是因為行為是點對點網路中多台電腦互動之下所造成的結果。強調點對點網路,可以幫助讀者去形成對系統樣貌的正確想像。
EOA 是英文 Externally-owned account 的縮寫,中文可以稱為「外部帳戶」或稱「外部擁有帳戶」。以太坊的 World State 是由眾多帳戶組成。帳戶主要分兩個種類。使用者可以用自己的私鑰去控制的帳戶即為外部帳戶。使用者可以藉由發送交易,來動支其帳戶的餘額或與其他帳戶互動。另外一種帳戶為合約帳戶(Contract Account)。這是藉由部署合約所產生。合約帳戶內的餘額會由合約程式碼的邏輯來決定其行為。
Nonce 計數器的目的是要避免交易的重放攻擊(replay attack),或稱為回放攻擊。當使用者甲欲轉帳 10 元給收款方乙時,發送的交易資料由以下幾個主要欄位形成:
系統在處理這筆資料時,會檢查數位簽章簽署的訊息,也就是上面諸欄位,作為確認發送方同意的手段。系統還會檢查交易上計數器的數字,是否與發送方帳戶資料的計數器相同(數值現在皆為 3)。如果不相同,則交易無效。在交易成功生效後,發送方帳戶的計數器數字會增加一(變成 4)。而發送方未來發送的交易,也同樣要附上對應的計數器數字(也是 4)。
假設沒有計數器的檢驗機制,惡意攻擊者可以藉由重新發送使用者甲的交易,達成對甲的餘額重複扣款。這是因為系統不會知道這筆交易已經發過了。而有了計數器檢查,過去已經發過的交易,再次發送都會失效。
以太坊的點對點網路中,由眾多電腦連線組成。「節點」就是網路中一台電腦的稱呼。不同的節點可能擔任不同角色,執行不同任務。
「驗證者」就是一種特別的節點,他負責系統資料的寫入。驗證者會監聽點對點網路中又其他節點廣播而來的交易,並且存放在記憶體中。我們稱存放交易的記憶體空間為「記憶池」。驗證者會從記憶池中,挑選手續費最高的交易,優先打包到區塊裡。
「區塊」本身也是資料,記載著眾多使用者交易。區塊裡的交易會對世界狀態造成變更:可能是餘額、合約程式碼、或合約變數值的更新。驗證者接著會把區塊廣播到點對點網路中,讓其他節點收下。其他節點在逐筆執行區塊中的交易之後,各自更新他們所保存的世界狀態。更新之後,整個點對點網路的世界狀態應該都是要完全相同的。
以太坊的帳戶是一個 「鍵-值 對 (key-value pair)」結構。「鍵」key 的部分是 20 位元組(byte)的地址,而「值」value 的部分是由四組資料形成:
這四個欄位的意義,會因帳戶是外部帳戶或合約帳戶而有所不同。外部帳戶與合約帳戶,這兩者的餘額欄位都有意義。外部帳戶則是有 Nonce 計數器,而合約程式及儲存欄位是空值。合約帳戶 Nonce 計數器的數字,會是這個合約曾經建立其他新合約的次數。合約程式與儲存欄位則記載相應的資料。
一般而言,口語上我們會把地址和帳戶混著使用。「我匯款到你地址」和「我匯款到你帳戶」口語上意義一樣。所以除非特別要區分地址與其他欄位,大多時候 EOA 地址就是在講 EOA。EOA 地址與 EOA 是指稱一樣的東西。
區塊鏈中的專業名詞之所以經常感到意義不明、混亂難區分,經常自學看一些影片和文件看到一頭霧水,第一個關鍵原因是這些英文的詞,當初在取名字的時候,就顯然已造成混淆。英文專業詞的英文本身就已經意義不明確。比如說,英文 Externally-owned account 的「externally」到底是什麼意思?這個外部是相對於誰的外部?英文可能可粗略地解釋為,「相對於 EVM 的外部」的帳戶,若如此來看,又是什麼意思?
第二個原因是英文翻譯到中文的翻譯問題。「bytecode」就是一個例子。以太坊的 「bytecode 位元組碼」是指 Solidity 智慧合約編譯之後產出的結果。目前的翻譯,位元組是 byte。位元組碼是 bytecode。
英文的 bytecode 是「一串 byte 位元組」所組成,「bytecode」的中文翻譯需要另外發想一個新詞。翻譯上遇到挑戰。目前翻譯有幾個詞在考慮:「位元組碼」、「位元碼」。「位元組碼」比「位元碼」適合的原因是,「bytecode 位元組碼」他是以 byte 為單位的。所以 bit 的數量一定都是 8 的倍數。如果翻譯翻成「位元碼」,那麼他有可能是以 bit 為單位,而 bit 的數量可能不回是 8 的倍數。所以「位元碼」相對不適合。
第三個是有些詞已有確切定義,翻譯上難以強調有新的意義。例如,在以太坊的語境下,已經有的詞彙可能特指某一個事。舉例來說,地址 address 這個詞,生活中可能覺得是指住家地址或電子郵件的 email 地址,但在以太坊的語境中,address 是特別指一串 20 位元組(byte)的資料。語境切換的問題也容易導致名詞意義混亂。