智能合约全栈介绍 - 钟文斌 | Jeth 第三期

编者按:本文系 Qtum 的 钟文斌讲师,在由掘金技术社区主办,以太坊社区基金会、以太坊爱好者与 ConsenSys 协办的 《开发者的以太坊入门指南 | Jeth 第三期 - 上海场》 活动上的分享整理。Jeth 是围绕以太坊技术开发主题的系列线下活动。每期 Jeth 会邀请以太坊开发领域的优秀技术团队和工程师在线下分享技术干货。旨在为开发者提供线下技术交流互动机会,帮助开发者成长。前端

欢迎添加稀土君微信:xitujun,回复“以太坊”进群和讲师交流。git

本场分享视频回放连接(B 站)

分享整理传送门

1小时搞明白以太坊 DAPP 开发 - 熊丽兵 | Jeth 第三期github

讲师介绍

钟文斌,本科毕业于上海交通大学,中国科学院硕士,现任 Qtum 量子链中国首席开发工程师,主要负责 Qtum Core 和 Qtum x86 虚拟机等开发,对区块链基本原理有较为深刻理解。在加入 Qtum 以前就任于 SYNOPSYS 任高级研发工程师,有超过四年的大型软件开发经验。web

你们好。我是钟文斌,来自 Qtum。为何我能来说以太坊智能合约开发?由于 Qtum 自己是支持以太坊这套虚拟机的,至关于兼容吧,因此咱们也算是有一些了解。

今天我会讲如下几个话题。数据库

首先,为何咱们要智能合约?智能合约到底长什么样?最后咱们说以太坊智能合约全栈走一回。DApp 做为一个 APP,在用户点击那个按键以后,它到底发生了什么?咱们今天都会涉及到。编程

为何要智能合约

智能合约你们应该知道,不管是比特币以太坊仍是不少如今的须要挖矿的链,他们都在进行挖矿这么一个行为。那挖矿是什么?我今天就不作深刻解释了,可是至少你们知道挖矿是很是浪费资源的。后端

那这么浪费资源究竟是为了什么呢?安全

为何咱们好好的跑在服务器上的 app,须要变成 DApp?它实际上是一个社会科技。整个社会之因此存在,是由于人与人之间要协做。在不存在协做的状况下,多是我本身作一个独立开发者,能够作任何事情。当我须要跟个人朋友或者合做伙伴去合做的时候,我就须要互相信任。这些信任是须要成本的,合做的范围越大信任的成本就越高。好比说我和个人亲朋好友合做,那基本上我是很是信任他的。再往大说,咱们要在整个社区合做,好比说整个掘金社区要一块儿作一件事情,咱们可能就须要更大的信任。服务器

这个信任最重要的一点在哪里?就是不要侵犯别人的利益,而且保障本身的利益。熙熙攘攘皆为利益往来,因此没有利益的合做,就不大须要信任,可是最须要信任的地方是哪里?每每就是有利益的地方,有钱的地方。因此不管是社区城市国家,甚至全球都须要这么一种协做。要实现协做就会有成本。微信

区块链能作什么?下降互相伤害的风险,那友谊的小船就不会翻,因此说它就是使可以令人们可以达成信任,也就是说可以在利益上达成一致,你们能够不用担忧别人骗个人钱。

我刚才说,这是一个Social Technology,就是说以前咱们全部人都在基于信任作事情,但实际上信任的门槛是很是高的。刚刚你们都已经互相认识了,可是我想问一下你信任对方吗?这是很是难的。可是你信任你的父母吗?你应该是信任你父母的,这是在长时间的积累下,才有这样一种信任。

因此信任是很难创建的。人们想到法律,用法律来保障人之间的信任,但这远远不够。还有就是咱们一开始是亲友的一些人情,到后面变成市场。咱们一开始的协做多是咱们两我的,最后演变成更多的人参与,就须要更健全的法律。或许咱们能够用智能合约来实现这一切。

这个是以前经合组织发布的,一些国家的政府开销占整个 GDP 的比重。

咱们能够看到这36% 到58% 不等,这是个很是高的一个比例。这些比例在作什么?就是使你们可以协做。也就是说让你们可以信任政府,或者信任这些组织,可以作一些事情。这就是信任的成本。因此智能合约就是,咱们用程序用代码来代替咱们人工实现这些信任,让智能合约做为一个信任和协做的工具

以上就是简单地介绍了一下智能合约作什么,为何咱们须要去挖矿?它其实就是说可以让人创建起信任。

智能合约具体是什么

它说是一种合约,实际上就是一段程序。你们应该知道 AWS LAMBDA。通常咱们去开发一个业务逻辑,在开发业务逻辑的同时,咱们还须要去维护后台的一些服务器,去维持这个业务逻辑。AWS LAMBDA 能够实现这么一个功能,你只须要关注你的业务逻辑,而后你把业务逻辑放到 AWS LAMBDA 这个平台上,以后,用户只要调用这个业务逻辑,他就能够用了。你不用去管这个服务器在哪运行或怎样,最后就是用户用了多少计算能力,他就付多少费。

相似就是这么一个架构。这个其实跟区块链的理念有那么一点像。区块链或者说以太坊,也是这样的一个平台。你只须要关心你智能合约写了什么,但最后它跑在区块链上,你不须要去关心,但每一个用户须要为调用这个智能合约付费。

举例一:计数器

这就是一个智能合约,是一个计数器,你们应该都能看懂。

第一行,是 Solidity 的版本号。Solidity是如今智能合约最主流的一个编程语言。这合约的名字叫 simple counter,就是一个简单的计数器。它很简单,里面有个 counter,有个 function,就是对这个 counter 进行一个加加的操做,好像跟普通的 JS 的程序没什么太大区别。 但实际上智能合约和它有很大的区别。

它在操做的这个 counter,其实是在操做一个数据库。就是说若是是一个类的一个实例,通常是放在内存里面,内存清掉以后,这个 counter 的全部数据都不存在。实际上在这个合约上面,这个 count 是记录在数据库里面的,因此你每进行一次加加,其实是进行了一次读写,对数据库进行了一次读写。它和普通的 JS 稍微有点不同。

举例二:功德香火链

咱们再看一个更好的例子。这个例子是我我的很是喜欢的。

这个叫作功德香火链。这个的需求其实很简单,就是说你捐赠香火,咱们在区块链上给你计一次功德,给你念一句阿弥陀佛。你们感觉一下这佛光。

其实这个例子咱们简化一下,它有三个需求。

首先咱们要初始化,设定这个链上有一个管理员,好比说方丈,方丈管钱。每一个人都应该可以捐赠功德。因此每一个人都要可以捐赠,而且这部分钱只有方丈能够动,不是每一个人均可以取出来的。因此说若是你在刚才说的 AWS LAMBDA 上面去作这样一个东西,是没有人会信任你的。你能够随意改这里面的数据,你也不知道我有没有记你的功德,这钱用在哪你也不清楚。可是智能合约它最厉害的地方就是说它跟钱相关,而且可以让别人相信这个钱没有被乱用,这是怎么作到的呢?待会咱们讲全栈的时候会解释,但如今咱们先来看看这个合约。

这个合约经过刚才需求分析,其实就这么十几行。咱们稍微把它分解来说一讲。首先第一个需求,咱们要设定管理员。 这个就是至关于合约的初始化的一个函数。

这边有两个比较关键的地方,一个就是 msg.sender,至关于当前调用那个合约的用户。你在区块链上放一个合约,每一个人均可以建造一个这样的链,因此你怎么知道这个链是否是某个大师发布的呢?那这个大师要公布一下这个他所建立这个合约的地址。每一个人均可以建立一个不一样地址的合约,可是只有这个大师,他公布的才是你们想要捐赠功德的地方。因此这个 msg.sender 就是当前合约建立者的地址。咱们把建立这个合约的这我的设为 owner,就是管理员。

第二个需求就是每一个人都必须可以捐赠。

有几个比较关键地方,这边有个属性叫 payable,就是说这个合约是能够往里面打钱的。 我刚才说过智能合约最厉害的地方就是它能够管钱,因此你能够经过设置 payable 的属性,往这个 function 里面打以太坊。这个 msg.sender 就跟刚才不同了,他固然仍是调用合约的这我的,但如今是调用合约的人就变成了捐赠者,他往里面捐钱,而后他会作一个 assert,说你捐赠的金额必须大于0.001以太,否则就不够香火钱。你敬赠完以后,若是知足条件,那我就给你念一下阿弥陀佛,而后给你记录一条日志,你们均可以在链上看到你捐了钱,你被念了一句阿弥陀佛。

最后一个需求是说只有方丈能够取钱。

这边有一个 require,当前调用 withdraw 这个 function 的人必须是管理员。咱们一开始建立合约的时候就建立了管理员,就是这个方丈。一旦认证经过,方丈就能够取这么多的钱到某个帐户。这边还能够再插入一个日志,好比说去翻新佛像,相似这样的事情。这就是一个很是简单的智能合约的例子,它与普通的 APP 不一样之处就在于它全部东西都记录在区块链上,它是公开透明的,你们能够验证这个合约确实存在。并且你能够看到往里面打的每一笔钱,任何人都没有办法修改,包括这个 owner,他只能提款,他也不能修改里面发生的全部转帐的行为。

EVM 平台的特性

咱们还回到这个智能合约这个东西。咱们刚才讲到都是跑在以太坊上的智能合约,以太坊的虚拟机就是智能合约的执行环境,叫 EVM,Ethereum Virtual Machine。它有一些什么特性呢?

一是调用合约由用户承担计算费用。 不管是方丈创造那个合约,仍是你去捐赠,仍是方丈去取钱,它都须要一个叫作 gas 的手续费,这个手续费都是调用合约的人去付。

二就是用户可以彻底掌握这个权限。 你的捐赠行为和方丈的提现行为,都由他们本身控制,经过什么控制?经过客户端的一个签名,你掌握了私钥,你就能够对它进行签名,签名以后服务端去验证,经过以后再在整个区块链网络上去广播,再去验证。因此说每一个人它本身控制了本身全部的权限,不存在说像AWS lambda 同样,你挣的钱就至关于给了这个平台。可是这个是放在一个合约里面,你们都能看到的,都能验证的一个环境里面。

另一点就是性能低下。 以太坊网络其实全球有将近2万个节点,那比特币网络可能有将近1万多个全节点。一个2万多台机器的网络,可能计算功能应该是特别强大的,但实际上并非。它的性能取决于网络上性能最差的那台计算机,为何?由于每一个节点都要重复计算。你对一个合约的调用,每一个节点都须要计算一遍,每一个节点都至关于存储了一份彻底的拷贝,它须要去达成全网的一个共识。这就是为何我可以信任这个网络,由于即便少数的人在做弊,咱们大多数人都还在验证大多数人所认可的事实。因此咱们能够相信比特币或者以太坊这个网络。可是这它的性能实际上是很低下的,由于每一个节点在作的事情实际上是如出一辙。

去中心化平台的缺点

,刚才已经介绍过。

,每一个调用合约的行为,你都须要付 gas。

,就是它性能也不好。

咱们访问一个网页,至关于发出一个网络请求,服务器就把全部信息发给咱们,这个请求很是简单,这个整个交互的过程很是简单,生命周期很是短。可是在以太坊上在比特币上全部的交互都是经过 transaction,交易来完成的。整个交易生命周期很是复杂,还须要通过全部节点的全网验证,并且中间会出现不少各类各样的错误。并且它也没有这种网络请求,也没有可靠的随机源。

最使人发指的一点就是合约一旦部署了是无法更新的。你能够删除某个合约,可是你不能更新。一旦出了 bug,问题会很是严重。普通的软件出了 bug,可能就是一个运营事故。可是以太坊的 bug 出现过几回,都是动辄几千万美金。好比说 Parity 那个事件,它里面的一些合约被删掉,那个钱虽然理论上说没有丢,可是它所在的某个地址上,全部人都没有办法再把这钱取出来,1.5 亿美金就被冻结了。因此说智能合约上的一个小小的瑕疵,均可以形成很是大的金融损失。但这也是它的魅力所在,它可以管钱,它跟钱相关。人之间的共识信任不少是创建在这种利益之上。

去中心化意义何在

按照套路,我如今就要讲它意义何在了,实际上我也还没想清楚。因此说这是抛出来一个开放性的问题。

我刚才已经介绍了去中心化平台大概是什么样子,它的特色是什么,但它的意义何在呢?我不想去评论一些什么,由于整个行业都还在思考。去年的我若是在这个时间点说,我会说它可能会要改变世界,可是今年一年的事情发生下来,去中心化应用这条路,到底最后能不能走通,我我的目前保持观望态度。因此课程咱们还继续讲,可是意义何在,但愿你们听完以后本身去思考。咱们这个世界到底到底需不须要全部东西都是去中心化? 我认为确定不是,我认为多是一个中间状态,但去中心化必定有它的意义所在,至少咱们如今拥有比特币能够不须要一个中心化的机构实现一个全球的那么一个价值流转。至少咱们有以太坊,它使咱们可以在你们互相不认识的状况下,进行 ICO,进行融资,这是一个很是伟大的创举。

DAPP 全栈走一回

咱们刚才说到了智能合约,举了两个例子,那若是它变成一个应用,它最后在链上到底发生了什么呢?咱们再举一个例子。

举例三:简单存储合约

这个是一个很是简单的智能合约,就是一个简单的 set 跟 get ,一个简单的存储,而且得到值的这么一个应用。

一个应用,它自己可能从前端到后端有这么一些东西,因此我待会也会从前端到它怎么进行一个 RPC 调用,怎么样进行 ABI 的编码,合约怎么样运行。而后在 EVM 上是变成怎么样运行的,最后是怎么样放到那个数据库里面。因此这一点从这个一路我都会讲下来。

前端:WEB 2.0 VS WEB 3.0

咱们先来看看,这是 Howard 同窗写的,关于web 2.0 和 web 3.0。

Web 2.0就是如今你们所熟知 Web 的整个框架。那类比于 DApp 的话,咱们暂时把它称为 Web 3.0。

前端 Web 里面多是 HTML 服务,那在 DApp 开发里面,咱们可能就是一个 DApp 或者 Web 3.0,其实没有太大区别。

那刚才说了 Web 2.0 多是网络请求,但在 Web 3.0 里面全部东西都是经过合约,经过 transaction 交易去触发的。

Web 2.0 里面数据的组织方式多是 JSON,在以太坊上多是 ABI 编码

服务器端咱们能够经过这些请求,咱们能够进行一些操做,或者实现一些业务逻辑,那在所谓的 Web 3.0 里面,它其实就是经过智能合约来处理这些业务逻辑。

在 Web 2.0 里面咱们可能会有操做系统,Web 3.0 都是以太坊虚拟机。实际上它是把虚拟机跟操做系统作了一个混合,区分的不是很是的明确,既有虚拟机要作的一些事情,也有操做系统层面的一些事情。

那在 Web 2.0 里面,咱们可能有数据库,在 DApp 开发里面也有数据库,是经过 Merkle Tree 的方式去组织起来的。实际上在以太坊里面合约存储并非 Merkle Tree,是 MPT,Merkle Patricia Tree。咱们能够把它简化成 Merkle Tree,其实指导思想是同样的。

因此前端其实要作的事情很简单,就是展现链上数据,或者是 DApp 的一个入口。

咱们在本地须要作的事情就是签名,全部东西都是一笔交易,你能够在这一笔交易里面发送以太坊,也能够在这笔交易里面去调用合约。

咱们平时可能接触到跟区块链比较相关的一些应用,那大概分为这两类。就是像 coinbase,binance 那些交易所。这个平台实际上并非一个 DApp,虽然它跟区块链相关,处理区块链的一些交易,但实际上它是一个彻底中心化的平台,全部的数据都在他的服务器上面,全部的请求,甚至你的币都是打给他们平台。

另外就是 myetherwallet,imtoken 这种手机端的或者网页端的钱包软件,每一个用户本身可以彻底掌握私钥,不用把钱把以太坊比特币打给任何一个中心机构,用户彻底掌握这笔钱的动向,因此它更像一个去中心化的应用。

前端例子:REMIX IDE

咱们看看这个前端的例子,刚才那个合约你们还记得吗?一个set 一个 get。这个REMIX IDE 上面有一个叫 simple contract 的合约。这合约有两个 function,一个叫get,一个叫set。咱们如今 set 一个666,而后你按下这个按键以后发生了什么呢?

用 RPC 递交事务

它会生成一笔以太坊的交易。比较关键有两个数据,一个是 from,说从哪一个地址调用,一个是 data ,你调用的这个合约里面包含了哪些数据。你按完这个按键以后,你会发现你在以太坊上进行了这么一笔交易。

这个交易 function 是 set,它 set 了一个16进制的值,就是666。这个就是以太坊上一个交易。

用 ABI 编码传递数据

咱们来看一下它传递的参数,咱们刚才看到一大串那个data,它是什么呢?这个 data 的前四个字节,实际上就是选择调用哪个 function。这四个字节是怎么来的?

对 set 这个函数的原型作一个 SHA 的操做,它会变成很长的一串哈希。咱们取前面四个字节做为这个函数的标识。因此你看到 data 的前四个字节就能肯定,我如今调用的是这个 set 函数。后面的这个数据就是咱们要传入的参数,就是666。具体到以太坊的虚拟机怎么处理这么一段东西呢?

EVM 字节码

它能够变成这样一个字节码。最关键的一点是最后它会进行一个 sstore 的操做,它会在某个数据库里面把这东西写进去。咱们把它变成比较好理解一点的伪代码的话就大概这样。

它其实进行了三个东西,头四个字节,我能够肯定我是要跳到哪个函数,而且这个函数传入的参数是第四个字节后的那32个字节,它每一个参数的长度都是固定的32字节。在666读出来以后,这个 set 函数进行的操做就是往一个内存里面写这个值。

数据存储

那写在哪里?它其实是写在一个数据库里面。可是这个数据库会经过 Merkle Tree 的数据结构,反映到区块上面。Merkle Tree 是个二叉树,它全部的节点的值都是下面两个子节点的哈希。因此一旦发生某一个值的改变,整个树相关路径上的哈希都会发生改变,最后的根也会发生改变。这整个树的根的哈希至关于全部这些数据的签名,或者标识。一旦某个数据发生了任何改变,整个 root 哈希也会发生改变。刚才咱们把 666 这个数据写到一个地方,而后这个整个哈希就发生改变,咱们从新计算出一个根哈希的值。这个值就放在区块链上。区块链它每一个区块除了包含全部的交易以外,最重要的一块,它有一个区块头。这个区块头有几个结构,一个是它包含上一个区块的一个哈希值。以此类推,我这个哈希值标识了前面全部的区块全部的交易。若是别人想骗我,说他改变了前面的某一笔交易,那我这个哈希的验证就不会经过,它会被整个区块链网络认出来,说这个是篡改的。咱们之因此说区块链是不可篡改的,就是由于有这样一个结构。

那另一个东西就是咱们刚才说到 Merkle Tree 的根。Merkle Tree 的根就是全部交易的哈希值的一个标识,一旦这些标识被确认以后,这个根也就惟一肯定了。而后这边有个 nounce,就是咱们所谓的挖矿的关键。所谓的挖矿,实际上是在计算符合某一个难度要求的哈希值。为何比特币要去挖矿,首先比特币想实现一个去中心化的网络。在中心化的网络里面,我须要服从一个中心化组织。可是在去中心化的网络里面那我听谁的?我产生一个一个新的区块,我应该服从谁挖出来的那个区块呢?那就让你们一块儿算一个值,这个值是一个哈希值,它没有任何取巧的办法,只能经过增长算力来解决这个问题。把前一个区块的哈希加上这个 Merkle Tree 的这个根,再加上区块头的一些信息,这个 nounce 是惟一能够改变的变量,你经过改变 nounce 从 0 到 一个很是很是大的值,你能够一直在算某个哈希。一旦这个哈希符合某一个难度要求,好比说前面 10 位为零或者 11 位为零,它就至关于知足了全网共识的难度要求。在这个难度要求下,你产生的这个区块就是合法的,你就能够向全网广播。一旦你是全网第一个算出这个哈希值的人,你就成为最新的这个区块生产者,能够得到比特币或者以太坊的奖励,也就是说你挖到矿了。比特币或者以太坊,能够经过这样的方式实现比较分散的分发(假设矿池不存在)。还有就是能够保证随机性。在一个去中心化的、你们谁都不信谁在网络里面,若是某一我的固定去产生区块,他很快就会被攻击好比 DDoS 之类。他一旦不能产生新的区块,整个网络就会瘫痪。经过这个方式能够很是随机的让全部人都有机会生产下一个区块,攻击者彻底没法预测下一个产生区块的是谁,那他就没法去攻破这个网络。 因此说我认为有两点,一就是币的分发,二就是保证随机性。 咱们刚才说到数据库,保存这个数据的 transaction,最后反映到这个 Merkle Tree 上,最终经过一个哈希的方式存在链上。随着这个链愈来愈长,至关于每一个区块都有前面全部链条的证实,它就变成了全网共识,没有人可以改变,也没有人可以去伪造。 这就是为何咱们刚才 set 了一个666,它不会存在某一台服务器上,或者是几台服务器上,或者某我的可以去更改这个666。由于全球一万多个以太坊的节点都在他们本地的数据库上记录了,我这个合约里面这个值就是六六。即便你某几我的想去改他,也不能够打破这个共识。包括刚才那个捐赠功德香火链也同样,全部人都知道了,你这位仁兄是念了五句阿弥陀佛的,这个方丈是取了这笔钱来干吗的。他不会因为任何我的或者少数人的做弊发生任何的改变。

刚才这个过程就是咱们从前端到ip到最后的存储,看了一遍,以太坊上智能合约是怎么样去运行的,它最后到底产生了一个怎样的效果。

新一代智能合约平台

咱们刚才讲到都是围绕以太坊,可是不得不说以太坊的虚拟机并非一个特别好的一个虚拟机,固然它是为了智能合约专门设计的一个将来安全性实验的一个虚拟机。目前以太坊虚拟机还有如下缺点:

  • 只能用 Soidity 语言编程
  • 没有标准库
  • 合约之间的互相调用关系没法预先肯定,没法并行执行一些合约
  • REMIX IDE 编译器过于古老
  • 虚拟机与操做系统不分层
  • 智能合约没法更新

业界有不少人在作新的虚拟机,好比说比较火的 WebAssembly、EOS 他们都在作。能够支持 JS 网络编程。而后好比说 RChain 这个项目,他本身搞了一个 Rholang 就是新的编程语言。 咱们 Qtum 也在作新的虚拟机,是一个 x86 虚拟机。相信你们应该都听过 x86 指令集。基本上咱们如今全部的设备至少是非移动设备,仍是用英特尔的 CPU,他支持的就是这个指令集。大部分编程语言,大部分的工具都可以被编译成 x86 指令集的可执行目标文件。也就是说若是咱们在区块链上支持了这个虚拟机,那目前大部分的主流语言和主流的你们熟悉的工具,就能够直接被拿来使用来编写这个智能合约。因此说可能这个能够给你们带来一些便利,咱们也但愿如此。

还有就是说,以太坊的虚拟机跟操做系统层实际上是混合在一块儿的,这在编程当中可能带来了不少的困扰,因此说咱们会把它进行一个分层的设计。另外整个智能合约它是无法更新的,可是在 Qtum 里面咱们能够作到这一点。就是咱们有一个至关于分布式自治协议,那经过这个协议咱们能够但好比说咱们有一些标准库。那整个业界,固然我这边没有列全,也各类各样的项目都在作这个虚拟机。但不能否认目前这个以太坊仍是最流行或者是最成功的一套虚拟机,也是最成功的一个智能合约运行环境。

我今天分享就到这里。这是咱们GitHub地址:qtumproject,供你们参考。

相关文章
相关标签/搜索