一個多月沒更新博客了鹅髓,因為我在專心開發(fā)一個智能合約進(jìn)階課程陷寝;現(xiàn)在,這個課程已經(jīng)基本完成星掰,我就以這篇硬廣做個簡單的回顧和總結(jié)吧多望。
我入行做程序員已經(jīng) 17 年了,但這還是我第一次寫文章來給自己做宣傳氢烘。從畢業(yè)開始便斥,我就被不會包裝自己的問題所困擾,不知道如何在陌生人面前(比如面試的時候威始,哈哈)體現(xiàn)自己的水平可能是我這種類型的技術(shù)人員最大的弱點枢纠;我不是什么專家、大咖,更沒有什么 reputation晋渺,我就是個老程序員镰绎;和我相熟的人也許知道我的水平,但不喜社交木西、不愛表現(xiàn)畴栖、不會包裝的問題始終還是在那里。性格上的某些愚笨和遲鈍大概真的很難改變八千。
不過吗讶,凡事都要看兩面。我也相信認(rèn)認(rèn)真真做事的人不會真的沒人賞識恋捆,用心打磨的高質(zhì)量內(nèi)容也不會真的沒有市場照皆,哪怕沒有什么漂亮的包裝。我不敢說自己有匠心沸停,但我做事還是用心的膜毁。
引子 - 做這個課的動因
雖然很早就知道了比特幣,但我個人是 2016 年底才開始學(xué)習(xí)和研究區(qū)塊鏈技術(shù)的愤钾。經(jīng)過了一個月左右的對 fabric 的從入門到放棄(關(guān)于這個話題瘟滨,未來我應(yīng)該會專門寫一篇博客來講),我把精力集中到了以太坊上能颁。從 2017 年 3 月到 10 月的大概 7 個月左右的時間里杂瘸,我用業(yè)余時間翻譯了以太坊官網(wǎng)的 Homestead 文檔,沒有用任何機(jī)器翻譯軟件伙菊,完全是自己讀原文來譯為中文胧沫,很笨對不對?我知道當(dāng)時已經(jīng)有其他人做了中文版占业,但我做這個事的目的還是學(xué)習(xí)绒怨、是積累,這就是我的風(fēng)格谦疾。我從來不認(rèn)為做技術(shù)能速成南蹂,我自己也從來不是那種臨陣磨槍就能考高分的“聰明同學(xué)”,所以我看不起那些不重細(xì)節(jié)念恍、不重積累六剥、不肯花時間打基礎(chǔ)、粗心大意的程序員們峰伙;雖然隨著年齡的增長疗疟,我不會像 20 多歲時那樣輕易表現(xiàn)出來,但心里的感受并沒什么變化瞳氓;我也知道像我這種風(fēng)格的人注定是少數(shù)策彤,也注定是不討喜的。
到 2017 年底的時候,我基本上已經(jīng)知道了以太坊是什么店诗,它能干什么以及它正在干什么裹刮。而后就發(fā)現(xiàn)了目前國內(nèi)文章質(zhì)量最高的中文以太坊社區(qū) Ethfans。我當(dāng)時的想法還是去結(jié)合自己對軟件技術(shù)的理解和積累去做一些高質(zhì)量的翻譯庞瘸、提供一些高質(zhì)量的內(nèi)容捧弃。在今年 3 月份的時候,我很幸運(yùn)的參與了 HiBlock 社區(qū)組織的 Solidity 官方文檔的中譯項目擦囊,后來也成為了管理員违霞,對中譯版做了很多的校訂工作;同時瞬场,我開始學(xué)習(xí)以太坊黃皮書买鸽。2017 年下半年我曾經(jīng)看過黃皮書,但當(dāng)時真的看不懂泌类;半年之后再來看癞谒,感覺就簡單了很多底燎,同時也更深地理解了黃皮書的價值和它開創(chuàng)性的貢獻(xiàn)刃榨,尤其是在看了其他很多所謂“智能合約平臺”的設(shè)計(不對,應(yīng)該說是借鑒双仍,哈哈)之后枢希。
然后我就從今年 4 月下旬開始對黃皮書的中文版(最初由猿哥和高天露中譯)的正文全文進(jìn)行了獨立的校訂和增補(bǔ)更新(結(jié)合英文版拜占庭版本的更新,當(dāng)然朱沃,也沒有用翻譯軟件)苞轿,到 5 月初最終完成。至此逗物,結(jié)合 Solidity 文檔中的相關(guān)細(xì)節(jié)搬卒,我終于覺得自己真正搞懂了以太坊、搞懂了智能合約翎卓。不過契邀,直到現(xiàn)在(8月中旬)我依然沒有看到市面上有其他人在講黃皮書,無論線上還是線下(當(dāng)然我自己簡單講過幾次)失暴。我其實非常奇怪:為什么我認(rèn)為的智能合約開發(fā)的必修基礎(chǔ)課沒有人在講呢坯门?為什么這么有價值的、水平這么高的技術(shù)文檔沒有人在講呢逗扒?那些自己看看社區(qū)文檔就能搞定的東西反而那么多人在講呢古戴?不過,答案其實也很簡單矩肩、很明顯现恼,是不是?
所以,我想我該做一個真正有質(zhì)量的課述暂,給那些和我一樣關(guān)注細(xì)節(jié)痹升、希望扎扎實實打好基礎(chǔ)、討厭低質(zhì)量的快餐式學(xué)習(xí)的同行打造一個能真正幫助他們提高對智能合約的理解畦韭、幫助他們盡快從入門到精通的智能合約開發(fā)進(jìn)階課程疼蛾。
以太坊黃皮書
從課程的內(nèi)容上,我認(rèn)為要理解智能合約艺配,要討論任何高級話題察郁,都必須要首先搞懂黃皮書,因為這是以太坊的基礎(chǔ)转唉,是繞不開的皮钠。如果大家看過 Solidity 文檔,應(yīng)該會發(fā)現(xiàn)有很多技術(shù)細(xì)節(jié)在文檔里都只說了結(jié)果或者效果赠法,但并沒說為什么是這樣麦轰,而這些明顯感覺不解渴的解釋(當(dāng)然,你需要和我一樣不滿足于知其然)砖织,就是需要黃皮書幫我們解惑的款侵。
也許有些朋友還不知道有以太坊黃皮書這么個東西,所以我們首先來看看黃皮書里到底講了什么侧纯。下面是以太坊黃皮書原文的所有章節(jié)目錄:
- Introduction
- The Blockchain Paradigm
- Conventions
- Blocks, State and Transactions
- Gas and Payment
- Transaction Execution
- Contract Creation
- Message Call
- Execution Model
- Blocktree to Blockchain
- Block Finalisation
- Implementing Contracts
- Future Directions
- Conclusion
- Acknowlegements
- Availability
- References
- Appendix A. Terminology
- Appendix B. Recursive Length Prefix
- Appendix C. Hex-Prefix Encoding
- Appendix D. Modified Merkle Patricia Tree
- Appendix E. Precompiled Contracts
- Appendix F. Signing Transactions
- Appendix G. Fee Schedule
- Appendix H. Virtual Machine Specification
- Appendix I. Genesis Block
- Appendix J. Ethash
- Appendix K. Anomalies on the Main Network
- Appendix L. List of mathematical symbolsReferences
現(xiàn)在清楚了吧新锈,以太坊黃皮書是完整的以太坊協(xié)議的技術(shù)說明文檔,包含了所有的設(shè)計細(xì)節(jié)和基礎(chǔ)算法說明眶熬。以太坊黃皮書是世界上第一個智能合約平臺的“技術(shù)細(xì)節(jié)”說明(而不是概念性的“白皮書”)妹笆,并且已經(jīng)被事實證明是有效的、成功的娜氏,它在工程上的意義不言而喻拳缠。(目前絕大多數(shù)的所謂“智能合約平臺”都或多或少地“借鑒了”以太坊黃皮書所提出的設(shè)計,包括現(xiàn)在炒作的如日中天的某智能合約平臺)贸弥。所以窟坐,學(xué)習(xí)以太坊,學(xué)習(xí)茂腥、理解智能合約狸涌,怎么能不學(xué)黃皮書呢?
當(dāng)然最岗,以太坊黃皮書有一定難度(里邊有 300 多個數(shù)學(xué)公式/抽象表示)帕胆,并且語言表述上也非常晦澀般渡,對閱讀者而言是個很大的挑戰(zhàn)懒豹。我有個朋友曾說:“讀黃皮書味如嚼蠟”芙盘,很形象生動,我也很同意脸秽。所以要做進(jìn)階課程儒老,首先要面對的就是如何講解黃皮書。
這個課程的第一部分(兩課時)就是”以太坊黃皮書精簡教程“记餐。我會把黃皮書正文中的重點內(nèi)容完整地呈現(xiàn)給大家驮樊,沒有公式,但所有重要的細(xì)節(jié)都不會遺漏片酝;而在第二課時中囚衔,我還會結(jié)合以太坊客戶端的實現(xiàn),為大家形象地解釋以太坊的執(zhí)行模型(以太坊虛擬機(jī))雕沿。課程的目的是幫學(xué)習(xí)者先從概念上理解黃皮書中最重要的設(shè)計細(xì)節(jié)练湿,提高他們自學(xué)黃皮書的效率和理解程度。
這第一部分的內(nèi)容审轮,也是我個人非常得意的肥哎,是我的特色,目前市面上還找不到同類的疾渣、同等質(zhì)量的內(nèi)容篡诽。
Openzeppelin 源代碼分析
相信已經(jīng)有越來越多的開發(fā)者知道了 openzeppelin-solidity 這個項目,在以太坊生態(tài)中稳衬,這絕對是個偉大的項目霞捡。因為它提供了眾多經(jīng)過社區(qū)反復(fù)審計坐漏、優(yōu)化的薄疚,可復(fù)用的基礎(chǔ)合約模版。這在我看來也是非常非常重要的所謂“最佳實踐”赊琳,因為我從剛剛?cè)胄袝r就非常重視可復(fù)用的代碼和設(shè)計模式街夭。“不要重復(fù)造輪子”躏筏!尤其是那些已經(jīng)被證明很好用的板丽、很安全的“輪子”。
在這個課程的第二部分(兩課時)趁尼,我就將為大家逐一解釋這個項目中的所有合約模版的源代碼埃碱。學(xué)習(xí)這些優(yōu)秀的、經(jīng)過反復(fù)審計的代碼酥泞,對開發(fā)者而言就是一個很大的提高砚殿,讀懂這里邊涉及的諸多經(jīng)典的設(shè)計模式,對開發(fā)者提高編碼水平芝囤、培養(yǎng)良好的編碼習(xí)慣也大有裨益似炎。
雖然在我看來辛萍,這個項目里的大部分合約都不需要特別解釋,但我還是仔細(xì)的為大家整理了一個相對比較優(yōu)化的學(xué)習(xí)順序羡藐,幫助大家快速了解這幾十個基礎(chǔ)合約贩毕。而其中關(guān)于權(quán)限控制、生命周期仆嗦、支付辉阶、懸賞以及 ERC20、Crowdsale瘩扼、ERC721 等合約模版都是非常有實用價值的可復(fù)用代碼睛藻。
智能合約安全開發(fā)指南
智能合約安全的問題是智能合約開發(fā)者必須面對的問題,智能合約開發(fā)也是一個典型的上手容易邢隧、精通難的技術(shù)活兒店印;所以尘执,作為進(jìn)階課程翠拣,這個話題也是必須要來談的。
在這個課程的第三部分(兩課時)里濒旦,我將首先為大家介紹目前所有已知的攻擊(針對 Solidity 智能合約)纫谅,包括重入炫贤、算術(shù)溢出、意外之財付秕、Delegatecall兰珍、默認(rèn)的可見性、隨機(jī)錯覺询吴、外部合約引用掠河、短地址/參數(shù)攻擊、未檢查的返回值猛计、競爭條件/預(yù)先交易唠摹、拒絕服務(wù)、時間戳操縱奉瘤、未初始化的存儲指針勾拉、浮點和數(shù)據(jù)精度、tx.origin 判定盗温;所有這些攻擊都會結(jié)合具體的代碼片段來講解藕赞,以幫助大家理解其中的原理和細(xì)節(jié)。而后卖局,我將介紹智能合約安全編碼的一般原則斧蜕、Solidity 智能合約開發(fā)的最佳實踐、軟件工程上的考量以及一些安全輔助工具吼驶。
智能合約開發(fā)進(jìn)階
課程的第四部分(兩課時)將繼續(xù)深入介紹智能合約開發(fā)的高級話題惩激。在第七課里店煞,我會講解以太坊虛擬機(jī)的費用設(shè)計、指令設(shè)計风钻,簡單地介紹 Solidity 內(nèi)聯(lián)匯編顷蟀,并講解合約 gas 優(yōu)化的基本原則。不管用什么高級語言編寫的智能合約程序骡技,最終都是會被編譯為 EVM 指令的鸣个,最終都會表示為 EVM 字節(jié)碼;所以從本質(zhì)上講布朦,理解 EVM 指令才是智能合約開發(fā)的終極目標(biāo)囤萤,這也需要我們能真正理解 EVM 的棧(stack)、內(nèi)存(memory)是趴、存儲(storage)涛舍、calldata 和 returndata 的結(jié)構(gòu)。
在這個課程的最后一課(第八課)中唆途,我將講解三個程序?qū)嵗阂粋€對基礎(chǔ)排序算法的 gas 優(yōu)化實例富雅、一個針對合約存儲和 gas 返還機(jī)制的代碼優(yōu)化實例以及一個以合約實現(xiàn)的簡化的以太坊協(xié)議模擬器。以此來講解一些 Solidity 智能合約開發(fā)中可能會遇到的比較復(fù)雜的場景以及相應(yīng)的處理實例肛搬。
課程設(shè)計和推進(jìn)計劃
除了以上這些基本課程內(nèi)容以外没佑,我還精心設(shè)計了幾個需要大家真正動手的編程作業(yè);對于初級合約開發(fā)者而言是有一定挑戰(zhàn)的温赔,需要花一些時間和精力才能完成蛤奢,非常有益于開發(fā)經(jīng)驗的積累、提高對合約編程的理解陶贼,同時這些作業(yè)本身也有很高的實用價值啤贩。我也會單獨為大家批改每次的作業(yè),給予相應(yīng)的單獨指導(dǎo)骇窍。
另外瓜晤,在時間安排上锥余,以上這些內(nèi)容會被分?jǐn)偟剿闹艿臅r間里腹纳,相對給學(xué)習(xí)者一個更充足的理解消化時間。即使如此驱犹,考慮到內(nèi)容本身的難度嘲恍,這個課程對于學(xué)習(xí)者來講依然是有非常大的挑戰(zhàn)的。不過就像我剛剛談的那樣雄驹,我不認(rèn)為學(xué)技術(shù)能速成佃牛,對于這個課來講也不例外;我設(shè)計這個課医舆,絕不是想幫大家在短時間成為智能合約“專家”(這也是不可能的)俘侠,也不是簡單地教大家如何做一個 DApp 或者如何發(fā)一個 Token象缀;而是想為那些真正想學(xué)好智能合約開發(fā)的同行“節(jié)省一些自己收集、學(xué)習(xí)相關(guān)知識點的時間”爷速,是想為這些朋友做個領(lǐng)路人央星,幫他們理清脈絡(luò),并提供盡可能多的信息惫东,為未來的學(xué)習(xí)積累打下一個比較好的基礎(chǔ)莉给。
這是一個精心設(shè)計、打磨的包含了非常多技術(shù)細(xì)節(jié)的課程廉沮,需要你耐心地學(xué)習(xí)颓遏、理解和積累,是可以反復(fù)咀嚼消化的滞时;它絕不是那種只需要看一次的實操課或者簡單地對社區(qū)文檔的搬運(yùn)和重復(fù)叁幢。
Solidity 真的簡單嗎?
Solidity 是一種結(jié)合了 C++坪稽、Python 和 Javascript 語言創(chuàng)造出來的為智能合約開發(fā)而定制的語言遥皂,雖然它在設(shè)計時沒有考慮形式化驗證(智能合約的運(yùn)行結(jié)果是依賴于其本身的合約“狀態(tài)”數(shù)據(jù)和區(qū)塊鏈環(huán)境數(shù)據(jù)的,所以最初沒有考慮形式化驗證大概也是可以理解的)刽漂,它的數(shù)據(jù)類型的表現(xiàn)力有限(比如不支持真正的元組類型演训、不支持多維動態(tài)數(shù)據(jù)的序列化等等),但它也確實在事實上簡化了智能合約的開發(fā)贝咙,是一種上手很容易样悟、對初學(xué)者“很友好的”開發(fā)語言,它的技術(shù)價值是不可否認(rèn)的庭猩。
不過窟她,這種看起來“很簡單的”語言,其實并不簡單蔼水,因為有太多不那么直觀的因素會影響 Solidity 程序的運(yùn)行震糖;而大部分開發(fā)者也許并不那么理解智能合約的運(yùn)行環(huán)境——以太坊虛擬機(jī)(EVM)的各種各樣的技術(shù)細(xì)節(jié),各種各樣的大坑小坑趴腋。比如 private 函數(shù)和 public 函數(shù)在調(diào)用時到底有什么不同吊说,僅僅是可見性么?比如數(shù)據(jù)在內(nèi)存和存儲(storage)中的結(jié)構(gòu)有什么區(qū)別优炬,為什么我可以對存儲中的動態(tài)數(shù)組使用 push 和 pop颁井,而對內(nèi)存中的就不行?比如 fallback 函數(shù)是如何運(yùn)作的蠢护,它真的不能接收參數(shù)也不能有返回值么雅宾?比如 transfer、send 和帶 value 的 call 有什么區(qū)別葵硕?又比如 EVM 中復(fù)雜的費用設(shè)計(尤其是存儲的使用費)和 gas 返還機(jī)制是如何影響合約的 gas 消耗(也就是運(yùn)行費用)的眉抬?
如果你不關(guān)心這些細(xì)節(jié)贯吓,那這個課程就不適合你了;這個課程的目的就是要為那些關(guān)心這些細(xì)節(jié)蜀变,想真正搞懂智能合約開發(fā)的朋友講解相關(guān)的原理和語言特性宣决,使他們理解 EVM 的運(yùn)行機(jī)制、了解智能合約代碼的可能漏洞和相關(guān)最佳實踐昏苏、了解合約 gas 優(yōu)化以及如何在合約中處理復(fù)雜的數(shù)據(jù)結(jié)構(gòu)等等尊沸,從而成長為真正“合格的”智能合約開發(fā)者。
寫在最后
這個課程里不會講那些看看社區(qū)文檔就能掌握的基礎(chǔ)語法贤惯、語言特性或者學(xué)過程序設(shè)計的人都應(yīng)該知道的那些基礎(chǔ)知識和基礎(chǔ)算法洼专;課程的重點是幫助大家理解以太坊協(xié)議、理解 EVM 的機(jī)制和 Solidity 的一些高級語言特性或者不容易理解的技術(shù)細(xì)節(jié)孵构。如果基礎(chǔ)知識欠缺太多屁商,你也就很難獲得應(yīng)有的收獲和提高。
在寫這篇硬廣的時候颈墅,這個課程的全部視頻已經(jīng)錄制完成蜡镶,總時長 12 小時左右,每課時大概 90 分鐘恤筛;課程內(nèi)測也已經(jīng)全部結(jié)束官还;從最初的設(shè)計到最終完成總共花費了六周多的時間。盡管有些小的瑕疵毒坛,但總體上講我個人還是非常滿意的望伦。據(jù)我所知,這也是目前國內(nèi)絕無僅有的高質(zhì)量的智能合約開發(fā)進(jìn)階課程(重運(yùn)營模式的線上課程)煎殷。
這是一個為那些和我一樣在意細(xì)節(jié)屯伞、討厭速成的開發(fā)者打造的智能合約開發(fā)進(jìn)階課程,需要時間和精力的投入豪直,當(dāng)然劣摇,還需要一些資金。不過我也相信弓乙,在這個課程中你一定會有收獲末融!