00:00
好,那上节课我们已经给大家讲了,就是在JS里面定义一个对应mango里面数据结构的一个产品文件,对吧?然后我们还讲了怎么样去用express起一个server,那这两个基本基础内容我们都已经掌握的话,接下来我们要做的还有一部分,呃,我们还需要去把它确定一下,那就是我们怎么样去触发在mango里边的这种操作,就像我们一开始跟大家说的,我们触发操作的这一个元素是什么呢?是合约里边的事件啊,大家还记得对吧?所以那么大家会会认为就是以太坊里边的事件,它是什么样的一个一个形式呢?它其实就是合约的状态改变的时候,我们让合约里边去触发一个日志记录,然后他的日志记录会通知。
01:00
到订阅它的那些啊,那些节点上去,或者是我们这里边的server,或者是其他的一些东西啊,那所有的编程语言其实都是有这样的一个日志功能的,那大家会发现我们如果要是把这样一个日志数据写到一个文件,或者是写到一个呃数据库里边的话,那我们其实就可以用以太坊里边的这种呃监听事件的这种机制来去实现,所以大家会发现就是在solid里边跟其他的编程语言是一样的,它也是通过呃这样的一个日志系统去实现了一个事件的机制,我们在这里其实要做到,其实要做的很简单,就只是在合约里边加上一部分事件的声明,然后在合适的时候把这样的一个事件啊触发出来就可以了,所以大家就是如果,呃,而且就是说solid里。
02:00
源的这种事事件的机制,它还有另外一个优势是什么呢?就它的日志是可以无限查询的,呃,但大家可以认为它是无限查询的,也就是说因为所有的历史数据全部都存在区块链上,所以如果大家想要去查的话,理论上所有的都查得到啊,即使是我们很很遥远之前的历史也都查得到,很遥远之前的事件也都拿得到啊,所以就是这个时效性上来讲,扫粒体或者说区块链以太坊的这个系统在事件处理上时效性是更好,呃,就是它的处理的时间长度是可以更长更宽的,好,那么我们接下来就把这个要加入到我们的合约里面去了,对吧,好。那这是我们的合约,大家会想到一般我们定义事件的时候,在哪里定义呢?那一般情况就是在前面我们的状态变量定义完成之后,呃,在我们的这个函数开始之前去定义,对吧?所以比如说我们这里就可以直接放在constructor之前,这里我们可以去定义一个event event叫做new product,对吧,就是我们创建一个产品的时候,我们就把它对应的信息要监听出来,然后要插入到猫狗里面去,之后就可以在猫狗里面去查询了,对吧?所以我们这里边其实需要的事件就是产品上架的时候的那个事件,新创建产品的事件,所以是new product,好,那么里边的参数其实就是。
03:51
就是我们在事件里边要去传进去的参数,对吧,那这个参数可能是什么东西呢?大家会想到其实就是我们产品里边的相关的所有的那些产品信息对不对,所以应该有一个。
04:08
呃,那这个大家会想到,其实就是product ID对吧?然后string name,当然就是还会有category对吧?好,这个string应该小写对吧?好,那接下来还有还有是应该叫做image link是吧?咱们上面的大家可以参照我们上面的这些定义对吧?Image link string description link,呃,后面还有什么。后面的那个time我们都是用来表示的,对吧,Option start time unit option and time啊,大家记得就后面我们还有那个start price对吧,这就是把所有的这些东西都定义一遍就完了,然后当然了,就是还有一个参数应该是什么?呃,Statuss,这个应该是我们一上架的时候都是open对吧,这个不需要,那我们还应该有一个是是不是这个,呃,Production啊,呃,这个product connection啊,对,所以那大家注意,我们这里定义product condition的时候,定义的是一个枚举类型product condition对吧?那如果我们要。
05:59
要是定义这样一个事件的时候,是不是不应该用枚举类型去做事件传递对吧?那我们直接枚举类型本身就是一个,其实本质就是一个一个U对吧,整形,所以我们直接传一个就可以了,那这里我们给一个product condition对吧?好,那么把整个的这些东西都传进来就可以了,这里先定义这样一个event,这里的这个网瘾应该是太长了,对吧?
06:30
嗯,这个没关系啊,大家如果想要把它折回来的话,也可以折回来,我们比如说在在这里把它折一下,好,那么接下来大家会发现我们还有一个问题,诶,这里为什么有一个错误啊,这个都是格式上的一些错误啊,这个不影响我们的操作好那么大家会想到我们定义了事件,是不是还得在某个地方把这个事件要对emit出来,对吧?所以大家会想到这个new product是在哪个函数里边去it这样一个事件呢?啊,那它是新创建一个商品,上架商品对吧?肯定就是ADD product to store,所以我们直接在这里加上这个limit new product,呃,大家注意这个it的关键字最好还是要要写上,因为现在的版本大家可能不写it。
07:31
直接去new product,这样调用是可以的,那到5.0之后就不可以了啊,所以大家还是养成好习惯,好new product,然后我们把对应的参数要传传进去,大家会看看到我们定义的这个产品是不是就是上面这些东西啊。所以这是product index,然后name category。呃,这个其实就是都是很枯燥无味的,把这些一长串都写过来就可以了,大家细心一点,不要写错就行,Option time。
08:28
Star price,好,然后我们最后一个大家注意,最后一个应该是,呃,大家注意,我们在上传商品的时候是做了一个强制类型转换,Product product condition,然后转换成了这个枚举类型,对吧?现在我们定义的就是一个U的,是不是就不需要转换,直接把这个传进去就可以了,对,所以这里边直接这个好,这样就完,对吧?好,那么我们的合约已经定义完成,我们的合约更改之后,大家会想到我们是不是应该得重新把它做一下编译啊,啊,这个是必须要做的,对吧?Comp。
09:18
呃,所以大家养成好习惯,就是我们每一次做完合约的更改之后,都要把它实时的做一下编译,呃,在trouble里边的话,这个其实非常简单的啊,好,那么大家看到我们现在已经编译完成好,那么我们在这个合约里边做事件触发的这一个机制就已经定义好了,那接下来我们其实就是要去监听这个事件了,对吧?那怎么样去监听呢?大家一定还记得我们之前是给大家讲过的,呃,在WEB3那一部分里边我们讲过对吧?呃,那在这个,呃,Travel里边,我们travel的这个合约调用的过程当中,其实也是一样,只不过就是travel里边加入了这一个点击deploy的这种用法,对吧?我们拿到合约实例的话,每次都要用这种方式,那拿到合约实例之后,大家就会发现还是一样,我们可以直接定义一个product event,叫做他点new product对吧。
10:18
啊,然后后边就可以跟我们那个传入的参数,比如说from block 0two block let,只要是我们所有历史里边有的这些产品就全部能够查出来,然后大家会看到下边就定义了一个product even的点watch,那这就是我们真正的这个监听事件,对吧?那就一旦有一个新的块触发到这个new product这个事件的话,我们的这个watch就会把它捕捉到,然后进入到这个回调里面来,呃,那我们回调去做什么处理呢?肯定就是还是标准的这种,呃,错误优先的这种回调函数方式,对吧?那先处理这个error,如果有error的话,把它打印出来,Return,如果要是没有error的话,那就把result里边的对应的这个argument拿出来,我们把它save product,那这个函数就得我们到时候再去定义了,对吧?这个same product就不是存到区块链上。
11:18
而是要存到mango里边了,对吧?好,那么接下来我们就做这个存储商品的这部分内容,好那么这一部分内容大家会想到我们肯定是要改哪个文件啊,我们现在文件很多了,对吧,大家会看到我们这个有合约一堆文件,APP这边有index JS,对吧,然后还有一堆这个scripts。那同样这边还有一堆这个,呃,Product,然后c server,我们改哪个。对,大家如果要是呃能够想到的话,应该能想到肯定是改server对不对,我们应该在server这边去做事件的监听。
12:07
呃,因为我们这里的这个事件监听是不是应该跟我们的这个index.gs一点关系都没有啊,因为index.gs是我们的web前端,对吧?你在前端那里那里去做这个事件监听显然是不合适的,我们应该放在web后端对吧?那我们的web后端其实就是这里的server啊,所以我们这里要用这个server去做这件事情,那其实大家会发现我们之前的这个server只是一个例子,对吧?我们把它全删掉好了,接下来我们重新实现一下这个server,那这个server里边我们需要做这样的几件事情,首先,呃,首先我们应该能够定义出来相关的WEB3对象,对吧?然后我们应该能想到我们要启动一个监听的一个进程。
13:00
对吧,就像刚才写的这个,我们定义一个event product event,然后定义出来之后点watch就可以监听了,对不对?在server里边我们要做这件事情,然后大家还会想到我们是不是在server里边应该还要定义跟mango操作相关的一些东西啊,因为我还要往里存,对不对啊,存那个产品信息的时候是要跟mango相关的,好那么接下来我们就把这一部分就是一一实现一下,首先我们最一开始的内容大家会想到我们还是要去处理,大家大家可以先看一下我们这个课件这里的内容啊,首先大家会看到我们这个要改这个server.js对吧,这一部分内容最多,呃,大家会看到这一部分内容里边。最开始这一部分这大家很熟悉对不对?其实这一部分就是我们去定义WEB3跟trouble口相关的那那一部分东西,对吧?呃,前面这就是把这个1COMMERCIAL到Json先拿出来,这就相当于是我们的abi嘛,然后下面就是呃,拿到插口里边这个contract对象,然后去把这个我们的合约合约的抽象对象拿到,对吧?然后之后再点deployed就可以拿到合约实例了。好,那么我们现在就在这里边具体实现一下,呃,我把这个copy一下,这个名字有点长,我们首先定义一下,这个叫e commers store artifacts,就是在这个travel的调用过程当中经常会用到的一个定义,对吧?因为它把里边我们所有的那个Jason文件里边的内容是叫做artifacts的,好,那么它应该是require哪个文件呢?我们require的是那个Jason文件对吧。
14:52
大家应该记得我们是在build的文件下,对不对,然后coms,然后我们那个名字叫什么来着,Copy一下吧,In commer store.jason好,那么大家会发现,呃,我们这样的话就已经拿到了这个合约编译出来的Jason对象,然后我们定义一个contract require travel contract对吧?啊,这都是常见的这种用法,然后另一个WEB3,那WEB3要require web3对吧?然后接下来我们会比方说定义一个,我们定义一个provider,对吧。
15:52
在trouble里边我们已经这么写,写了好多次了,Providers.http provider,我们还是localhost起local的8545端口。
16:18
好,那最后大家应该记得我们要定义这个e com store对吧?它等于什么呢?等于用travel的这个contract的方法,然后传进来上面的这个artifacts对吧?然后就定义出了我们的这个抽象方法,然后大家记得在呃,插口里边还得有一个操作是什么呢?是e com store,我们还得set provider,对不对,对,为什么我们要把上面的那个定义出来,是因为还有这么一步,Set provider provider,哎,好,呃,这样几行就把我们整个跟插相关的WEB3定义,然后呃,合约抽象对象的定义全部都已经完成了,那接下来我们就直接可以用这个e com store.deploy就可以拿到它的那个合约实力了,对吧?好,这是我们的,就是之前做的一些准备工作,大家都很熟悉了,然后接下来。
17:18
大家会发现,我们既然想要去操作mango,对吧?那同样我们就还应该定义跟mango相关的一些东西,比如说我们这里先把mongos定义出来,跟我们前面的那个产品文件定义是一样的,对吧,Require mongos。然后mongoose.promise大家还记得吧,我们要把这个全局的promise对象付给他。然后我们定义一个。
18:00
诶,Model啊,这个product model我们就不用重新定义了,为什么呢?因为我们是不是已经在外面的这个文件里面已经定义好了,是不是点product把它引入进来就可以了啊,大家看一下这个写法对吧?当然大家可以这里写这个product JS对吧,我们这里没有加引号。好,直接引入这个点product就可以了,对吧?啊,直接这是JS里边no node JS里这种引入方法,好,那接下来大家会想到,呃,我们既然已经定义好了models,还有product model也引入进来了,那接下来是不是应该要把他们,呃,我们要建立起跟mongo那边的连接,对吧?我们还不知道连我们的mongo server在哪呢,我们本地,呃,就是上周的时候大家安装了mongo之后,不是自己本地起了一个server吗?然后我们还说mongo的那个连接方式可以写那个,呃,Mango DB对吧,然后后面跟上冒号,然后后面什么对host host nameme对吧,然后端口各种各样的配置,对吧?那这个东西我们在哪里去配呢?呃,所以接下来我们要做这个事情,所以是mongoose.connect大家看到有一个connect对方法。
19:32
对不对,Connect方法里边传入的这个字符串就是我们的mango连接mango DB,然后冒号斜杠对吧,比方说我这里是连的logo host,大家还记得端口吧,27017对不对,然后比如说我直接指定连到哪一个。呃,数据库database,比方说我就叫EBA_D那大家会想到这是不是直接连接上之后,它就会直接use DB,这个E倍D,这个DB啊啊,所以大家会发现这个DB有没有,大家觉得有关系没有,回回忆一下,我们当时在芒果里面操作的时候,即使这个没有,你直接柚子也可以切过去,对吧?所以这个是没影响的,所以我们直接连接就可以了。好,那我们另外再定义一个DB等于mongus.connection。
20:33
好,所以大家会发现,这样就拿到了前面的这个monggo.connect这是去连接我们当前的这个mango server,然后下边这个DB。拿到它的connection,接下来的这个DB就相当于是我们可以直接去做mango操作的那个接口函数就拿到了,好,那这就是mango的一个基本的操作啊,啊,当然我们这里DB可能,呃,就是连接可能会有错误,对吧?所以大家可以去判断一下这个DB里面的错误,比方说有error的话,呃,On error,那么我们可以我们可以打印一句话吧,好,我这里直接把这个copy过来好了,conso.error.find对吧,打印这样一句啊,Mongo DB error,好,大家会看到这就是我们建立一个mongo连接的一个标准的做法,那如果大家用的是不是自己的本地的mango server起的是一个云服务器,呃,或者是大家甚至用的是就是别人提供的这个mongo server这个服务的话,大家只要把这个mongo链链接去改掉就可以了,对吧。
21:47
啊,甚至大家还可以加上那个用户名密码什么的,这种登录方式都是可以的,好,那接下来大家会想到我们应该就还是我们。要去做这个server的一些操作了,对吧?那server的操作的话,之前其实我们已经发现我们server是用express去构建的,那同样啊,这个其实不该删啊,我们现在还是得用得到,我们还得应用这个express,对吧?光这个定义就定义了一长串,那然后我们定义一个APP,它就等于express这个函数的返回,对吧?好,那么接下来大家还记得我们是不是APP就可以listen了,好,Listen一个3000端口,然后我们去给一个返回,那这这里我们就可以直接pencil.log啊,就可以直接打打一个字符串,对吧。
22:58
比方说我们还是打刚才那个叫什么,呃,EBay server started listening port。
23:16
3000对吧?好,那么大家会想到这接下来应该还有app.get对吧?那现在我们可能暂时还用不到,我们先不考虑这个app.get这一部分,那大家会想到我们还应该有一个什么事情呢?我们本来要做的是还要去监听事件对不对?那所以其实大家会想到app.listen这一部分,其实是我们起这个web服务的这一部分内容,那现在我们假如说还不考虑前台去发送HTP请求,让我们的这个后后台server这一端去给他响应的话,那我们其实跟他还没有任何关系,对吧?我们现在真正要的应该是一个什么东西呢?是不是应该要起一个监听服务啊?
24:08
比如说我这里定义一个叫做,呃,叫做product listener listener定义这样一个监听器,呃,我们要说这个new product event listener,我们定义这样的一个监听器,这其实是什么呢?这其实是一个函数,对吧?所以我们接下来在下面把它实现一下,那function a new product。Event listener,然后我们实现一下它的内容,那大家可以想到在这个函数里边,我们直接在note里边就把它提起来了,对吧?那这里边其实我们要做的是不是就是刚才在课件里边大家看到的,我们要去拿到合约对象合合约实例,然后去定义它的那个事件方法对不对,定义出事件来之后,然后事件点watch对不对啊,就是这样的一个过程,所以我们在这里去定义一下吧,E commerce store.deploy的点赞,然后这里边我们就可以直接拿到合约实力对吧?I,然后拿到I之后,我们就可以拿到它的new product。
25:55
这个方法那大家应该能想到,我们这里是不是可以去定义一个product event,然后让它等于i.new product后面的定义我们就跟之前一样就好了,对吧,From block0,然后two block。
26:20
呃,这个我们给一个latest对吧?好,呃,那我们定义出来这一个事件之后,大家会想到是不是接下来就可以,呃,直接在里边。去watch了,点watch对吧?那watch的这个函数大家会应该记得它是一个error优先的一种写法,对不对,Error和result对吧?那首先我们判断一下,如果有error的话,诶,这里面不是这样的写法啊,如果有error的话,我们就把它打印出来,点log error,然后我们只把return就好了,就不需要再去处理了,对不对?那如果说要是没有error的话,是不是就得处理result了啊?所以这里我们要做的是,比方说还是定义一个叫做save product的一个函数,要传进来的内容就是result.argue。
27:38
啊,当然就是这个大家可以发现,就是我们监听事件的时候拿到的那个result里边的结果,他的那个对象,我们去解析一下就知道他要解析什么了,对吧?这里已经告诉大家,就是我们要解析这个arguments这个对象。
我来说两句