2018 年 07 月 14 日,秘猿科技區塊鏈工程師蔣金洋在“開發者的以太坊入門指南”中,進行的《如何實現一個簡單的以太坊》演講分享。“IT 大咖說”作為獨家影片合作方,經主辦方和講者審閱授權釋出。
以太坊是社群驅動的專案,並且一直在更新,以太坊基金會一直鼓勵多種實現以避免網路故障。那麼如何去實現一個以太坊?本次分享介紹如何去了解以太坊規範,以及實現以太坊的主要元件和功能。
為什麼要學習以太坊
對於 The DAO 專案相信很多人聽說過,該專案使用智慧合約完成了 DAO(去中心化的自治組織)功能,參與專案的人員可以用私鑰給專案轉一筆資金以獲得相應的投票權,然後使用投票權表決這筆資金的用處。雖然專案最後因為智慧合約的漏洞而掛掉了,但是這種用法相對最原始的區塊鏈應用要跨出一大步。
去中心化交易所是區塊鏈的另一個應用場景,它的本質是用智慧合約來保證安全性。雖然在資產的交易過程中會有一部分中心化服務用來匹配交易的過程,但是資金永遠是由私鑰透過以太坊網路和智慧合約來控制的。
從這兩個案例可以看出智慧合約和以太坊的 web3.0 概念的確有值得稱道的地方,它們在保證資金和機制公開透明同時,也給予了使用者更多的權利。而這些在中心化服務裡很難實現,或者說是一種奢望。
如何學習區塊鏈
以此為契機我萌生了投入到區塊鏈領域的想法,並開始尋找與區塊鏈相關的公司加入他們。秘猿科技是我首先想到的公司,這家公司令我映像最深的是他們主要產品都在 GitHub上,包括區塊鏈產品、錢包、區塊鏈瀏覽器都可以找到,而且許可證非常開放。不過由於之前並沒有區塊鏈方面的知識積累,所以最終我是以 Web 開發的身份加入的,並在試用期間開始學習區塊鏈相關的技術。
“擼鏈”是我認為比較有效的學習方法,公司內部也有很多透過“擼鏈”從 web 開發轉到區塊鏈開發的人員。簡單來說“擼鏈”其實就是自己去實現一條區塊鏈。對於我來說既然要做區塊鏈,當然是選擇第二代的以太坊作為實踐目標。
“擼鏈”的難點在於要耗費大量的時間和精力,最終可能還做不出來。收益也很明顯,一條區塊鏈的完整實現過程,無疑會大大提高個人在此領域的開發能力。
最終成果
上圖是我花了 3 個月的時間從頭到尾實現以太坊的最終成果。在實踐的過程中,我剛開始看的是以太坊的 wiki,其中包含所有關於以太坊的相關資料。
不過要想實現以太坊的核心,還需要去看一本黃皮書,此書由以太坊的技術合夥人所寫,書中形式化的證明了以太坊核心的 EVM 部分,並含有大量的公式,學習起來相當困難。
然而這還不最難的,更難的地方在於以太坊是一個正在開發的專案,所以沒有固定的規範,很多情況下都需要去除錯已有的客戶端才能理解當前的實踐的含義。當做到這一步的時候,我會發現雖然剩下要做的東西還有很多,但是難度卻陡然下跌,大部分只要花費時間就能夠實現,不再像之前那樣無從下手。
以太坊測試
Ethereum Tests 是需要開發者重點關注的專案,因為這是唯一能夠追蹤以太坊規則變動的專案。它提供了大批的單元測試用來測試以太坊的實現,只有透過了這個測試才可以算是實現了以太坊的規範協議。
Test 中頻繁更新的目錄並不多,大概只有 3、4 個,不過裡面集中了大概幾千條測試。其中 BlockchainTests 主要是一些關於以太坊塊的驗證和 fork 規則,PoWTestsfuz 負責驗證共識演算法是否符合規定,RLPTests 是以太坊的編碼庫測試。
測試過程
測試的時候首先給我們一個 json 格式的檔案(如上圖),儲存有一些初始化的值,包括錢包和鏈的地址,balance
是二進位制化的錢包餘額,code
為空表示這個地址是一個錢包而非合約,storage
表示合約中儲存的資料,之後我們將自己的初始資料相應的填入其中。
第二步會提供給我們一些輸入,比如對於 BlockchainTests,就會提供很多塊資料,我們要將這些輸入到我們的實踐中。按照以太坊的規範,此時會執行塊的內容,執行完之後最初的 json 檔案會發生變化,之後要做的是檢驗變化後的狀態是否和測試中的狀態一致。
如何瞭解以太坊的規範
就拿 DevP2P 元件為例,它是以太坊的底層網路元件,以一種 P2P 的方式使節點之間互相連線,給上層應用提供隨意通訊的能力。
DevP2P 的規範大概可以從 wiki、黃皮書、EIP 等 3 個地方獲取到。wiki 是以太坊所有資料的入門,不過這裡面的資料可能不會太過詳細,對 DevP2P 的描述也僅限於告訴你它是什麼,沒有具體的實現方法。
黃皮書主要是寫的是 EVM 的規範,類似 DevP2P 的網路部分並沒有涉及。EIP 是社群驅動的以太坊改進提案,社群成員可以透過提交 EIP 來向以太坊官方展示自己的提升方案,如果官方認可該議案,會給它分配一個 EIP 編號,然後讓社群成員一起來參與討論,最後再去各客戶端實現。可以說以太坊中的大部分規範都在這裡,很遺憾的是 DevP2P 在 EIP 中提到的也不多。
在以上方式都行不通的情況下,我們只能去檢視官方客戶端的程式碼進行除錯,如上圖在官方程式碼中插入一些 print 語句。這也是我所用的方法,將 geth 收到的資料一段段的列印出來和本地的處理程式碼進行對比。