00:00
那之前我们DAPP不仅仅是可以用控制台去交互,还有一部分可以说也是很重要的一部分,既然是D,我们要把它的网页要做出来,对吧?我们得写HTML文件,我们得写JS,然后让我们真正的起一个server,然后浏览器上能够访问到它,能够去做一些实际的操作,那这一部分我们怎么做呢?大家来看一下啊,首先控制台交互这个应该在前面了,对吧?好,首先我们的HTML是不会有太大的更改的,对吧?大家可以想到我们的这个页面其实是没有什么,呃,没有什么特别的东西,没有什么就是新加扩充的东西,所以说基本上是没什么区别,但是这里需要注意注意的一个啊,好,我们先打开之前的。大家还有之前的那个index那个那个文件吗?看一下啊,我忘记放在哪里了。
01:06
好,这里我们先退出来。嗯,直接把这个文件copy出来吧,好,大家可以看一下,这是我们之前的这个,就是index这个文件大家还记得,如果大家还记得的话,之前我们这里啊,应该是index.js对吧?因为我们的本身的HTML,这是index.html,然后我们的JS本身写的也是一个index.js,这个大家应该有印象是吧?那我们现在要做的是要把这个改成app.js。诶,这是为什么呢,大家。
02:01
大能知道吗?我们可以在这个文件结构里面再给大家来看一下啊,因为我们所有打包生成的文件最后都要放到这个build下面来,对吧?大家可以看到这个build里边,其实我们最后要的就是一个index.html和一个app.js,那我们本来写的那个文件不是应该叫index.js吗?那为什么现在又要有这么一层呢?呃,这就是因为我们加入了这个外派,对吧,大家还记得吗?今天上午跟大家说wepa会给我们做一个打包的一个管理,他会怎么做呢?Entry,它要把这个index.js输入进来,然后输出的是build文件夹下的一个app.js所以说我们的原文件JS其实还是应该JS,只不过用了外派这个工具之后,它会给我们做一些附加的打包工作,然后做一些压缩,最后输出一个生成一个文件,是这里的app.js大家还记得这个文件是很可读性很差的,对吧?他这是做了各种各样的压缩之后的,所以大家看这个文件就就会看不懂,呃,但是这个东西我们并不关心,Onepa会给我们做好,所以我们在浏览器里边真正要用到的其实是这个文件。
03:29
所以我们在index HTML里面也要写app.js我们的index.js呢是原文件,那这里的app.js相当于是经过我们原文件编译之后的一个东西,大家看这个就有点像字节码了是吧?呃,大家可以简单的理解成这个样样子,所以我们最后在浏览器里边执行的是app.js,所以我们的index.html。啊,当然这还是原来的这个呃文件,所以我们就直接可以把它替换掉了,对吧?直接把它删掉,然后我就把我们之前的这个copy过来,Copy过来之后呢,大家要注意这里是必须是app.js对吧?这里要注意一下,呃,当然这个大家如果要是想敲的话,也可以去手敲啊呃,这个但是我觉得HTML可能没有什么难度,或者说就是就是细心就好了,对吧,大家知道它的框架是什么样的,所以我觉得这个直径copy过来也没有什么问题,呃,好,那接下来我们再看一下还需要注意什么啊呃,这里边还加了两个东西,那这个东西就是简单跟大家说一下就行,我们在这里呢,会再加一个,就是在标题下面把这个address显示出来,所以我们在这里啊。
04:56
我们这里有一个h Hu对吧?在这里加一个加一个div,呃,然后ID等于哎,这里好像已加上了对吧?对,下面已经加上了,所以我这里就就不用再加了,只不过它这个缩进有点问题,好,所以在这里再加上一个div就可以了,那另外还有一个东西是在整个我们的表格下面再显示一个message,就是提示信息对吧,我们当前呃是什么样的一个状态,再去提示一下,那好,这里我也加上了啊,只不过都是这个缩进有点问题,就在这里加上,加上一个这样的div就可以了,好,那么我们现在关键的其实就是我们的这个app.js,那对于我们而言,其实主要是这个index.js对吧?对,所以。
05:56
看一下这个index.js,我们先把它之前的这个可以删掉了,对吧,好,那么大家想想一下,这个index.js其实跟我们之前的应该还是差不太多对吧,那首先同样我们还是呃,这个我们就default。
06:22
As we3,我们把这个WE3先引入进来,对吧?WE3好,然后我们大家注意啊,这个会比较比较特别一点,我们要引入travel里边的一个组件,这个东西它叫做contract,我们直接把这个也是啊,Default as,因为它本身默认的这个default export就是contract,我们把它引入进来之后,还是就是把它叫成一个contract,用在我们这个文件里面,From,呃,这个应该叫tri contract大家看到了对吧?这里面有自动股权,好,那这一个contract的这一个组件就相当于是在窗里面给我们定义好的一个可以。
07:23
直接操作我们当前已经部署的合约的一个组件,所以一定要用,呃,这里的话,因为咱们这里是在浏览器里边去做操作,如果require的话,那是在note里面的一种引用方式,所以这个是咱们在浏览器里面的方式,那当然就是import了,对吧?所以这个两种两种方式要搞清楚啊,尽管都是JS note里边的引用模块的方式,跟浏览器里边JS引用模块的方式是不一样的,浏览器里面都是这这样一个pod的方式,对吧,这个这个之前咱们我是有点找不到,之前咱们那个文件啊,大家应该存着都有看一看之前咱们的JS是怎么写的。
08:11
大家能找到吧,就是咱们之前的这个simple voing的这个这个文件啊,这里是不一样的一点,因为咱们这里就已经不像之前那样,要把地址直接写死在里面,对吧,API写死在里边,插口给我们做了这一切,所以我们只要引入窗口里面的这个拈,然后就可以做一些别的事情了,好,那么接下来我们还要引入什么呢?我们import,我们要把呃,宫廷的Jason文件要引入进来,所以比方说我们叫一个叫一个voing的,在我看一下我们这里定义的是什么东西啊啊,这里定义的是叫voing artifacts,对,在窗户里面它有一个artifact的一个定义,大家还记得就是在我们前面看到他的那个迁移脚本里边会看到他有一个。
09:08
这个是contract啊,大家会看到它的这种引用模式就是artifact.require对吧,所以我们命名的话也尽量跟T里边的命名保持一致。好,JS artif artif from吧,叫好,那么后边我们就要把真正voing的那个Jason文件要引入进来,那我们得看一下那个目录在哪了,对吧?我们当前的目录大家注意index.js是在app.scripts下面,所以它得向上返回两级目录对不对?它向上返回一级,返回到APP下面,再返回一级,才能返回到我们这个根目录下面,对吧?现在我们是要到根目录下边的,呃,应该是build吧,Build下边的contracts。
10:13
下边去找到voting.jason对吧?所以是这样的一个目录,大家看看清楚,好,那我们已经要引用的东西都已经引引入进来了,那我们大家可以看到这两个东西是我们之前没有的,那我们既然要引入窗口的一个contract的模块,然后还要把我们这个voting的这个对象的文件都拿过来,这个里边大家知道就有abi,也有也有自解码,对吧?所以这些东西是都有的,那trouble既然帮我们管理出了它,是不是我们把这个A提供,是不是窗户就知道我们要的是哪个合约了呢?啊,确实是这样的啊,所以我们想要拿到合约实例的时候,我们直接就voting挖一个voting,它就可以直接用我们前面定义好的trouble里面的这个contract的这个模块,然后。
11:13
点啊,Contract直接直接就可以用了啊,然后我们把voting artifacts串进来就可以了,那这样的一个voting对象就相当于是我们的已经定义好的一个合约实例,所以就是这个引用方式比我们之前其实又会简单很多,对吧?啊这这东西就是直接拿来用就可以了,好,那接下来。嗯,我们是不是还得有一个定义来着吧?啊对,我们这里是有一个对应关系,大家还记得吧,Candy有一个对对对应关系,这个我们还是得写进去啊呃,这个里边我就let一个candidates,这是一个哦,这应该是一个对象,对吧。
12:07
他对应的叫candidate one,看你就这个就基本上没什么carry,这个主要是我们在HTML里边定义了这几个ID,叫做CANDIDATE123对吧,然后我们在添加他的内容信息的时候,要利用ID去找到他啊,但是我们的这个候选人的名字是直接hard code写在里,所以我们现在还是直接这么去用啊,然后我们看一下就是这里边我们会怎么去定义这样的一个事情啊,我看一下我们这里是怎么写的。
13:08
嗯。好,大家看这里边我们写的这个方式跟之前就会有一点不一样了,对吧?首先我们还是先写这个,呃,Document ready吧,这个相对来讲应该比较简单一点,对吧?呃,这个document ready呢,就是我们Dollar document,这是我们在整个页面加载好的时候,Document这个对象ready的时候,我们要去做的一个页面渲染,对吧?那里边我们可以定义一个。回调函数,那在这个回调函数里面去做我们相对应的这些需要做的事情,对吧?大家注意看这里我们应该先会去做一个当前浏览器环境的一个判断,这是为什么呢?就是之前给大家说的,我们如果要是在浏览器里边去调用一个,就是引入一个WEB3对象的话,首先应该判断这个浏览器里边是否内嵌了。
14:15
WEB3实例,比如说我们经常用的mala,它其实就会直接给我们的浏览器里面注入一个WEB3的全局对象,对吧?所以我们应该先去检查,如果说已经有WEB3对象的话,那我们就应该用mama的这个WEB3对象,如果没有的话,再用我们本地定义好的这个WEB3,对吧?所以大家还记得我们当时是说过这个对吧,Type of web3,如果他已经定义好的话,也就是不等于on fine。嗯,那么我们就直接可以,呃,我们先这这个这个,至于这些就是警告或者提示什么的,我们先就先先不管对吧,我们先管它这个最核心的东西,我们直接把window.web3就给一个。
15:21
制成我们当前的这个WEB3,因为我们已经有当前的这个WEB3实例了,对吧?WEB3点current provider,大家还记得这个这个参数吗?WEB3下面的current provider就是在我们的浏览器里边,如果已经有的话,浏览器环境里边如果有这样的WEB3对象的话,WEB3点current provider就是能够拿到值的,所以我们这里就相当于把当前window的全局WEB3这个置为我们当前的current provider,这就是这样一个,就是假如说是这个,呃,就是外面我们有ma mask已经提供了这样一个WEB3对象,就是这,那当然else的话。
16:15
呃,如果我们要是在当前没有这样的对象的话,那肯定我们就需要去重新创建一个了,对吧,那就window window点。WE3等于又一个WE3,大家还记得这个怎么样去加那个provider吗?上面我们没有直接写那个provider对吧?之前我们是在上面直接就写,把这一套全写写好了对吧?对,你有WEB3点,应该是we3.provide对吧?点http provider,然后把我们现在设定好的这个local host8545写进去,所以在这样的一个情形下,我们就不用当前浏览器已经有的这个WEB3对象,而是重新去建立一个新的WEB3对象,用到的provider是我们当前的local host8545对吧。
17:30
好,那接下来我们已经有了这个外三对象,这这里为什么会报一个错小括号是吧?好那么接下来大家注意还有一步操作需要怎么样去操作呢?Voting这个对象要去做一个set provider操作,这里需要把它去set一下,然后set的是什么呢?WEB3CURRENT provide要这样去set一下,好那接下来我们去就处理我们的要做的事情了,我们需要把每个人现在的得票数查出来后,后边要显示的那一个表格里边,对吧?所以接下来我们去,呃,先去定义一下当前的这个。
18:30
呃,应该是candidates对吧?Candidates等于先candidates啊,哦,我们已经定义了candidates是吧?看name吧,Names吧,object.kids我们先从前面定义的这个candidate candidate里边把它拿出来,好,那么接下来我们就要去便利括号里面没有啊,I等于零,我们要遍历这个看names了,对吧?
19:10
每一个对应的names我们都要去查一遍,发送一个请求到区块链上,然后把它对应的能够就是查到的当前的得票数都拿出来,然后给到我们就是HTML里边对应的那个ID,好,接下来就是I应该小于can词names点对吧,I加加好,在这个里边怎么样去做呢?那其实就是voting跟我们在那个命令行里边做的应该一样了,对吧?这是travel的这个模式,voting.deploy的点then,好,呃,那么我们这里就拿到这个,我们叫ing instance,对吧?
20:10
好,拿到这个voting instance之后呢,我们就可以直接调用我们的方法,Total是叫for吗?对,Total for。呃,这里好像我们还应该对total vote for,我们就直接应该拿的是candidate names里边的爱对吧,直接把这个内容拿出来,然后去做一个查询,好,然后大家这个如果喜欢这样的那个链式调用的话,其实是可以直接这么去写的,然后我们再去处理它一下,这个时候怎么去处理呢?呃,拿到的这个结果,那么response,对吧。
21:12
我们要处理的时候,是不是就把它写到对应的那一个格子里面去了,所以这个时候就又要用到我们的对Dollar,呃,这个就得用ID去找了,对吧,那要加的这个应该是得到candidates里边对应的那个去拿,对不对candidates。好,这个我定义一个变量吧,这个这个很难受对吧?Let,呃,我们这叫name吧,等于candidate names I,如果我们这里没有把这个name直接弄出来的话,这里我们是不是candidates里面还得再输candidate names I对吧?这个有点麻烦啊,所以我们定义了之后,这里就直接是就可以了,嗯,同样上面这里我们也不用写这么一长串,定义了之后就直接name就可以了。好,呃,那么现在我们是不是要把它HTML内容要写进去,要写的内容其实就是我们这里的结果对吧?啊,当然大家不要忘了to string对吧,拿到的是一个big number,所以我们直接把它to string写出来就可以了。好,这是我们的这一部分,呃,内容好,我们回过头来检查一下。
22:41
应该是没什么问题对吧?好,接下来还有一个,大家记得当时我们还有一个vote的一个按钮,对吧,这个会比较麻烦一点,大家肯定能想到这个vote这个按钮点一下之后,我们需要去真正的发一个请求才可以,大家可以看到这里的这个做法是定义了一个window的全局,全局对象直接定义了这样一个vote for candidate啊,它是等于这样的一个方式。
23:15
所以这个就其实是什么呢?就是相当于我们当时定义那个function。呃,Vote for candidate对吧?因为我们点点击一下那个按钮的时候,是要调用这个vote for candidate方法的,大家还记得吗?那个HTML里面怎么写的?回忆一下啊,这里我们有一个链接形式的按钮,它的on click事件是会触发vote for candidate这个方法的,对不对?所以我们在JS里边也是要好,这里啊也是要定义一个方式叫vote candidate,大家注意这里的写法,这里的写法是相当于定义了一个全局window的一个一个子对象。
24:02
它的这个对象名字叫做VO candidate,而它是什么呢?它是一个方式,就这个就跟我们直接定义一个方式是一样的,对吧,只不过它把它定义成全局的更好用一些,好,那么我们就用这种这种方方式来来去定义一下吧,再学一下这种写法。好,我们还是在上面来写啊。Candidate name好,直接在这里可以写,对吧?Window点呃,这个应该叫小写啊,Vote for candidate是这样的对吧?哎,不是啊,不是window.vote for candidate,我们后面是要让它等于一个函数的,对吧?这个写法大家注意一下啊,那就function。
25:10
呃,里边应该给一个传进来的candidate对不对,好,那么后面就是这样的一个。后面是它的函数体,那大家肯定想到这个函数题里面,我们肯定是要去触发我们的那个,呃,发送投票的那个方法,去调用区块链上发送投票的那个方法,所以同样我们这个时候是要去,呃,这个这个时候是把那个包在了一个try cash里边,对吧,我们学一下这种方法去做做一个错误的处理,那TRY的时候呢,我们肯定就是说要去。呃,大家还记得我们当时是怎么写的吗?一开始我们应该是先要去拿到当前的数量,对吧?我们在做投票的时候,第一步应该是怎么去做的,大家还记得吗?
26:19
呃,如果说大家大家忘记的话,可以回过头去再查一下我们当时的那个就是这个JS文件啊,这个JS可能还稍微有点大,所以大家当时可能如果要不是自己真正的手敲一遍的话,可能会有一点有一点疑惑对吧?好,我们呃来看一眼这边的实现吧。呃,这里上面是先写了一下这个message对吧,就是先让大家看一下,我们前面不是加了一个message那个一个div嘛,这里其实就是先去显示一个,呃,一点击这个按钮按键的时候先去示一个信息,说你确实已经发送了一个这样的一个提交,这个我们先不管啊,我们先看下面基本的东西,基本的东西这里是先要去把这个candidate后面的这个内容是要。
27:16
呃,这个相当于是要清空的对吧,所以大家注意,就是我们一点投票的时候把,大家还记得这个candidate是什么吗?在这个里边,Candidate是我们这里的input对吧。啊,所以这个操作其实是要先把这个input给定的这个东西先清空,所以我们去做一个这样的操作,Dollar加上can点是吧,直接给一个空字符串,就说明是把它清空了对吧?好,那么接下来我们就是投票了,投票的话我们直接就有voting这个对象,然后voting.deployed这还是跟我们之前的那个方式一样,对吧?呃,点deployed点,然后点赞then的话,我们拿到这个VO instance,然后。
28:23
我们可以把它拿出来去用,那么voting instance就可以去发送我们的投票的那个交易了,对吧?发调用我们投票的合约方法,Vote for candidate应该就叫这个名字对吧?好,我们去做投票,那投给谁呢?投给。前面传进来的这个candidate对不对。好。看那大家肯定想到你既然这里要去做这样的一个交易的一个发送,那肯定我后面得有得有回调了,对不对点那。
29:17
呃,我们这里的话就直接拿到这个re,然后再去做一个回调处理,那其实这里边发送的是一个交易,那返回的那个对象,刚才大家看到是一大串对吧?我们这里如果不做别的处理的话,其实也不需要,那其实我们这里主要是要做什么呢?提交交易成功之后,我们其实更重要的是要把我们那个对数量得更新,对吧?所以说这里边其实我们只要是要把我们的那个东西再重新的更新一遍,那呃,这个时候我们看一下应该是怎么实现啊。
30:00
应该是去调这个instance的totalport对吧,跟下面的这个一样,呃,这里大家注意看,它是定义了一个DVIID,然后拿到了我们对应的这个name的上面的这个编号,就candidate几对吧,先拿到这个,然后在里边去把这个DYID对应的这个里边的东西要去做一个写入,所以是这样的一个一个动作,那当然了,这里它是直接就是做了一个return,这就相当于是我们呃,整个这一个点赞的这个函数调用的一个返回值,就是这里的这个点赞的一个返回值对吧?那下面如果要是想做这样的处理的话,我们还可以继续做这样的链式调用,那这里边的话,我们其实可以可以不用再去return了,对吧,我们直接把上面这个拿到写进去就可以。
31:00
Let did等于candidate,应该candidate对吧?Candidate这里的candidate其实是上面的这个name对吧?然后我们从candidates里边对应的candidate name拿到的就是它对应的这个ID对不对?好,先把这个ID先存一下,然后我们直接可以用voting instance调它的total lose for那个方法对不对,Total for。呃,我们这里要的是candidate对吧,还是选这个candidate点来,那这里呢,我们肯定就拿到这个东西之后,我们直接把它to string就可以拿到真正现在的那个数量,对吧?所以我们还是看一下下面怎么写的来着,Dollar对吧?把它写进去,Dollar根据我们当前的这个编号,这个号是did对吧?好点HTML,我们的结果to string把它写进来,这样就把我们表格里边每个人对应的那个投票得票数就及时的更新。
32:48
出来了对吧?所以大家注意一下好,OK,这样的话我们就已经实现了整体的这个功能,当然了,这里既然有TRY的话,那下面还应该catch,对吧?所以我们这里没有他把,呃,就是整个trouble里边给我们包的都可以包成一个promise,那我们都可以用点赞的这种链式调用,后边的返回就已经没有error了,对吧?那error怎么处理呢?所以正常来讲的话,Promise是可以有点点赞点catch的,那我们这里没有点catch去处理,那我们就在外面包一个整体的try catch来做处理,对吧?所以这是这样的一个应用啊,那这里我们把这个error拿到。
33:32
呃,好,我们就直接简单的弹出点log吧,把它打印出来,好,这就是我们完整的这样一个JS的一个视线。
我来说两句