- 深入以太坊智能合約開發
- 楊鎮 姜信寶 朱智勝 蓋方宇
- 11774字
- 2019-05-22 18:30:43
第1章 快速了解以太坊
從2013年年底Vitalik Buterin發布《以太坊白皮書》(Ethereum White Paper)以來,以太坊逐漸被世人認同為區塊鏈2.0的代表。以太坊與區塊鏈1.0時代的代表比特幣(bitcoin)最大的不同在于應用的目的和范圍。比特幣區塊鏈由于非圖靈完備的腳本以及單個區塊存儲空間的限制,主要用于追蹤比特幣的所有權。然而以太坊是具有圖靈完備的編程語言、更高效的共識機制、支持更多應用場景的智能合約開發平臺,可以為各種去中心化應用(Decentralized App,DApp)提供運行環境。
一般來說,實際生活中的任何商品、服務、管理或經濟活動都可以在以太坊平臺上使用代碼表示,實現去中心化(decentralized)以及通證化(tokenized),從而進行交易。而且相比于傳統的方式(如使用借記卡支付等),以太坊在提供交易的安全性、抗審查性的同時,花費的成本更低。
本章內容主要參考《以太坊白皮書》以及Wiki,主要目的是帶領讀者快速了解以太坊的相關概念、發展歷史以及相關的開源項目。閱讀本章之前最好先對比特幣區塊鏈的概念以及運行原理有大致的了解,從而與以太坊進行對比理解。
1.1 以太坊是什么
根據《以太坊白皮書》(A Next-Generation Smart Contract and Decentralized Application Platform,原文參見:https://github.com/ethereum/wiki/wiki/White-Paper)的描述,我們可以對以太坊進行如下定義:
以太坊的意圖是為去中心化應用程序構建一個可替代的協議,這是一種在大規模使用的去中心化應用程序和為特定目的設計的簡單的低頻應用間進行了必要權衡的協議,同時考慮了應用間的高效交互能力。以太坊通過一個抽象的基礎設施層來實現這個目標:一個內置了圖靈完備編程語言的區塊鏈系統。在這個系統中,任何人都基于他們自己的要求編寫智能合約和去中心化應用,他們可以自定義權限控制、交易數據格式以及狀態轉換函數。在這個平臺上,我們可以構建基于密碼學原理構成的自主對象,也就是所謂的智能合約,它在比特幣腳本系統能實現的功能之上增加了圖靈完備、價值感知、區塊鏈感知和狀態保存等特性。
用最簡單的一句話來說:以太坊就是一個基于區塊鏈的智能合約平臺。
這里有兩個關鍵的基本概念:區塊鏈和智能合約。
區塊鏈(blockchain)的概念出自比特幣協議,本質上是一個基于P2P網絡(點對點網絡)的分布式賬本系統,交易數據被以所謂的“區塊(block)”進行打包,在全網節點中被順序執行并通過工作量證明(proof of work)共識算法進行數據同步和驗證,是一種已經被證明安全可靠的分布式底層技術。它具有去中心化、去信任(無須信任)、開放自治、極難篡改、極難偽造以及其他一些技術特性。關于區塊鏈,在很多書籍、資料中都有詳細介紹,這里不再過多展開。
而所謂智能合約(smart contract)其實并不是一個非常新的概念。早在1994年,美國計算機科學家尼克·薩博(Nick Szabo)就在他的論文中正式提出了智能合約的概念,并且他自己也嘗試做了實驗性的軟件系統,但并沒有得到工程上的驗證,或者說當時還沒有發現可以真正支撐相關特性的技術方案。直到2013年年底《以太坊白皮書》的出現,才使這個概念重新進入大眾的視野,而以太坊這四年來總體穩定地運行,也從工程上證明了智能合約是可以實現的。
那什么是智能合約呢?
尼克·薩博曾舉過一個現實世界中的例子來說明智能合約,他用的是ATM或者自動售貨機。很容易理解,比如ATM,我們要從自己的賬戶中取若干現金,那我們需要告訴ATM我們的賬號(無論以何種方式),然后輸入我們要提取的金額,ATM則會根據我們賬戶余額的情況判斷是否能給出足額的現金。對于自動售貨機,也是類似的。售貨機內的商品肯定是明碼標價的,我們選想要的商品,然后付錢,機器會把商品“吐出”,并找零;商品不足或者支付金額不足時會給出相應的反饋。而與此類似的功能,目前都是可以在以太坊上通過智能合約實現的。比如我可以將合約當作我自己的一個現金錢包,有需要的時候從合約中提取相應的金額,余額不足時合約也會產生錯誤;又比如,我們可以通過合約來進行虛擬資產的售賣,就像2017年的ICO(Initial Coin Offering)風潮那樣,通過智能合約來進行token的發行、售賣等操作,整個過程都可以是公開透明且自動完成的。這就是智能合約。
在以太坊中,就是通過把基于區塊鏈的交易,拿到一個具有自己的指令集、自己的存儲機制(臨時存儲和永久存儲)的可編程虛擬機中來執行,來實現智能合約的。這個虛擬機就是以太坊協議的最大創新,就是所謂的“以太坊虛擬機(Ethereum Virtual Machine,EVM)”。所以,以太坊也可以看作是“區塊鏈+EVM”。EVM就是前面以太坊的技術定義中提到的支持圖靈完備編程語言的基礎設施,我們可以通過特定的高級語言,比如Solidity,來自定義地編寫智能合約。在本書的第7章中,我們將完整、詳細地講解以太坊協議(EVM)的原理和實現細節,這里就不再做過多展開介紹了。
最后需要解釋的就是上文中以太坊的技術定義里多次提到的去中性化應用程序。DApp可以簡單地理解為以智能合約而不是以傳統的、由個別組織和公司控制的以中心化的服務器(server)為后端的應用程序,DApp的叫法是為了與那些基于客戶端-服務器(client-server)架構或者瀏覽器-服務器(browser-server)架構的所謂中心化應用程序相區別。目前來看,根據業務需求,僅將部分應該由智能合約來處理的邏輯放到類似于以太坊這樣的去中心化智能合約平臺中,而其他無須做這種改動的業務仍然基于傳統的服務器架構實現的所謂混合架構(hybird mode)的DApp具有更大的現實性,也更具有工程可行性。在本書中也有關于DApp開發的具體實例供讀者參考,在此也不再過多展開了。
如今,以太坊已經成為程序員最為青睞的智能合約開發平臺,這離不開社區為以太坊貢獻的優秀的開源DApp開發工具和框架,例如:目前最受歡迎的以太坊開發框架Truffle,可以在本地提供完整的合約編譯、部署、測試功能;以太坊的JavaScript API——Web3.js,能夠幫助開發者使用HTTP或者IPC連接輕而易舉地與本地或遠程的以太坊節點交互;在幣市上,排名前100的幣中有94%都是按照以太坊的“ERC-20 tokens”標準進行的ICO。
接下來使用一個簡單的眾籌示例來展示以太坊是如何運行的,以及以太坊在這個示例中解決了什么問題。目前世界上最大的眾籌公司Kickstarter,在每次眾籌過程中,投資者都會將資金交給Kickstarter管理。如果眾籌金額達到了創業團隊設置的目標,那么Kickstarter應該將資金轉交給團隊,否則將投資者的資金按原路返還。然而,在這個過程中,無論是投資者還是創業團隊,都完全將信任建立在Kickstarter上。目前在以太坊上已經有很多類似的應用,如圖1-1所示,創業團隊可以將眾籌合約部署在以太坊上,通過EVM由以太坊上的所有節點執行。投資者向合約發送以太幣(ether),合約將記錄資金的變化,同時也會記錄發送者的地址,以便將資金退回。
當眾籌期限截止時,如圖1-2所示,如果實現了眾籌目標,合約將自動把資金發送到創業團隊的賬戶,否則,合約將自動把資金退還到投資者的賬戶。合約的代碼以及運行過程中的每一次狀態改變都是公開透明的,沒有任何機構或個人能夠改變合約的執行結果。

圖1-1 以太坊運行示例

圖1-2 眾籌期限截止時資金的轉移
1.2 以太坊的歷史和發展路線圖
以太坊的聯合創始人Vitalik Buterin早在2011年就癡迷于比特幣背后的技術,那時他年僅17歲。他活躍于各大比特幣社區,不僅作為程序員為比特幣的發展做出了重要貢獻,而且與他人聯合創辦了Bitcoin Magazine。然而他逐漸認識到了比特幣區塊鏈的局限性,他認為區塊鏈除了可以用于數字貨幣的交易,還可以解決更多實際的問題,于是他開始考慮如何實現自己對區塊鏈的愿景。
在2013年年底,Buterin發布了《以太坊白皮書》,以太坊正式誕生。他憑借自己在開源社區的影響力,吸引了大批優秀開發者加入以太坊的開發隊伍。2014年4月,Gavin Wood博士發布了《以太坊黃皮書》,其被稱為以太坊技術“圣經”,詳細描述了以太坊技術細節,以及EVM的運行原理,為以太坊之后的快速發展打下了堅實基礎。2015年7月,以太坊第一個正式版本“邊境(frontier)”發布,從此以太坊進入高速發展期,越來越多的開發者加入其中。
根據Etherscan提供的數據,如圖1-3所示,從以太坊上線時算起,截至2018年6月,整個以太坊網絡處理的交易數量總計超過了750萬次,基本呈指數型上升的趨勢。其中,在2018年1月4日,達到了交易的頂峰,網絡在24小時內處理了130萬次交易。

圖1-3 以太坊交易數量圖
發展至今,以太坊網絡中擁有唯一地址的節點數已經超過3500萬,如圖1-4所示,從以太坊上線到2018年1月,節點總數一直呈指數級增長,其中,2018年1月5日當天為增長速度的最高峰,增加了35萬節點,之后基本以每天增加10萬節點的速度線性增長。
從各個國家和地區的分布情況來看,根據Ethernodes提供的數據,共有超過17000個以太坊節點分布在六大洲,這使得以太坊成為去中心化程度最高的區塊鏈。擁有以太坊節點數最多的10個國家如表1-1所示。
表1-1 擁有以太坊節點數排名前10的國家


圖1-4 以太坊網絡中擁有唯一地址的節點數量圖
以太坊的發展規劃主要分為4個階段,每個階段都會以硬分叉(hard forking)的方式進行。以下是這4個階段的基本情況。
第一階段:邊境(frontier)
以太坊的第一個正式版本,2015年7月30日發布。這個版本的以太坊還十分簡陋,但已經可以執行智能合約,支持礦工挖礦,也支持以太幣的交易。在這個版本上,用戶首次可以購買以太幣,并在以太坊上測試自己的DApp。
第二階段:家園(homestead)
“家園”于2015年3月14日發布,這個版本作為“邊境”的后續版本,核心開發人員對其進行了大量的優化改進和廣泛的測試,其安全性和穩定性已經受到開發者和用戶的認可。但這個階段仍處于以太坊的測試和發展階段,在發布之后依然暴露出許多問題。
第三階段:大都會(metropolis)
這一階段的目標是實現更加易用、輕量級、速度更快、更安全的以太坊,給開發者在其上開發DApp提供更大的靈活性。此階段分為兩個版本,分別命名為“拜占庭(byzantium)”和“君士坦丁堡(constantinople)”。其中,“拜占庭”版本的硬分叉發生在2017年10月16日,而“君士坦丁堡”版本的升級時間預計在2018年完成,具體時間待定。
第四階段:寧靜(serenity)
以太坊的最終版本,目前規劃在2019年完成升級。屆時,以太坊最終將從工作量證明的共識算法完全轉變成持有量證明算法(proof of stake),整個網絡也將更快、更高效、更穩定、更安全、對用戶更加友好,成為真正的主流區塊鏈。
1.3 以太坊的基本概念
1.3.1 賬戶(accounts)
在比特幣中,用戶控制的只是地址,不存在實際賬戶的概念。用戶通過帶有自己地址的作為輸出的UTXO的金額計算出自己的余額。這就類似于現實生活中使用的紙幣,每次交易都會消耗整數個的UTXO,并且產生新的UTXO(找零)。然而以太坊的核心就在于擁有賬戶的概念,每個用戶都會擁有兩類賬戶:外部賬戶(Externally Owned Accounts,EOAs)和合約賬戶(Contract Accounts,CAs)。在一般情況下,以太坊中的賬戶指的是外部賬戶。
以太坊之所以設計外部賬戶和合約賬戶,是因為在以太坊中,賬戶被認為是狀態對象:其中外部賬戶具有余額(balance),合約賬戶不僅具有余額,而且還有存儲。所有賬戶的狀態的集合就是整個以太坊網絡的狀態,每次產生區塊的過程都是以太坊狀態的一次更新,需要全網的節點達成共識。因此,賬戶對于用戶之間的交易以及以太坊之上智能合約的執行都具有至關重要的意義。
以太坊的外部賬戶由用戶創建,通過公鑰密碼學生成一個密鑰對,唯一對應一個外部賬戶。用戶在使用外部賬戶發送交易時,交易信息會被賬戶對應的私鑰簽名,從而使得EVM可以安全地認證交易發送者的身份。可以想象,如果以太坊只有外部賬戶的話,那它的功能也就只局限于外部賬戶之間發送以太幣交易,也就跟比特幣區塊鏈差不多了。用戶可以任意創建外部賬戶,而不需支付任何費用,而且外部賬戶之間的以太幣交易也不消耗費用。
合約賬戶則是由外部賬戶創建的,由相應的外部賬戶所有,但只受到合約中的代碼控制。一個合約賬戶對應一個合約代碼。合約賬戶中也可以有以太幣,這是為了將以太幣暫存,等到合適的條件或時間再將以太幣發送給其他合約或外部賬戶。合約賬戶中的代碼不會自主執行,需要其他賬戶(外部賬戶或合約賬戶)發送交易(transaction)來觸發代碼執行。合約賬戶擁有屬于自己的鏈上存儲空間,代碼以及代碼每次執行后的狀態都會存儲在鏈上。合約賬戶的創建需要消耗一定的以太幣,這是因為創建合約賬戶就是要部署新的合約,因此需要消耗一定的存儲空間存儲合約代碼。而且由于每次調用合約賬戶都會觸發代碼的執行,激發全網節點進行共識,因此合約賬戶跟任何其他賬戶發生交易的時候都需要消耗一定的代價。
從表1-2中可以清楚地看出外部賬戶跟合約賬戶之間的共同點和區別。
表1-2 外部賬戶跟合約賬戶的異同

1.3.2 合約(contracts)
以太坊中的合約也稱“智能合約”,但實際上就是一串非常簡單的代碼,并不具有智能性。在英文中稱其為“smart contracts”更多的是取單詞“smart”中“精巧的”之意,準確來說不應該翻譯成智能合約,但按照業內形成的習慣,本書依舊會采用“智能合約”或者“合約”統一作為對“smart contracts”的翻譯。
在以太坊中,一個合約實際上是一串代碼的集合,包括代碼中的各種函數以及代碼運行過程中產生的各種狀態。被部署的合約以EVM字節碼(bytecode)的形式存儲在區塊鏈上,一個合約唯一對應一個合約地址。
幸運的是,合約開發者并不需要了解EVM的原理就可以編寫自己的合約。以太坊支持多種高級編程語言,開發者可以用很少量的代碼編寫合約,經過專門的編譯器將合約編譯成字節碼之后,部署到區塊鏈上。以下是以太坊支持的幾種用來編寫合約的高級語言。
·Solidity:目前最受歡迎也是使用最廣泛的合約編程語言,語法跟JavaScript十分類似,也是官方最為推薦和支撐力度最大的編程語言。在后文的智能合約實戰部分,將全面介紹如何使用Solidity編寫智能合約。
·Vyper:以太坊平臺上目前最年輕的合約編程語言,目前仍處于試驗階段。Vyper的設計初衷是簡化合約編寫流程,減少合約執行過程中的gas消耗,增強合約安全性。Vyper的邏輯類似于Solidity,但在句法上更像Python,它的出現意味著以太坊徹底拋棄了原來基于Python的開發語言Serpent,同時為開發者提供了對于Solidity的一個替代選擇。
·LLL(Lisp Like Language):類似于匯編的略微低級的合約編程語言,適宜完成一些簡單、直接的任務。
1.3.3 交易(transaction)和消息(message)
在以太坊中,同時具有交易和消息兩個概念。這兩個概念有的時候表示的意思相同,但在一些特殊情況下卻要區別對待。在這里我們將簡單介紹兩者的相同點和不同點。
“交易”和“消息”都在《以太坊黃皮書》中有明確的定義。“交易”在《以太坊黃皮書》中的定義是:“由外部賬戶簽名的一串數據。既可以表示一個消息,也可以表示一個新的自治對象。交易記錄在區塊鏈的每個交易中。”這里的自治對象指的就是合約。簡單來說,一個交易有可能表示發送一個消息,也有可能表示部署一個新的合約。一個交易會被廣播到整個網絡中,會被礦工處理后記錄在區塊鏈上,在這個過程中會消耗以太幣。
“消息”在《以太坊黃皮書》中的定義是:“兩個賬戶之間發送的數據(data)和值(value,即以太幣)。消息既可能由自治對象產生一些確定性操作時產生,也可能由交易在數字簽名時產生。”這里的意思是一個消息就是賬戶之間傳遞的數據和一定數量的以太幣。消息有可能是在合約之間交互的時候產生,也有可能由交易產生,是一種內部的參數傳輸,不會發布在區塊鏈上。
簡而言之,交易都會在區塊鏈上記錄,而消息是發生在EVM內部的參數傳輸,不會顯示在區塊鏈上。
1.3.4 氣(gas)
以太坊作為一個“世界計算機”,在執行每次操作的時候都會消耗一定的資源(計算、存儲、內存等),因此以太坊的使用者想要讓以太坊為其工作,就要向網絡中的礦工支付一定的費用。由于計算機執行每次任務消耗的資源量幾乎是恒定的,用戶也希望自己支出的費用不會因為以太幣價格的波動而有太大的變化。于是,gas作為以太坊中一種特殊的工作量計量單位應運而生。
gas,顧名思義,可以很確切地將其比喻成以太坊世界的“燃料”,是以太坊生態系統的命脈,以太坊中的一切交易都要消耗一定量的gas。比如在現實生活中,我們想要讓我們的汽車一直運轉,就要時不時地去加油站加油,并需要按照加油的量支付相應的費用。類比到以太坊中,汽車就是我們的合約,汽油的計量單位就是gas,加油站就是礦工。
雖然礦工收取的是gas,但gas并不能在以太坊中交易,更不能在以太坊之外流通,因此礦工需要將收到的gas轉換成以太幣作為收益。與gas機制相關的幾個概念有:gasPrice、gasCost、gasLimit,以及gasFee。以太坊通過一系列機制保證在gas兌換成以太幣的過程中,gas的價值不會發生太大的變化。
1.gasPrice
gasPrice表示用戶愿意支付的gas的價格,即每單位的gas可以兌換的以太幣數量(eth/gas)。為了保證gas價值的穩定,gasPrice會根據市場的波動而一直變化,保持用戶愿意支付的價格與礦工能夠接受的價格的平衡。換句話說,以太坊的礦工會優先打包gasPrice高的交易,如果gasPrice的值過低,那么這個交易可能要等很久,甚至永遠不會被打包。根據Etherscan給出的數據,可以得出gasPrice的平均變化圖,如圖1-5所示。

圖1-5 gasPrice平均變化圖
2.gasCost
gasCost一般是恒定的值,表示以太坊的節點在執行某種操作時固定花費的gas數量,也就是表明每種操作所花費的成本是恒定的,幾乎不會發生變化,從表1-3中可以查看常用的一些操作所花費的gas數量。
表1-3 常用操作花費的gas數量

3.gasLimit
gasLimit指的是用戶愿意為某個交易花費的最高gas數量,當實際消耗的gas達到gasLimit的值的時候,交易就會終止。換句話說,就是給一個交易能夠消耗的gas數量設定一個上限。設計gasLimit的目的主要是為合約的執行提供一種安全機制,防止因為合約中的漏洞導致的對gas的無限消耗,可以將其類比成汽車油箱的容量上限。一個標準的發送以太幣的交易所設定的gasLimit一般是21000。
4.gasFee
gasFee是指在執行一個交易或者一段合約代碼的過程中實際需要支付的gas數量。一個區塊的gasFee可以用來推測出一個區塊消耗的計算量、所包含交易的數量以及一個區塊的大小。gasFee最終都會支付給礦工。
1.4 以太幣(ether)
以太幣是類似于比特幣的一種加密貨幣,在以太坊的健康可持續運行方面起著至關重要的作用。以太幣不僅可以作為一種數字資產在以太坊上交易,更重要的功能是給以太坊中的礦工支付費用(通過兌換成gas的方式間接支付給礦工)。
在1.1節中我們已經了解到,以太坊致力于構建一種分布式互聯網,為新型應用程序DApp提供基礎運行環境。盡管以太坊不被任何第三方所有,但以太坊的運行也不是免費的,需要通過一種激勵機制吸引全世界的礦工加入,為以太坊中發生的所有交易提供打包服務。跟比特幣區塊鏈通過比特幣獎勵礦工的方式類似,以太坊中獎勵以太幣。
1.4.1 以太幣的發行
2014年8月,以太坊在主網上線之前,展開了為期6個月的以太幣“預售(presale)”活動,在預售期的前兩周,用戶可以以“1比特幣=2000以太幣”的比率兌換以太幣,之后兌換比率線性降低到“1比特幣=1337以太幣”。預售活動結束后,總計募集了大約6000萬以太幣,其中1200萬以太幣用作以太坊開發資金,其余大部分都分配給了以太坊的早期貢獻者、開發者,以及“以太坊基金會(Ethereum Foundation)”。
以太坊上線后,礦工每挖到一個區塊(大約15s)會獲得5個以太幣的報酬,即挖礦獎勵(mining reward)。有些礦工雖然也挖到區塊(找到了PoW的解),但他們的區塊可能因為網絡原因沒有被添加到區塊鏈上。此時,他們可能仍然會獲得2~3個以太幣的報酬,這種獎勵稱為“旁系獎勵(uncle/aunt reward)”。在拜占庭版本更新后,挖礦獎勵和旁系獎勵分別降低到了3個以太幣和0.625~2.625個以太幣。
根據2014年預售時各方商定的條款,每年以太幣發行的上限是1800萬,這個數字大約是最初發行量的25%。
1.4.2 以太幣的單位
以太幣的基礎單位稱為wei,其他單位都是從wei衍生出來的,例如Kwei、Mwei等,而且這些衍生出的單位都有獨特的名字,一些源自為計算機科學和加密貨幣的發展做出杰出貢獻的人的姓氏。表1-4列出了以太幣各個單位的名稱以及換算關系。
表1-4 以太幣單位換算關系

1.4.3 以太坊挖礦
以太坊中的“挖礦”跟現實世界挖掘金礦類似,只不過礦工獲取的是以太幣,而不是金礦。礦工在付出算力和電力挖礦的同時,實際上維持了整個以太坊網絡的安全運行。為了補貼和獎勵這些礦工,以太坊中每有一個區塊生成,發布該區塊的礦工將獲得一定數量的以太幣作為獎勵。在以太坊中,挖礦是目前發行以太幣的唯一方式,也是人們獲得以太幣的主要方式(還可以通過交易換取以太幣)。
以太坊中之所以存在“挖礦”和“礦工”的概念,是因為以太坊與比特幣區塊鏈一樣,采用工作量證明算法(Proof of Work,PoW)實現全網共識。工作量證明算法的核心是礦工在將交易數據打包進區塊的時候,需要計算一個奇異值,使得整個區塊的哈希值滿足某個條件。由于哈希算法的特性,網絡中的節點在計算這個奇異值的過程中,沒有比逐一枚舉更優的策略,然而驗證奇異值是否滿足條件只需要一次計算即可完成。找到符合條件的奇異值的時間與條件設置的難度以及節點的算力有關,因此,每個節點都有機會獲得發布區塊的權利,但算力更高的節點最終勝出的概率更高。除此之外,還可以通過調整條件設置的難度來控制全網產生一個區塊的平均時間,在以太坊中,目前區塊產出的平均時間是15s。
1.5 以太坊測試網絡
和大多數區塊鏈網絡一樣,以太坊網絡也分為主網(mainnet)和測試網(testnet),彼此相互獨立,為不同目的服務。
以太坊的主網即以太坊實際的“生產環境”。在主網上,以太幣具有實際的價值,每次以太幣的交換以及智能合約的執行都意味著實際價值的轉移。測試網則是為了給開發人員測試新的網絡特性,以及測試為智能合約的運行效果提供服務的“測試環境”。測試網中的以太幣不具有實際價值,測試人員可以給自己的賬戶設置任意數量的以太幣進行測試,而不用消耗實際的以太幣。任何組織和個人都可以根據自己的需要搭建公開或私有的測試網絡。以太坊官方發布的測試網絡的發展歷程如下。
(1)Olympic Testnet:Olympic Testnet是跟隨以太坊的第一階段“邊境”發布的測試網絡,在2015年年初發布,不到半年就被Morden Testnet取代了。
(2)Morden Testnet:Morden Testnet取代Olympic Testnet之后被稱為以太坊第一個真正的公開測試網絡,從2015年7月一直運行到2016年10月。然而由于區塊鏈逐漸臃腫之后導致的同步時間過長,以及Geth客戶端和Parity客戶端共識不一致等問題,Morden Testnet被重建,之后改名為Ropsten Testnet。
(3)Ropsten Testnet:Ropsten Testnet服務于以太坊的第二階段“家園”,于2016年年末發布,是一個能夠跨客戶端運行的測試網,直到2017年2月都在正常運行。在當時發生了一起針對Ropsten Testnet的惡意攻擊事件,攻擊者將gasLimit的正常值從470萬調整到了90億,導致網絡中充斥了大量的巨型交易數據。大約過了一個月的時間,Ropsten Testnet才恢復正常。
(4)Kovan和Rinkeby:Kovan和Rinkeby都采用了權威證明算法(Proof of Authority,PoA)進行共識,只是分別服務于Parity客戶端和Geth客戶端。在這兩個測試網絡中,以太幣的發行由受信的第三方控制,而不是礦工。這些受信的第三方一般是參與以太坊開發的區塊鏈公司,致力于解決以太坊測試網中存在的問題。
1.6 以太坊客戶端
以太坊客戶端是一個寬泛的概念,凡是能與其他以太坊客戶端通信,而且能夠解析和驗證以太坊網絡中傳遞的各種交易消息(包括合約代碼等)的節點都可以稱之為以太坊客戶端。主流的客戶端應該也會提供創建交易以及參與挖礦的功能。
得益于Gavin Wood博士撰寫的《以太坊黃皮書》,開發人員可以使用可行的編程語言在大多數平臺上開發以太坊客戶端,這也造就了以太坊客戶端百花齊放的局面。盡管不同的客戶端由不同的團隊創建,使用不同的編程語言實現,但它們都遵從一樣的協議。
目前,市面上主要有6個使用較廣泛的以太坊客戶端,分別用不同的編程語言實現。其中,Geth和Parity是目前最流行的兩個以太坊客戶端,所擁有的節點占有率遠超其他語言實現的客戶端。Geth使用Go語言實現,被公認為是以太坊客戶端的“官方”版本,目前擁有最多的節點占有率。Parity則使用相對小眾的Rust語言實現,其作者就是《以太坊黃皮書》的作者GavinWood,目前占有大約30%的節點。
1.7 以太坊生態系統全景掃描
以太坊誕生之后,Gavin Wood首次提出Web3的概念,即利用區塊鏈技術將目前中心化的應用和服務搭建在去中心化的協議之上。然而,想要實現如此宏大的愿景,單憑以太坊的EVM遠遠不夠,還需要搭建許多外圍的基礎設施,圍繞以太坊搭建全新的生態系統。本節將簡單介紹目前最受關注的Swarm、Whisper以及ENS(Ethereum Naming System)3個項目,以使讀者對以太坊的生態系統建設有大致的了解。
1.7.1 Swarm
Swarm項目由以太坊的核心團隊開發,是一個分布式的存儲平臺,提供內容分發服務,在Web3架構中充當最基礎的一層。Swarm的終極目標是為以太坊提供去中心化程度和冗余度足夠高的公共數據庫,尤其是用來存儲和分發區塊鏈上的數據。具體來說,Swarm致力于為DApp提供一系列基礎服務,包括但不限于消息傳播、數據流、點對點審計、數據庫、存儲保險、易變資源更新等。
從終端用戶的角度來說,Swarm的突出特點不止體現在將數據分散式存儲,更重要的是Swarm能夠依靠以太坊區塊鏈的優勢,給用戶提供一種具有抗DDoS攻擊、抗審查、永不宕機、容錯性高的分布式存儲服務。以太坊基金會采用和運行以太坊測試網絡類似的方式運行著一個Swarm的測試網絡。所有人都可以通過在他們的服務器、臺式計算機、筆記本式計算機或者移動設備上運行Swarm節點來加入網絡。
1.7.2 ENS
ENS基于以太坊的命名轉換服務,主要功能是將形似“0xbfb2e296d9cf3e593e79981235aed29ab9984c0f”的以太坊錢包地址或者智能合約地址轉換成易讀的“myname.eth”形式。ENS另外還有一個功能,是提供有關命名的元數據,例如智能合約的ABI或者用戶的whois信息。
從功能上看,ENS非常類似于我們熟悉的DNS(Domain Name Service),只不過ENS所要轉換的并不是網站的IP地址,而是以太坊賬戶地址、合約地址以及以太坊中其他的身份信息。ENS同樣也是使用“.”將域名分級,每一級域名的擁有者對其下的子域名都有控制權。ENS的頂級域名,例如“.eth”和“.test”,由智能合約控制,合約中說明了其下子域名的分配規則。
由于ENS的實現完全依托于以太坊區塊鏈,故ENS跟DNS的架構完全不同。ENS包含兩個主要部分:注冊器和解析器。注冊器由一個單獨的中心合約組成,記錄了所有的域名以及每個域名對應的所有子域名的信息。解析器則負責從域名到地址的實際解析工作。
1.7.3 Whisper
Whisper同樣由以太坊的核心團隊開發,代碼直接嵌在以太坊客戶端中。簡單來說,Whisper是用于以太坊上DApp之間相互通信的協議。Whisper的設計并不是為了提供面向連接的系統,也不是為了幫助網絡中某一對通信節點簡單地傳送數據。Whisper專為簡單高效的廣播通信設計,同時也適用于底層異步通信。典型的應用場景如下:
·需要節點之間互相發布一些信息,且希望這些信息具有一定時效性的DApp。例如,數字貨幣交易所可能需要這種應用來記錄某人以某一匯率出售電子貨幣的報價信息。
·需要提供節點之間非實時的線索提示或者一般性通信的DApp。例如,小型聊天室應用。
·需要節點之間相互協作才能進行交易的DApp。例如,在數字貨幣交易所中,可以使用這種DApp在創建交易之前協調多個報價信息。
Whisper的設計很大程度上考慮了對用戶隱私的保護,然而這種保護需要消耗節點相當大的性能。在最安全的運行模式下,Whisper在理論上可以提供100%的隱匿度。用戶在使用Whisper的同時也可以自定義隱私級別,作為隱私保護與性能消耗之間的權衡。
Whisper是一種底層協議,不同的DApp可以根據特定的需求調整對于Whisper的使用設置,因此它也被稱為DApp的發展基石。Whisper目前還在開發當中,處于PoC(Proof of Concept)的第二階段,已經可以在現有Geth和Parity版本上使用。因此,至于將來的發展,Whisper的很多特性還可能發生變化。
1.7.4 其他相關項目
1.Oraclize
以太坊作為一個DApp的開發平臺,其上的許多應用都需要從萬維網上讀取數據,例如,金融類的應用需要資產的價格數據;保險類的應用需要天氣的數據;游戲類的應用需要生成隨機數,等等。然而,從某種程度上來說,區塊鏈是一個相對“封閉”的網絡,無論是比特幣的腳本(script)還是以太坊的智能合約,都無法從區塊鏈外部直接讀取數據。Oraclize的誕生解決了這個問題。
Oraclize在區塊鏈的世界里充當“數據搬運工”的角色,它為Web API與DApp之間建立了可靠的連接。當以太坊上的智能合約需要抓取外部數據時,它需要向區塊鏈上Oraclize合約發送一個查詢(即合約調用),指定數據源以及相關參數。Oraclize的服務端會不斷掃描新傳入的查詢,每當找到一個新的查詢時,服務端會根據查詢制定的數據源及參數抓取數據,將其打包后調用合約的_callback方法將結果返回。
在整個數據傳輸過程中,Oraclize并沒有打破區塊鏈自身的安全模型,也沒有更改數據源的格式和服務。Oraclize的解決方案是為所有從數據源處獲取的數據做真實性證明,證明文件可以跟返回的數據一起獲得。關于Oraclize實現真實性證明的細節以及Oraclize服務的使用方法可以從官網www.oraclize.it獲取。
2.IPFS
IPFS(InterPlanetary File System,星際文件系統)是一種新型的超媒體分布式存儲、傳輸協議,旨在構建更快、更安全、更自由的互聯網。與傳統的HTTP不同,IPFS索引數據的方式并不是依賴于服務器的IP地址,而是數據的哈希值。除此之外,IPFS最大的優勢體現在數據的存儲是分布式的,從而有效地避免了單點失效,也在很大程度上降低了DDoS攻擊的風險。
IPFS本身在技術上沒有獨特的創新,IPFS的主要貢獻是將多種市面上成功的P2P技術融合在一起,形成一個單獨的分布式系統,從而達到“1+1>2”的效果,這些技術主要包括:哈希表(Distributed Hash Tables,DHTs),文件共享系統——BitTorrent,版本控制系統——Git,自認證文件系統——SFS。IPFS將每個文件的哈希值作為文件的索引,不但可以快速檢索文件,而且可以實現在全網剔除冗余數據,減少對存儲空間的需求。IPFS使用的數據結構是Merkle DAG(與Git存儲文件的數據結構相同),因此可以記錄文件的所有變更記錄,并且可以輕易回溯到文件的某一歷史版本。每個IPFS節點除了存儲本地所需的數據之外,還會存儲一張記錄數據存儲位置的哈希表,以便進行文件的查詢和下載。
IPFS本身并不是為區塊鏈而設計的,但其與生俱來的去中心化屬性以及存儲文件的數據結構可以用作區塊鏈的鏈下存儲,很好地解決了區塊鏈本身存儲容量受限的問題。目前,在以太坊平臺上引入IPFS作為鏈下存儲的一般方案是,將數據本身存入IPFS,獲得數據的索引哈希值,之后將該哈希值存入區塊鏈中。
1.8 本章小結
在本章中,我們帶領讀者初步窺探了以太坊的世界,主要介紹了以太坊相關的概念以及以太坊目前的生態建設情況。一些讀者朋友可能在初次閱讀本章之后仍然會對一些概念感到有些模糊,不過沒有關系,請讀者朋友們繼續閱讀后續的實踐以及原理剖析的章節,很多概念都會在后面經常出現,到時回到本章再次閱讀,相信讀者會有更進一步的理解。