编者按:本文系 登链科技 CTO 的熊丽兵 讲师,在由掘金技术社区主办,以太坊社区基金会、以太坊爱好者与 ConsenSys 协办的 《开发者的以太坊入门指南 | Jeth 第三期 - 上海场》 活动上的分享整理。Jeth 围绕以太坊技术开发主题的系列线下活动。每期 Jeth 会邀请以太坊开发领域的优秀技术团队和工程师在线下分享技术干货。旨在为开发者提供线下技术交流互动机会,帮助开发者成长。html
欢迎添加稀土君微信:xitujun,回复“以太坊”进群和讲师交流。前端
熊丽兵,北京航空航天大学硕士,前后加入创新工场及猎豹移动,全面负责数款千万级用户开发及管理工做,2014年做为技术合伙人参与建立酷吧时代科技。2016年重心投入区块链技术领域,目前在登链科技任 CTO ,是全网访问量最大的区块链技术博客《深刻浅出区块链》博主,对底层公链技术,区块链技术落地都有深刻研究。github
谢谢你们,很高兴可以和你们分享一些知识经验,今天主题就是 《1小时搞明白以太坊 DAPP 开发》, 咱们直接进入主题,先介绍我本身,以前在创业工场、猎豹移动作工程师,而后如今区块链行业瞎折腾。web
这是我分享的内容,第一个先介绍什么是区块链的应用,再简单的实现一个DAPP。小程序
咱们作一个对比,如今咱们先来看一下APP的架构,就是咱们平时接触到的。平时接触的是一个个前端,例如APP、H五、小程序等,这个前端后面通常都会有一个相关的服务器,不论是前端显示的内容或者一些动做,它其实都是会有一些对应的请求发送到服务器里面,而后服务器收到这个请求以后会有一些回应,再发到前端的应用,就是这样一个简单的架构。后端
做为一个去中心化的应用,它的前端表现都是同样的,其实有时候咱们在跟客户作应用时,他说:“咦!你这个看上去好像和咱们看到的应用彻底同样,没什么区别啊。 ”其实实际也是如此,关键他的后端不同。关于这个疑问,咱们有时候会在界面上加一行字,“此数据通过全网同步”,而后他们表示这就是去中心化应用,但其实关键是链接前端的这个后端的节点,它不可是一个服务器,而是后端它连着的一个网络,无论你是链接到任何一个节点,它在理论上都是同样的。数组
实际上你的应用是在一个网络上面,当前端请求发送到后端的时候,后端链接的节点会把这个请求扩散到整个网络。因此只有当真正的请求达到了全网的一个共识以后,它这个请求才算是真正的生效。这就不像你只有一个服务器时的,只能它说了算。服务器
去中心化的交易所和中心化的交易全部什么不同?微信
在中心化的交易所中,你全部的钱都不是在你的钱包里面,而是在中心化交易所的钱包里面,理论上它是能够随心所欲的,可是去中心化它是不同,你的钱是在大家本身的钱包里面的,并且你的全部交易都是通过全网共识的,并非说它本身的节点,因此这个交易是受咱们本身控制的,这就是去中心化的应用和中心化的应用的一个最大的不一样。
在中心化应用里面,一般咱们发送一个请求是能够直接拿到结果,而去中心化应用要通过全网的共识,一般当你前端有一个请求发到节点,节点告诉你,由于我收到这个请求,它并不能立马处理并拿到结果,这也是一个开发去中心化应用里比较大的不一样点,因此若是咱们要想拿到这一个请求的相关状态,通常是经过事件Event。还有一点在去中心化应用里面,一般这个请求叫交易,这个交易和咱们开发普通应用的时候是不一样的,它是通过用户私钥的签名,这些就是几个明显的不一样点。
接下来涉及到具体开发的一个过程,下面图片中展现了 APP 和 DAPP 比较图。
前端部分和客户端部分其实基本上是同样的, 前端用户:通常经过在知道咱们普通开发APP的时候,它是经过一个HTTP的请求发到服务器再清空某转发的话,最后它会调用到对应的后台的程序中;在对应的去中心化中的地位中智能合约大概至关于咱们以前在写普通应用中一个后端的服务程序这样的角色。
不一样点是一般在开发DAPP的时候这个发送请求再也不是HTTP,而是RPC(远程调用)的一种方式,其中这个节点EVM就至关于咱们平时在写DAPP中它的Nginx/Apache这样的一个角色。 智能合约,它实际上是跑在一个节点上,或者说都跑到一个EVM上,固然这个EVM其实它就是在节点上的。
咱们要开发一个去中心化应用最主要作的是三部分 :
前端部分的编写
智能合约部分的编写
前端和智能合约的交互
我要实现这样一个简单的DAPP,它是在区块链上,保存须要名字和年龄,经过这个更新它会把这个内容同步到区块链中。
须要三个部分要写 :
编写智能合约部分,至关于咱们在写后端的服务程序
编写前端的部分,此次展示的是Web形式,其实也有其余形式
实现前端与合约交互
智能合约实际上是以太坊的一个程序,它是代码和数据(状态)的集合。而编写智能合约的语言是Solidity,若是咱们用图中举例,把contract变成一个class,这就和咱们写其余的语言基本上是同样的,就用contract定义hello,用function定义hello这样的一个函数,这个只有一个简单功能,它能够把一个字符串返回出来,这就是一个最简单的合约。
你既然要编写一个合约或程序必然须要用到相关的工具 :
Remix它是编写Solidity的一个IDE,这是一个Web 形式的IDE.
MetaMask钱包,它能够负责帮你把发送的交易作一个签名
Ganache节点,在开发中咱们须要链接到一个节点,若是咱们每次都直接链接到以太坊的节点,这个过程是很是慢的。因此咱们可使用Ganache这样模拟的一个节点,能够方便咱们进行开发
我定义了一个合约,刚刚在前面有提到两个部分,一是保持一个名字,二是保持一个年龄。那么这个合约就有两个变量,这两个变量在智能合约里面它叫作状态变量,它的内容就会存在区块链的网络上,而后由你定义的两个方法,一个叫set,一个叫get,set就是用来设置这两个变量的内容,get是用来获取。
(演示)我如今来教你们合约如何去编译部署
首先打开Remix里面(前面说起的工具中IDE Remix),地址:remix.ethereum.org/ , 如今咱们看到的就是IDE,而后中间是编辑代码的区域,右边这边有Compile它实际上是我这边勾成的,因此它是会自动去部署。部署的时候有一个叫环境的选择,它其实就是关联到MetaMaskq提供的一个环境。
咱们如今来部署一下,它其实也是提交交易的一个过程,因此它会弹出来提示让咱们去付多少钱Gas,而后同时也会完成一个签名的过程。部署好了以后,咱们就能够对合约相应的函数进行调用,而此时合约的编译和部署都已经完成了。而后咱们这边能够设置一个内容,它其实会发起一个交易,因此每次发起一个交易的时候,由于这个交易是用户发起的,因此须要用户的确认,这也是一个签名的过程。如今智能合约部分就写完了,这至关于咱们在写程序的时后端部分。
如今咱们再来看看前端部分, 上图中这个info是由我来显示内容的,两个input是须要用户去输入内容,一个button去更新内容,当用户点击这个button更新的时候,咱们就把数据提交到以太坊的网络中。
须要说起的是潜在部分,有几个关键地方就是引入了几个库,其中一个是web3,它是就是用来和节点进行交互的一个库。而后这部分是咱们须要去编写的,就是和合约进行交互的部分,web3它就是和合约进行交互的。咱们以前有一个RPC,就是从平时咱们写应用的时候是用HTTP请求,可是在咱们编写DAPP的时候,它是RPC的一个请求,其实web3它是对RPC的一个封装。
web3是和以太坊节点交互的一个库,它能够用来获取到节点的状态,还有帐号的信息以及调用创建合约事件等等 。
它也是对RPC的一个封装,它其实有不少个语言的实现,咱们如今要用到的是它的JavaScript版本的实现web3.js,咱们在开发一些其余的,好比说你开发一个安卓的应用,可能就要须要用到web3j,或者是你开发其余的就是非web形式的话,可能就要用到其余版本的封装。
要实现前端和合约的交互,首先咱们须要把这个web3导入进来,以后咱们要对web3作一个初始化。
以后咱们就须要用到合约的一些信息去初始化实例化合约,这有一个叫web3.eth.contract(ABI)就是智能合约提供的一些接口的描述。
在咱们编译智能合约的时候,其实编译器会为咱们生成ABI。咱们编码的时候就能够把这个ABI的信息拷贝出来。咱们在实例化合约的时候须要把这个ABI的信息填入进来,告诉咱们的WEB3要链接的这个合约到底有哪些函数?ABI的大概做用就是这些。
咱们须要链接到的这个合约的地址是什么?这个地址就是咱们在部署以后,它会为咱们生成一个地址,这就是它要关联的哪个合约的地址。咱们这个初始化合约部分就完成了,接着咱们可使用合约的实例去调用合约的相关函数。
咱们能够拿到info,它对应的就是一个合约的实例,达到这个合约的实例以后,就能够用这个实例来调用合约对应的方法,前面说起咱们合约里面有一个set一个get,如今能够经过这个实例来调用get,get它实际上是一个info的过程,因此咱们传播的一个函数,这个函数从这个result里面就能够拿到getinfo里面它返回的结果。
setinfo它有两个参数,一个name和一个get,这个get和set就是对应咱们刚刚编写合约的两个方法。我能够再次打开合约来作一个比对,刚刚咱们的代码里面有个set,一个get。
在web3里面使用实例的话,它就能够来调用到这两个方法,而后我在这个界面的这个app.js里面,咱们在初始化合约以后就会调用这个getinfo,它其实就是经过合约的实例来调用的,由于getinfo返回的是两个内容,另外它在js里面这边就是一个数组了,而后经过 下标result[0] 拿到名字,下标result [1] 拿到年龄,以后就能够把它设置到这个页面上。
Setinfo是当咱们去点击更新按钮以后,它会去调用setinfo。如今咱们其经过这么以上的操做以后,这个最简单的DAPP就已经实现了。
接下来咱们能够来运行一下。
(演示)如今保存以后,这个值就已经拿到了区块链上的信息,其实这个信息就是以前我在部署合约时设置的这两个内容。当咱们的页面关联上对应的合约的地址以及链接到对应的节点,它就能够拿到这个数据。这就是一个最简单的DAPP。但其实这个开发的过程是有点复杂,由于咱们还要去复制它的ABI、节点的信息等,所以有的时候这样的开发过程很是麻烦,但这可让咱们去了解DAPP开发的一个流程。因此实际上在开发的时候,咱们可能须要借助一些其余的一些框架,就是经常使用的两框架是一个Truffle,一个叫Embark。
我这边可使用这个Truffle框架来作个演示,刚刚咱们是在Remix里面作了这样一个编译,其实咱们可使用Truffle来去简化这个过程,这样的话就不用说频繁的去切换这个环境,咱们能够直接在这个里面(演示经过命令行 truffle compile 编译)去完成这个操做。咱们能够直接在这边编译,以后它会在build文件夹下给咱们生成一个对应合约名字的Json文件,这里面就是有ABI的信息。
咱们使用truffle-contract来初始化合约的时候须要用到ABI的信息,而后咱们也一样去再作一个部署,部署以后它也会为咱们在这个编译好的个Json文件里面去生成对应的地址,原来咱们在初始化合约的时候在app.js里面其实须要不少硬编码的一些内容,包括地址以及ABI的信息,可是咱们使用Truffle提供这样的contract的一个抽象的话,就可让咱们免去这些过程。
我这边把index.html里面的这个APP.JS换成另一个app_tf.js,也就是它使用Truffle框架的js在这里面的话,咱们就能够不用硬编码的去去复制ABI或者地址,直接使用经过或获取到它生成的一个中间的文件,节省时间,很方便,经过这种方式来实例化合约。
咱们接下来再来测试一下,由于刚刚咱们在truffle里面从新的去部署了合约,因此如今这个合约的状态是0,由于它默认值是0,而后若是是一个字符串的话,它就是空的一个字符串,咱们随即可以写一个来更新测试一下。由于要提交交易,因此要用户的一个确认。如今这样的一个DAPP就完成了。
代码的地址为: github.com/xilibi2003/…
欢迎你们跟我交流,下面是个人微信,也能够关注登链学院,咱们提供了不少区块链视频课程,谢谢你们!