深入以太坊智能合约开发
上QQ阅读APP看书,第一时间看更新

前言

为什么要写这本书

笔者其实并不是开源软件的早期拥趸,而是一名在企业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位合作者的编写工作,你们的鼓励和帮助使我们能顺利完成全部书稿。

最后要感谢笔者的父母和笔者的夫人提供的支持。

谨以本书献给笔者最亲爱的家人,以及所有热爱开源、热爱以太坊的朋友们!

杨镇