- 深入以太坊智能合約開發
- 楊鎮 姜信寶 朱智勝 蓋方宇
- 4398字
- 2019-05-22 18:30:42
前言
為什么要寫這本書
筆者其實并不是開源軟件的早期擁躉,而是一名在企業IT服務領域工作了16年的老程序員。大概在2016年下半年,因為工作需要,筆者開始研究區塊鏈,開始考慮在企業業務中使用這種所謂的“新技術”。不過因為當時的企業級區塊鏈方面還沒有可用的技術平臺(Fabric還不成熟),所以最終沒有在具體業務中使用區塊鏈。但也是由于這次對區塊鏈技術的學習,筆者發現了區塊鏈技術的潛力,尤其是發現了以太坊這個項目的潛力,這使筆者受到了很大的觸動,筆者感覺自己有可能基于對技術的理解和鉆研精神,在這個新領域中獲得超出過往十余年所取得的成績。
筆者在2017年用業余時間翻譯了以太坊官網的Homestead文檔,沒有用任何翻譯軟件,完全是自己讀原文來將其譯為中文的;而后參與了HiBlock社區組織的Solidity官方文檔的中譯項目,并很快成為項目的管理員,對中譯版做了很多的校訂工作,這也是以太坊社區官方的中文版本(以太坊官網上的Solidity文檔中有對應的鏈接)。之后就是《以太坊黃皮書》(Ethereum Yellow Paper)。《以太坊黃皮書》就是以太坊協議的技術說明文檔,里邊記載了以太坊協議的幾乎全部細節,包括以太坊虛擬機的具體設計。這是一份難得的、經過實踐檢驗的高質量技術文檔,對學習以太坊,乃至其他區塊鏈技術都有很高的參考價值。同時《以太坊黃皮書》也是所有以太坊客戶端的理論和實現基礎。目前業內幾乎所有智能合約平臺都或多或少地“借鑒”了《以太坊黃皮書》中的設計。
筆者從2018年4月下旬開始對《以太坊黃皮書》的中文版(最初由猿哥和高天露譯)的全文進行獨立的校訂和增補更新(結合英文拜占庭版本的更新,也沒有用翻譯軟件),到5月初最終完成。至此,結合Solidity文檔中的相關細節,可以說筆者已經掌握了與以太坊協議以及Solidity智能合約開發相關的方方面面的知識。在開始寫作本書的時候,筆者已經對以太坊協議和智能合約技術有了很深的理解。
本書主要內容
本書分為四大部分。
第一部分為準備篇,簡單地介紹了以太坊及其相關基本概念,并講解了以太坊的基本交互和基礎工具的使用。
第二部分為基礎篇,詳細講解了智能合約開發語言Solidity的所有語法和編寫合約的基本方法,同時也介紹了對編譯器的使用以及Solidity集成開發工具的使用。
第三部分為進階篇,詳細講解了以太坊協議的細節和以太坊協議的核心——以太坊虛擬機的實現原理和相關設計;講解了用于以太坊虛擬機函數調用的應用二進制編碼的細節;對目前最有價值的公共基礎合約庫OpenZeppelin-Solidity的所有源碼進行了詳細解讀;為智能合約安全開發提供了經驗性的詳細指南。
第四部分為實戰篇,結合若干DApp實例,講解了如何基于智能合約來構造可用的去中心化應用程序。
附錄中則包含了對以太坊協議中涉及的部分基礎算法、以太坊虛擬機的費用設計和指令設計的介紹,以及對Solidity內聯匯編的簡單介紹,可以作為我們進行智能合約開發的參考資料。
如果你是一名了解以太坊基礎知識和相關工具使用方法的開發者,那么可以直接從第二或第三部分開始學習。但如果你是一名初學者,或者對以太坊的基本概念和工具還沒有了解,請按照本書編排的順序從第1章開始學習。
本書嘗試實現的目標
本書將嘗試引導智能合約開發者深入理解下面的一些問題。
(1)認識到Solidity并不簡單
Solidity是一種結合了C++、Python和JavaScript語言創造出來的為智能合約開發而定制的語言,它在事實上簡化了智能合約的開發,是一種上手很容易、對初學者“很友好的”開發語言。只要用戶稍有編程經驗,就可以很快寫出一些簡單的智能合約。
不過,這種看起來“很簡單的”語言,其實并不簡單,因為有太多不那么直觀的因素會影響Solidity程序的運行;而大部分開發者也許并不那么理解智能合約的運行環境——以太坊虛擬機(EVM)——其中存在各種各樣的技術細節和各種各樣的“大坑小坑”。比如,private函數和public函數在調用時到底有什么不同?僅僅是可見性嗎?比如,數據在內存和存儲中的結構有什么區別?為什么可以對存儲中的動態數組使用push和pop,而對內存中的就不行?比如,fallback函數是如何運作的?它真的不能接收參數,也不能有返回值嗎?比如,transfer、send和帶value的call有什么區別?又比如,EVM中復雜的費用設計(尤其是存儲的使用費)和gas返還機制是如何影響合約的gas消耗(也就是運行費用)的?
顯然,這些問題并不是我們學習傳統的編程語言就可以了解到的,所以對于大多數初學者來講,這些細節很可能會妨礙他們真正掌握合約開發或者影響他們處理一些相對復雜的邏輯的能力。所以讓智能合約開發者真正搞懂Solidity與其他開發語言的區別是首要工作。
(2)不要重復造輪子
與我們在其他所謂傳統軟件開發中看到的工程特性一樣,在智能合約開發中同樣存在“重復造輪子”的問題。同樣的基礎功能或者非常接近的基礎功能,被程序員反復編寫,犯各種各樣的小錯誤,這種情況在智能合約開發的初學者中同樣普遍存在。那么有沒有已經被證明是很好用的、很安全的“輪子”呢?這也是筆者希望給智能合約開發者講解和普及的一個重要內容。因為筆者從剛剛入行時就非常重視可復用的代碼和設計模式,所以學會使用那些經過反復審計的、反復優化的可復用代碼,在筆者看來也是非常重要的。
(3)智能合約并非絕對安全
這個問題的答案已經眾所周知。其實自以太坊誕生以來,各種各樣的合約漏洞、安全問題已經多次出現在技術社區,乃至公眾視野中。所以合約安全問題早已不是小眾的話題。筆者認真搜集并整理了目前智能合約開發中已知的幾乎所有合約級別的漏洞或者可能遭受的攻擊,希望廣大的合約開發者能真正理解這些問題產生的原因并知道相應規避方法。這無論是對開發者本身還是對實際業務安全都極其關鍵。
(4)智能合約開發離不開軟件工程
任何軟件項目都脫離不了軟件工程上的一些基礎理論和最佳實踐,智能合約開發也不例外。當然,因為智能合約運行環境的特殊性,智能合約開發項目從工程特點上講與傳統軟件工程有很大區別。最主要的就是智能合約代碼一旦部署就無法更改了,這使我們已經習以為常的冷熱修補式的工程實踐再無應用可能。我們必須要結合智能合約本身的特性來安排工程活動。筆者也將結合自己15年以上的工程經驗和對智能合約開發的深入理解為智能合約開發者講解智能合約開發項目中需要注意的方方面面。
(5)本書中還有什么
在以太坊協議中,智能合約的本質就是EVM字節碼加上合約狀態數據所組成的所謂“自主對象(autonomous object)”。所以,內聯匯編是我們的終極武器。了解了內聯匯編,就知道了智能合約到底都能做什么,不能做什么;因為不管我們用什么高級語言來寫智能合約,最終都是要反映為EVM字節碼的,也就是EVM匯編指令,它們就是以太坊智能合約的全部能力。同時,了解EVM指令也是進行終極gas優化的基礎。這些相對高級的話題,也是筆者希望能讓更多智能合約開發者了解的。不過這些話題都被編排在附錄中,供學有余力的開發者參考。
(6)寫在最后
與學習其他技術一樣,學習智能合約開發是一個艱苦的、需要積累的過程,沒有人能一夜之間成為專家。筆者只是希望能將自己學習以太坊和智能合約的大部分收獲更快、更有效地傳授給后來者,讓更多同行真正理解和掌握智能合約開發的要點,但這也同樣需要學習者投入一定的時間和精力。
這是一本給那些和筆者一樣關注細節、希望扎扎實實打好基礎、討厭低質量的快餐式學習的同行們打造的,能真正幫助他們提高對智能合約的理解,幫助他們盡快從入門到精通的智能合約開發方面的書。
在開始有寫書念頭的時候,筆者就很幸運地獲得了3位朋友(姜信寶、朱智勝和蓋方宇)的支持,并收到了機械工業出版社華章分社的邀請,于是我們4人開始了本書的編寫工作。編寫工作當然很艱苦,大家都是利用業余時間進行的,所以前后大概經歷了5個月的時間。
我們希望本書為以太坊開發者或希望學習以太坊智能合約開發的開發者提供一套系統的、完整的學習和參考資料,幫助他們快速認識、理解和掌握基于以太坊和Solidity語言來進行智能合約開發,乃至DApp開發的實踐。本書的附錄也可以作為以太坊技術細節的參考手冊。
本書的特色
本書囊括了開發者基于以太坊平臺進行智能合約開發所需要的所有知識細節,由淺入深地講解了以太坊智能合約開發的方方面面。
本書的基礎篇介紹了以太坊智能合約開發語言Solidity的幾乎所有語法和語言特性細節,既可以按編排順序逐步學習,也可以作為工具手冊隨時查閱。而進階篇詳細介紹了以太坊協議和以太坊虛擬機的原理和相關細節,并對大量經過社區設計、優化的合約源代碼進行了詳細解讀,可以幫助開發者在知其然的基礎上知其所以然;同時,進階篇中也包含了對目前已知的所有針對智能合約的攻擊方式的詳細介紹和基于智能合約進行工程實踐的經驗總結,這些都是不可多得的優秀技術資料,有極高的參考價值。
此外,本書的實戰篇中還為開發者提供了完整的DApp開發實例,可以幫助開發者快速上手構建基于以太坊智能合約的新一代去中心化應用程序。
本書的附錄中則包含了對以太坊虛擬機的費用設計、指令設計以及Solidity內聯匯編的介紹,可以作為開發者更深入學習、研究智能合約開發的參考資料。
到本書截稿時,國內還沒有一本同類書籍能夠像本書一樣覆蓋以太坊智能合約開發的幾乎全部細節,并具有同等的講解深度和廣度。
讀者對象
本書內容的安排由淺入深,即使沒有智能合約開發經驗的開發者也可以學習參考。不過,由于本書中并未包括對區塊鏈技術基礎(比如分布式網絡、密碼學等)的詳細介紹,需要讀者對相關基礎知識有一定的了解。
本書適用于以下幾類讀者:
·有高級語言(如C++、Java、Python等)開發經驗的開發者;
·有計算機軟件及相關專業本科及以上學歷,且正在從事軟件開發工作的開發者;
·有計算機軟件及相關專業本科及以上學歷的在校生或應屆畢業生;
·其他有計算機專業基礎知識(如數據結構和算法、分布式網絡、密碼學等),且希望從事智能合約開發的開發者。
勘誤和支持
由于作者們的水平有限,加之編寫時間倉促,書中難免會出現一些錯誤或者不準確的地方,懇請讀者批評指正。為此,筆者特意創建一個在線支持與應急方案的二級站點http://book.blendercn.org。你可以將書中的錯誤發布在Bug勘誤表頁面中,同時如果你遇到任何問題,也可以訪問Q&A頁面,筆者將盡量在線上為你提供最滿意的解答。書中的全部源文件可以從上述二級站點下載,筆者也會將相應的功能更新及時發布出來。如果你有更多的寶貴意見,歡迎發送郵件至郵箱rivers.yang@icloud.com,期待能夠得到你的反饋。
致謝
首先要感謝偉大的Vitalik Buterin和Gavin Wood博士創造了以太坊平臺;感謝來自全世界的開源貢獻者們將以太坊生態發展豐富到目前的狀態;感謝以太坊社區為全球開發者提供的高質量文檔和相關資料。本書是站在巨人的肩膀上完成的。
其次要感謝3位合作者對本書的付出:其中,蓋方宇編寫了第1章、第3章和第5章,朱智勝編寫了第2章和第11章,姜信寶編寫了第6章和第12章。沒有你們的努力,本書是不可能在這么短的時間內完成的。
感謝機械工業出版社華章分社的編輯楊福川和孫海亮,在這近半年的時間中始終支持筆者和3位合作者的編寫工作,你們的鼓勵和幫助使我們能順利完成全部書稿。
最后要感謝筆者的父母和筆者的夫人提供的支持。
謹以本書獻給筆者最親愛的家人,以及所有熱愛開源、熱愛以太坊的朋友們!
楊鎮