智能合约全栈介绍 - Howard | Jeth 第一期

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

Howard 老师本次分享视频回放(B站数据库

分享整理传送门

以太坊智能合约 + DApp 从入门到上线:来自前端工程师的实战指南 - 王仕军 | Jeth 第一期编程

详解 ERC20 代币及众筹 - 熊丽兵 | Jeth 第一期后端

Howard 是《Deep Dive Into Ethereum Virtual Machine》一书的做者,该书深度剖析了 Solidity 和以太坊的原理。目前,Howard 任 Qtum 量子链 DApp 平台核心工程师,负责开发工具和数据库。Howard 在创业界拥有10年的产品开发经验,而且对构建去中心化产品充满热情。他也是本次活动的出品人。浏览器

你们好,很荣幸今天跟你们分享一下以太坊智能合约的一些开发经验,在开始以前,我今天先给你们先讲一个高层面的介绍,从前端到后端介绍一下以太坊的技术栈;而后以后咱们两位老师会给你们去介绍一些细节。因此个人这场分享只须要你们脑海里有个对以太坊的概念便可,具体细节后面咱们两位老师会给你们更精彩的讲解。安全

我今天就先介绍一下智能合约以及它存在的理由,而后带你们看一下智能合约长什么样子,最后会带你们梳理以太坊的整个架构,从前面面对用户的DApp到后面的存储数据库。服务器

先简单自我介绍一下,我是台湾同胞,目前在大理远程办公。

为何要智能合约

切入主题,为何要有智能合约,挖矿很是的费资源,为何要花这么多的精力这么多的资源在挖矿上面?网络

有位区块链先驱者提了这样一个概念:技术让人跟人之间去协做。咱们我的本身跟本身协做,可是我可能多作一点事情,会找个人朋友找个人亲人去合做,以此让我作更大的事情,这样咱们须要一些合做,我信任个人兄弟,我信任个人同窗这种类型的合做。更多的合做咱们跟以太坊的爱好者咱们掘金的事情咱们互相的爱好及把咱们捆绑在一块儿让咱们作更大的事情,再更大一点在一个城市,这个时候咱们要有法律,咱们须要各类政府部门,机关,就算我不认识你,我不认识买我产品的人,但我能够经过咱们的合约去保证咱们合做的可行性,更大一点就是国家跟国家、国际法院的合做等,这些跨边界的合做是更复杂的体系。人类的文明跟技术是随着这个合做的复杂性而增加的。前端工程师

那为何咱们要有规则呢,信任实际上是很是昂贵的资源,我最信任的人就是个人亲人和个人朋友,尤为是从小一块儿长大的朋友;可是我来到城市、国家这个级别的话,实际上是很难信任一个不认识的人,因此咱们要提升达成合做的可能性,就要下降信任最小的需求。咱们只要经过这个概念下降互相伤害的风险,友谊的小船就不会翻。数据结构

咱们要尽可能的信任别人,他讲这些东西是科技,咱们从人跟人之间的信任上升到法律,因此咱们开始讲法律时就不须要说起信任。从人情到市场,我可能愿意跟人合做,到市场咱们开始讲价格,咱们有价格的协调机制,就不须要讲人情了。咱们点对点的对话,必需要认识你这我的我才有办法跟你协做,多对多的撮合市场机制,这是一个持续演化的过程。

因此咱们开始讲这些事情的时候,会牵扯到社会扩容,社会的扩容是须要成本的,咱们须要有政府,须要有法院,须要有警察机构。上图中咱们能够看到OECD政府的GDP占比是从36%到58%不等。咱们虽然没有买单、没有直接的去支付这些成本,可是实际上这些东西在政府开销上占了很大比重。那区块链作的事情他是由于取代信任的机制,即以计算机替代人工成为核心的概念。因此说智能合约他具体就是一个计算机程序,它来替代靠人工运营的这些机构。

智能合约具体是什么

接下来咱们可看一下智能合约具体是什么东西。第一个例子就是亚马逊的 LAMBDA 服务,LAMBDA一个特性是你在LAMBDA这个平台写程序的时候,你只是去写你的业务逻辑,而这个业务逻辑你直接上传到 LAMBDA 平台上面,好像只是一个服务器的回调。只要有请求进来它就调用这个回调,计算完成后就直接终止了,你要本身去部署一个服务器,没有逻辑。LAMBDA 这个平台让你直接把服务器的这个业务逻辑放在平台上面,彻底不用去管后面对应哪些具体服务器,一有请求进来,并把 LAMBDA 启动,这个跟智能合约的架构很是像。

咱们能够看一个较为简单的例子,这个计数器的业务逻辑很简单,这边有一个COUNT,把它想成数据库里的数据,这个合约有数据也有业务逻辑,这个业务逻辑要作的事情就是把这个数字递增。当外部调用这个递增的时候,它去数据库里面修改这个COUNT这个变量,这个就是你的智能合约,从概念上来说也没有什么,它之因此牛逼是由于咱们用去中心化的网络去赞成了这个数据应该是什么,咱们具体接下来看一个更好的例子。

咱们把这个合约的这些变量理解成一个数据库,咱们可能日常在写一个加法的类型,它只是存在于类型里面,你的倘若死掉了,这个内存就清空了。在智能合约里面,虽然它是变量,可是你是写在链上面,而这个数据库恰巧是特别昂贵的数据库。咱们类比成 Java 的伪代码,咱们会想象后面每个合约它有一个相对应的数据存储,它是一个对象,是一个数据库,在这个方法里面刚才讲了递增的方法,它只是去操做这个数据库,在这个键修改它里面的值,因此你每次去改一个变量实际上是对数据库作一个操做,并且这个操做是特别昂贵的操做,能够给一个概念,普通全部的这些指定是要费用的,普通的一个纸币,好比说加减乘除,大概是2到5个不等,存储的话是2万个,大概算是5000倍的倍增。

咱们看一个更完整的例子,功德香火链,这个例子大概介绍了智能合约很是本质的一个东西。为何要写智能合约,咱们并非只是为了写这个数据,他之因此牛逼是由于他里面有金融属性,你们能够相信你,若是在我本身的亚马逊 LAMBDA 上搞一个功德香火链是没有人相信的,我在数据库里面能够随便修改,但若是咱们改为在智能合约中就变成是一个去中心化、不须要信任的一个程序。

你们来看一下这个东西,有一些需求,他初始化的时候咱们要设定管理员,任何人咱们都容许他捐款,最后要用这个款项的时候咱们容许管理员取款,而后让他写出全部取款他的去处去了哪里。

这个就是咱们整个智能合约的代码,就十几行而已,这上面大概有两点须要留意,有合约属性,拥有者的姓名,咱们会用这个属性来存储他的管理员,咱们控制了管理员权限才能够进行修改。下方分别是捐款和取款的函数,咱们接下来把这两个函数分开讲解。

初始化设定管理员,因此说这边咱们是要把数据存起来,咱们要知道谁是管理员,在建立这个合约的时候它是用一笔交易建立的,即有一个钱包去付钱而后去说这笔交易谁建立的。这里的属性指出当前用户的身份,这一笔交易的操做者以及合约的操做者。咱们这边作的事情很简单,在建立这个合约的时候咱们把当前的操做者存储在这个数据库里面,有了这个东西以后咱们就能够验证正在操做的人是否是管理员。

接下来咱们开始作这个核心的东西,即任何人均可以转款,以后你要作众筹让别人给你转钱,这个东西就涉及到金融的属性了。咱们看到这个函数也是同样,在操做这个把钱的用户,咱们要记下来,也就是要记下这个功德;PAYABLE 它只是通常拿来处理跟金钱相关的东西,这里是处理存进来的钱。这里要有个断言,要确认这笔钱必需要大于0.001,由于我不想要太少,太少就看不上、不想要;最后这边有一个日志,说咱们把这个输出和这个功德记下来,而后保佑发送这个钱的人,这个日志就记在链子上面了。报错是直接退款,他没有知足这一个条件这笔交易就失败了,他捐了钱就打回本来的账号,固然这个真实的合约你会作各类其余的需求,理念上就是你先检查知足了你的需求以后,你再去操做你的业务逻辑,而后最后你就能够输出记录这个事情。我认为比较有意思的事情,这个合约他有一个相对应的账号,这个账号合约有多少钱,你看里面的业务逻辑并无显性的说把这个钱给这个合约,你这个隐性只是说这一笔交易进来了,只喜欢这个逻辑,而后最后就会给这个账号,可是你不须要代码直接说这个事。

接下来看看看管理员取款,咱们这个函数可让管理员指出取钱的数量,这里又有一个断言,咱们在断言里面判断当前操做这一笔交易的人是不是这个合约的拥有者,咱们一开始就要把这个拥有者记录下来,以后的操做中咱们再去验证一下他是不是当初建立合约的人,若是是的话我就给这个用户给他打钱,转给他所要的钱。咱们首先要作一个小测试,假如说这个账号当前有10个以太坊币,而后拥有者试着去取11个以太坊会发生什么事、触发什么条件会报错。假如说它试着转钱,这边是从合约里面把钱转给A,它帐户里面的钱不够多就会报错,同事状态会直接所有回到原来的状态。这个回滚的概念特别的重要,通常你在写程序作一个操做的时候就有一个请求进来了,你对数据库作一个操做,那你报错了,以前的数据库要回滚;以太坊会自动作这个回滚的事情,只要一失败它就立刻回滚。

咱们能够看一下一些平台的特性,过去一般是你本身公司买这个服务器,你们用这个服务是不用钱的;如今是用户承担全部的计算费用,GAS模型去计算,而后很核心的点是用户他掌握了权限,好比说你用支付宝想转账你在支付宝平台上确认这笔账能不能转,那如今用客户端在客户端作了签名,而后服务端说让你转账,他是不会去验证这个客户在终端究竟是谁。还有一点,虽说以太坊或者量子,有着几千几万的节点,其中以太坊是有17000多个节点,看似这17000个节点计算能力还不错,事实上并无。由于每个节点要重复每个计算,计算每个数据,因此当咱们说存储数据库,若是是当成传统数据库来用是不可行的,由于太贵了。

去中心化平台也是有他本身的缺点,他很慢,处理一笔交易要花20秒;其次贵,每一笔交易要花大概0.1或者是0.2美圆,若是你要发一笔比较大的合约就是10美圆到100块人民币左右了。你作应用交易的生命周期极其复杂,这个东西你必需要等他确认,等一次两次三次,而后他可能中间会抛错,各类不一样抛错状况,有多是业务逻辑抛错,也有多是他给的GAS不够,而后跑一半逻辑他没有钱了,就终止了,还有一些其余的在业务上有一些没有办法作,没有网络请求没有随机员,还有你不能更新合约代码,以前出了一些漏洞,有些人写了合约,这个合约被别人删了,而后他不少钱就卡在里面,几千万美金的钱卡在里面。因此说在作的时候就可能须要思考一下我这个东西去中心化有意义吗,究竟是哪些东西值得去中心化。

DAPP全栈走一回

那咱们接下来更深刻的看一下,DApp全栈走一回,咱们用一个简单的例子而后走到最后面的区块链上面存储的数据。这个合约中,我有一个变量,有一个值,而后我惟一要作的事情就是修改这个值或者是读取这个值,这个就是个人一个简单的智能合约。

咱们会从前端开始,咱们看一下从前端再递增RPC,这个是ABI的编码,咱们一下子再展开来讲,这个合约就是他的业务逻辑,EVM最后到区块链存储,咱们一个一个展开来再说。

因此说你能够比较一下WEB 2.0到3.0他们技术站的对比,而后WEB 3.0就在吹牛说WEB3.0技术是同样的,只是换汤不换药,在WEB 2.0咱们作了一个请求,用户按一个钮就产生一个请求,用户按一个钮就产生了一笔交易,会带有必定的金额,这个须要整个网络去确认,而不是单一的服务器去确认,可是在前端是由用户批准交易以后再丢给网络让网络去处理。而后你写后端说我这个请求他里面具体的数据是怎么样的给一些结构,那咱们如今作后台的话经常是用ABI的结构,以太坊这边它相对应的这个数据结构就是叫作ABI编码,传给智能合约的数据就是用ABI编码,在WEB 2.0咱们作服务,后来在WEB 3.0咱们想写智能合约去作这些服务。但操做系统层面在WEB 2.0时是 Windows 这些操做系统,如今的以太坊就是虚拟机,同时也能作一些操做系统方面的处理,好比说存储数据转钱,或者是调用其余合约,这些是用EBM来作的,这些是混合了两个不一样的东西在一块儿,又是虚拟机又是操做系统。最后咱们要存储数据,就是在WEB 2.0文件系统这些去存数据,在WEB 3.0咱们有电子版本控制,你能够有各个版本。

那咱们看看前端,前端要作的事情就是展示链上的数据,重点仍是同样,用户在本地签名以后再把数据提交到链上,这个权利是握在用户的手上,咱们能够比较一下WEB服务和纯客户端的两个概念,你们熟悉这个应用就是币安这种平台作交易,实际上这些不够造成这些权限的控制都在平台手上,像钱包这种东西才是比较正儿八经去中心化,你说了话不算,是用户控制权限。在这两个极端去纠结若是我真的要作一个去中心化应用的话,它的用户体验会不好很难用;好处是中心化的服务,用户体验好且反应快,可是就是出了事的话那你们都一锅掀了,如今是在两个极端里面去纠结怎么作。

咱们看一下前端的例子,这个REMIX IDE,他指向合约,他有两个按钮,一个是GET 的按纽,还有一个是SET的按钮,我要经过调用的方法去改那个值。而后当我按向那个按钮我要去设定666,这个时候他用RPC去递交一个事物,而后在以太坊就是这个RPC的方法,他们的概念是同样的。

因此我调用这个方法从个人钱包去打这个数据,而后咱们以后会把这个数据去展开,它也是一个RPC,这里面的数据传给智能合约的数据,咱们来展开看一下。

我把刚刚那个东西调用到网络上面,我就能够看到这一笔交易,这个就会把交易里面的一些信息显示出来,我花了多少 Gas,而后里面传了一些数据。

咱们看 ABI 的编码,咱们能够拆开两部分,这个 60fe47b1 他也是调用方法,这个是他的方法名而后拼接在一块儿去取这个前面四个字节就是这个方法的选择器,我调调用智能合约的时候前面四个字节指定我要调用哪些方法,后面那些就是我传参,就是用这个编码出来的,虽然666其实只须要2个字节,可是他ABI编码的设计必需要32个字节,因此说这里能够看到他是有必定的浪费的。刚刚传到数据上来以后EVM的节点就会把智能合约的代码加在这个里面去执行,这个是咱们刚刚设定的方法,传值进去进行修改。

咱们能够看一下EVM的字节码,刚刚看到这个是智能合约,这个智能合约最后经过编译器会编译到字节码,他基本上是从上到下一个一个执行的。咱们要关注的是有两个能够关注的,上面这边60fe47b1这个就是咱们选择器,我先判断一下是否是这个方法,是这个方法的话我跳到这边来去继续执行。因此说这个就是咱们SED方法,最下面咱们存储数据了,这点是一个关键点,咱们刚刚是要存到value这个属性,这个属性他能够理解为建值,他直接是映射到0的位置,我用0去存储,最终把这个数据存储到内存里面去,因此说这是整个合约最关键的指令,存储数据。

咱们把刚刚说的那些东西从EVM字节码变成代码,这个是我发的时候他里面会带着一些数据,这个数据就是有一个指令,而后我取前面四个字节这个就是我要选择的方法,若是匹配了这个字节我就跳到tag这边,这边我要取参数,我也是从这里去取,我直接从四个字节之后取32个字节出来,这个就是个人参数,而后最后我把我读出来的参数存到这个位置,这个就是咱们刚刚合约作的事情。

咱们下面分析一下sstore这个指令是在干啥,咱们刚刚作的事情就是把数据存在第一个位置,L1这个位置,这个位置能够是无限多的,我存在这个位置以后他就会更改,其实最上面的这个就是个人版本号,个人版本号他是取这两边的,而后每个节点都同样,这边的 hash 是由下面来更改的,若是我更改了这里面的数据,这边的 hash 会变,而后致使最上面的这个版本号也变了,因此说直接把这个 hash 当成版本号就能够了。若是我去改动这边的数据那经过这个路径去改变最上面的版本,下面这边是我存储数据的地方,我任何地方存储的数据都会影响到最上面的版本号,跟 top 的版本控制有点像。

这边就是咱们存储数据的数据结构,接下来咱们看一下这个数据结构最后是如何融入到链里面去,这个就是我们的区块链,里面会存着版本号,像说你去 GitHub 上面看一个项目,会有历史更新文档,会讲这个版本号修改了什么,这个版本号修改了什么。这个就数据结构相似于一个版本,每一个版本会去记录这一个相对应的版本号是什么,而后从这个版本号能够取出相对版本全部的数据。

再回顾一下刚才提到的,咱们从前端经过RPC,这个是以太坊节点提供的服务,经过到RPC调用这个节点,调用里面的数据是由ABI编码结构化,而后传给合约,合约处理这个数据,最后这个合约是相对应字节码,而后由EVM解析,解析的结果一般就是存出去要么就是给别的账号打钱,大概就是这样。

区块链现状&将来

区块链的现况你们体会一下,有点天下大乱的样子,区块链的新世界,这个是咱们对将来的小展望,如今大概是5000万个用户在炒币,可能将来十年区块链会增加到10亿用户,像手机同样普及。若是这个事成真,每一个人都会有一些数据的资产,变得像手机同样普及,这样的话咱们要讨论。这就牵扯到扩容,扩容的话有几种方案我如今比较看好侧链和跨链的方案,若是咱们要作产品那就考虑说这个到底怎么样作出好的产品给人用,因此说如今不少正在驱动的区块链产品很难用被各类喷;再一个是隐私的问题,区块链就是公开账本,毫无隐私可言。

智能合约发现了不少的问题,智能合约在安全上或者是在可用性上面他学习成本是至关高的,由于它是不一样的平台,所用的编程语言也与其余语言不一样,一切都要从头开始学。如今咱们能够看到一些新一代的智能合约平台能够出现了,像WEB 3.0是在浏览器里面作一个接近底层的版本。因此说咱们能够看到像以太坊生态圈里面truebit在尝试而后像rholang这类项目,它也解决了合约并发的问题,像咱们公司量子我如今作一个虚拟机,这个是模拟了CPU的架构,咱们但愿说经过这个架构能够支持一些比较底层的开发去作智能合约,而后咱们会比较关注像操做系统和虚拟机的分层,如今你去分析EBM的原理,它是字节码,里面会看到一些属于操做系统的的这个指令,它实际上是建在虚拟机里面,这个也是一个技术上的一些问题。刚刚也提到了一个问题,就是智能合约到底能不能更新,应该怎么更新,这也是如今行业里面讨论的问题,咱们会采用一个像DGP这种方式,咱们经过投票去让用户选择这个智能合约应该怎么更新。欢迎你们跟我交流,谢谢你们。

相关文章
相关标签/搜索