00:00
好,接下来大家看我们已经知道了,整个这个拍卖流程分为两个过程,一个出价,一个揭示出价,对吧?这两个流程接下来我们肯定是要用两个函数来实现的,对吧?首先我们先得把相关的数据结构定义出来啊,这个就是以后大家去做产品设计或者说程序流程设计的时候的一个标准的步骤,我们先知道自己的程序是要干什么事情,先明确流程,然后呢,真正写代码的时候先确定数据结构,对吧?先把要用的数据结构确定好,然后接下来我们定义要有哪些函数,具体再把这个函数填充就可以了。好,接下来我们想到我们既然是要去出价,那用户每一次的出价我们是不是都得去去存起来啊,因为到时候你如果不存的话,那到时候揭示出价的时候,你到哪去找这个信息呢?所以在之前我们一定是要把每个。
01:00
用户出价的过程都存起来,好,那么大家可以看到这个其实很很简单,能想到我们用一个结构体就可以表示,对吧?比如定义这样的一个结构体,它里边有什么内容呢?有这个竞价人,然后会有它的这个给哪个产品的竞价product ID得有,对吧?然后还会有value,这个value是什么呢?我们这里不可能铭文存储它的那个竞拍的价格对吧?那个是我们会把它当成一个加密之后的哈希来做存储的,所以我们在这里没有存这个东西,这里的value是什么?是他竞价的时候带过来的那个以态的数量对不对?所以我们这里是要做一个存储的。那另外呃,还有一个就是表示当前的这一个竞价是否已经被揭示了,它应该有一个布尔型的变量,对吧?那大家可能就会想到你如果这么定义的话。那它本身的那个竞价的核心数据去哪儿了呢?它竞价的那个我们是加密之后的,对吧?你这里边根本就没有加密之后那个字符串啊,啊,当然我们可以在这里边再加一个数据,就是把它做个冗余,把它放在这里,有一个加密的字符串,就是包含了自己的竞价的数量和自己的那个加密的密码,对吧?那两个东西合成的那个哈希放在这里也是可以的,但是我们就会想到,其实我们还有另外一种途径,因为这个哈希我们用来是做什么的呢?是在它揭示报价的时候,我们要通过哈希能够找回当时它的报价的这一个结构体,对不对?所以我们肯定需要有一个mapping对象,这个mapping表示什么呢?表示从一个我们加密的那个哈希字符串,到它指向的那一个B的那个竞价。
02:56
这个结构体这样的一个对应关系对不对?所以如果我们把那个竞价的那个哈希字符串当成一个K的话,那我们就不需要在这个值里边再去重复存一遍了,对吧?啊,所以是这样的,当然大家如果想做冗余的话,我们在里边再存一下也可以,但是我们既然是这里把它当K来存,那就没什么问题了啊,所以大家可以想到我们存储的时候,其实是在一个存储了所有竞价这样一个数据结构里边,这样一个mapping里边,把它的那个哈希当成K,然后把对应的这个B的这样一个结构体当成值存进去。
03:41
啊,这也方便之后我们再去查询对吧?揭示报价的时候,我们算出来那个哈希就可以直接找到啊,这是这样的一种设计,那大家可以看到我们对于每个人来说,是不是他都有可能有很多个竞价,很多个报价啊,所以大家就会想到我们其实需要的,那应该还得再报一层,就我们去找的时候,可能是根据每个人来找到它对应的每一个报价,对不对?哎,所以是根据竞价者来的,所以我们又定义了一个mapping,这个mapping是从每个人的地址到它对应的所有竞价的一个一个map,那所有竞价它又是根据什么来存储呢?那K是我们的这个哈希,然后具体的值是我们的结构体这样的一个东西啊,那当然了,就是所有人的竞价。
04:37
这个保存在哪里呢?保存在这个product里边,所以大家就会发现我对应查询产品的时候,你要查哪个产品的定价,就到他对应的这个mapping来找对不对,然后你再根据不同的人去找到这个人对这个产品给出的不同的竞价,然后呢,我们再根据他所有的这种哈希值去找到每一次的竞价啊,这就把我们整个的这个数据都梳理清楚了,好接下来我们就把这一段先敲一遍吧,这个就真正要敲的话是比较简单的啊,但是大家会发现就是关键在于理解好,我们这里还是把这个多空两行,就是看起来整个程序可读性会高一点,对吧。
05:31
好,我们定义一个structure叫做BI,刚才给大家说了,里边会有一个BI对吧,这是它的竞价人,那这个当然BI本身也是一个,相当于是一个,就是大家看到有了下面那个mapping之后,这相当于也是一个冗余的存储,对吧?但是我们会觉得你如果要是单独查询一个竞价的基本数据的时候,那可能这个BI还是需要直接展示出来的,所以我们就直接在这里放在这里,这主要是方便前端展示一下拿数据啊,这样方便。而我们那一个加密之后的字符串呢,前端肯定不会去想要去展示,对吧?所以我们用别的这些键值能把它查出来就可以了。好,除了这个地址之外,还有就是我当前是哪一个产品,对不对,Product ID,这是竞拍人和竞拍的产品,那另外就是单独的这次竞拍的一些数据,那会有一个value对吧。
06:32
这是我们跟着这次竞拍,他带过来的那个押金,那个拍过来的那个以态的数量,好,接下来最后还有一个标志位,我们做一个布尔型的变量,这个reviewed就看是否揭示出来了,对吧?Review这个词是揭示的意思,所以正常来讲,一个报价提交的时候,那这个review的就应该是false。那等到它真正揭示的时候,我们按照这些判定都把它判定准了之后,真正正常揭示之后,把这个支成处对吧,就是这样的一个过程,好那么除了这个B之外,我们在product类型里边还需要去多定义一个mapping,这个mapping是从我们的竞价人到他所对这个产品报的竞价的一个一个映射,对吧?那所以他所报的映射呢,这本身又是可能有很多个映射,对吧?所以我们又是用一个map来存储,为什么要用mapping来存储呢?因为里边我们可以用。
07:42
加密出来的那个哈希作为键值去做很方便的检索,对吧,所以我们不存数组,而是用一个哈希,这里我们用一个BYBY32啊,然后它映射到我们的B的这样的一个结构体数据类型,对不对?好,那么整个的这个东西我们就把它叫做B就好了。
08:08
那这个过程大家就会发现,我们的数据结构定义的其实非常简单,呃,就是代码上看起来非常简单,但事实上这个逻辑还是有点复杂的,对吧?大家把这个地方就是数据结构的定义一定要理清楚,好好想清楚,就是为什么他要这么去定义,就这里的BI32,我们存的是那个哈希,我们利用它来做键值,然后它对应的那个B的数据结构,就是我们具体的每一次竞价的时候的那个数数据,那这样的一个数据放在每个人手里呢?每个人其实对我们的这个一个产品来讲,它是可以无限出价的,对吧?所以说它是要对应到这样的一个mapping的,那对于我们product里边,它又有各种各样的竞价者,所以这又是一个mapping,所以这个数据结构就是一个mapping嵌套。mapping好,这是。
09:08
数据结构,基本数据结构有了之后呢,我们就来看出价了,出价这个过程当中大家看啊,那会想到我们前面已经说了,出价的时候要带什么参数呢?首先你也知道我这是给哪个产品出价对吧?那本身出价人我们mes send这个是可以知道的,出价的金额mes value这个也可以知道,对吧?但是你你说你得除了这两个参数之外,你还得告诉我你是给哪个产品去报价,所以product ID这个不可少,另外还有一个就是你的关键的报价信息,这个我们是做过加密的,所以说我们还得有一个B的字符串,对不对?呃,所以大家就会看到,呃,我们在处理的时候怎么去处理呢?就是定义这样的一个B的函数,把这样的两个数据传进来,注意后边它得是一个payable的函数类型对不对,因为它是要可以接收以态的对吧?好,那么现在我们就来先呃,这。
10:09
你多说一下,就是我们到底怎么样去做这个加密,那那这里边可以给大家就是呃,具体说一下这个过程啊,就是我们直接用S3这个哈希函数,那在这个教案里边给大家推荐的方法呢,是呃,就是用这个e eri JS有这个库里边的函数沙函数,那大家如果要是说。想要按照这个教程里边完全一样的话,大家用这个也是可以,或者大家如果要是嫌麻烦,因为这个这个库大家还得安装对不对,如果要本地没有的话,还得n PM in storem GS u对吧?那如果要是说大家想要简单一些的话,怎么弄呢?呃,大家肯定能想到我们WEB3里边应该就有对应的,就有对应的函数对不对,WE3里边大家会看到是不是就有一个S3函数啊,所以我们直接其实用这个也是可以的啊,WEB3的S3,那么我们去比方说吧,我们把这两个去做一个处理对吧?好,那大家可以看到我们直接就可以得到一串哈希对吧?啊,当然。
11:24
呃,这里的这个煞三看起来好像,呃,我没有做过校验啊,这个是不是就是是不是有问题的一串数,这个没有做过校验,呃,看起来跟这里的这个好像不太一样,所以说大家如果要是就是假如说这里用到的是不同的沙S函数的话,那可能我们后面还会有问题对吧,就我们首先是得保证我们后台的合约里边用到的S3函数跟前台我们用到的这个S3加密的时候得是一样的,这这样才可以,所以说呃,这个大家就是只要我们前后台确保用到的是同样的这个函数就可以了,大家如果愿意的话,我们直接外三点S3也是可以的,好了,那接下来我们就来去把这个B的函数做一个实现好,前面是我们创建这个product的函数,接下来我们就去做这个竞拍了。
12:24
那竞拍的过程当中,首先有两个参数对吧?UN product ID,首先我们要把product ID传进来,另外我们还应该得传一个BITS32的B对吧,我们就叫B吧,就是beat three对不对?我们加密之后的那个哈希好,那么这是一个public类型的函数,注意它是payable对吧?啊,这个一定要注意啊,然后我们可以给它定义一个返回值,是否成功返回一个波尔型的,写错了啊,返回一个布尔型的。
13:10
变量,那么接下来我们就是要做这个具体的竞拍了,对吧?那大家可以想象得到,竞拍的过程当中,我们传入了一个product ID,那是不是我们先得把对应的那个产品找出来啊,然后才能把那个产品里边的那些静态相关的值写进去,对吧?好,那么我们定义一个product。呃,Product,诶,大家想我们之前定义product的时候都是用的memory,那我们现在是用memory还是story呢?大家想一下,就是这里我们定义的时候用哪种数据类型啊,可以对大家说的对啊,可以告诉大家这里用storage,当然默认就是storage对吧,但是我们,呃,如果要是默认不写的话,它会提示一个warning,所以我们最好还是显示的把它写出来,这里为什么要用storage呢?对,大家可以想象到,如果我们这里用storage的话,这里其实是我们直接要用这个product ID要把它取出来了,对吧,我们不是,呃,大家可以看到前面我们这个memory取出来之后,是不是直接把这些我们只是做一个临时变量,直接把它返回去啊。
14:33
啊,所以我们就可以直接是memory,然后这个函数结束之后直接释放就可以了,对吧?那我们在这里的话,大家是不是想到我们根据这个静态的信息是不是还得改这个东西啊,要改的话,那我们是不是就可以建立一个storage队型的,呃类型的这个变量,然后我们指向这个stores,还是跟上面一样,对吧,Product ID in stores store啊,然后我们把product ID传进去。
15:10
后边再去取出来对应的product ID,这样就拿到了对应的在我们状态变量里边的那一个产品,对不对。那这个产品如果我们给到这个storage类型的话。状态变量里面是不是本身它就是storage类型,那再付给一个storage类型的临时变量的话,那其实它是一个指引用,对呃,是一个引用拷贝对不对,它不会直接把它的值全部原封不动拷贝一遍,只是它的一个引用,那所以之后我们改product是不是就相当于把这个状态变量改了。对,所以说这里我们的用途是要改它,所以我们就用一个storage类型的变量指向它,那相当于就是给了它的一个引用对吧?好,我们来看一下,好,他是说报的错,是说没有用到对吧?那这个我们暂时不需要管好,那接下来我们就会想到这个时候我们是不是就要准备要去把它的对应的一些信息写进去了,那写之前呢,我们先得判断一些基本的条件,对吧,比方说require。
16:19
呃,什么呢?那首先大家会想到我们当前,现在你是要去竞价,那我是不是得判断你现在这个竞价是否已经失效了,对吧?所以大家记得我们在。Solid里边有一个关键词叫now,对吧?这个now就是直接获取我们当前系统里面的unit时间戳对吧,Time,所以我们可以直接让它去跟啊,这个可以是大于等于对吧?可以等于大于等于应该是product,是不是至少要比他的start time要要早一点啊对,所以是product option start time对吧?好,那同样你既然是要比start time要迟,那同样就应该比and time就要早,对吧?所以小于等于an time,大家会看到它这里。
17:20
在不停的这个抱包你,它是需要一个error messages的,对吧,那我们在后面还是给个error messages吧,呃。我,我们叫current time吧,不要说闹了,Current time should be,这个应该是later,对吧,Than option,好好,接下来一样的啊,我们给一个这样的错误信息。And time,对吧?好好,那接下来我们继续想,我们还需要有什么样的要求呢?我们在报价的时候还需要有什么样的要求呢?是不是我们之前给的那个以太的数量,呃,就是当前应该是以太的数量,是从这个交易带过来的,我们给的那个。
18:24
以态的数量是不是至少不能比我们的起拍价格少啊,对,这也是一个基本的要求,对吧?这块如果要是比他价格还少的话,你直接把它拒绝就就完了,所以我们这里它带过来的以态数量是什么呢?就是呃,MSG.value对吧,Messages.value那它应该这个应该是直接大于的,你等于其他价格应该是应该不对,对吧,应该product.start price,好,这是我们的一些基本的要求,呃,我们看一下还有别的要求没有啊,好,还有一个要求。
19:07
啊,大家会看到还有一个要求是我们得要求当前他的那个币子,也就是说竞拍的那个信息里边,他的竞拍人还没有,对不对,你如果要是说已经有一个同样的这个竞拍数据来了的话,我们是不是就不应该把它再存起来了?是不是这样,大家想一下,就是说在B子里边,我们是存储了所有的静态信息的,对不对,那也就是说一个人我是可以反复的去提交竞拍信息的,那我上一次报价15美元,那下一次可以报价20美元再提一次,但是你如果说你报价还是15 15美元提过来,那我是不是默认你就不应该这个就不应该成立,对吧?你不能再存一份吧,或者至少说我应该保证你提交过来的这个加密之后的哈希不应该一样,对吧?你这个如果一样的话,我到时候怎么去存呢?我得覆盖你之前的那个信息,所以说我得保证当前他的这个BI是零,好,是这样的一个思路啊,好,我们把这个再去做一个require,呃,所以它的要求是product.beats里边。
20:25
的messages.sender大家记得它本身是一个地址到它里边这个人所有竞拍的一个mapping对吧,所以说我们先message ther拿出来这个人他所有的竞拍的,呃,竞拍的这个数据数据结构对吧?然后它所有的这些be的是be子,是用什么样的东西去做筛选,去做这个索引的呢?是用他的那个哈希值,所以我们把这个B的再传进来,那这样拿出来的就是对应的就是当前他需要查的这个B的的信息,对不对?那这个B的信息里面到底有没有呢?所以我们要求它的点B的要等于零,也就是说当前它的信息不能有。
21:19
如果要已经有的话,那我们认为它其实已经是写入这个对应的东西了,对吧?所以我们就不应该再把它重新写一遍了,好,这个require东西还有点多啊,好,终于require完了,那接下来我们是不是可以把它该写的东西写进去了,对吧?首先大家会想到我们是不是他的信息在这个product.b里边会往里写对不对,就在这个里边对吧?同样还是message send,然后我们就直接把它按照这个哈希写到对应的那个里面去,对不对?那这样的一个B的,它等于什么呢?等于一个B的对象,我们把它做一个。
22:02
做一个赋值,那第一个信息是BI对吧,Be就是3MESSAGES send,好,那第二个信息是什么?第二个信息是product ID,那当然就是传进来的product ID对吧?好,那接下来再一个,那就应该是呃,要传的是value对吧?那同样这个也是通过message.value传进来的,最后还有一个是否已经揭示,那我们是不是初始的时候给false啊,好,这个已经有了对吧?好,接下来product点大家记得我们还有一个投投币子这个属性对吧?那你已经投了票之后啊,这这不是投票了啊,这你已经报了价之后,是不是要加一啊,就跟我们投票是一样的对吧?每一次投票都得加一,好那么如果做完了这些操作的话,直接wait出就。
23:03
可以了,大家可以看到是这样的一个处理流程啊,呃,这里有warning,我们看一下,好,他说的是这个需要一个message error message,对吧,梳理一下吧,我们这个就说,呃,Be should be,那我们就be should be none吧,简单写啊,然后上面这个也给一个信息,就是说value should be larger than price,对吧?好,我们这样就把它写完了,这里报的是什么?嗯,哪个最后一个require。这个require是吧?呃,为什么通过不了,就是觉得他一开始就应该有值是吗?对正常来讲一开始肯定是没值的,对不对,它这个是这个B的,是我们传进来那个加密字符对不对,对它正常来讲,只要他没用同样的这一个字符传过这个交易,那肯定就是空的,所以说肯定默认是零对吧?好,所以这是我们的这个交易。
24:22
好,那接下来我们还是先把它发comp对吧,每次写完之后大家校验一下,不要有错,哎,这个很烦啊,每次他都不显示,大家看到这种不显示的状态,明显就是他没有没有读取出改变,认为没有改变。啊,当然上面这个汪Ning大家会看到,就是它其实是说就是推荐是不要用now这样的一个,一个就是呃,简单的这种时间引用的,对吧,现在都要用那个block的time step,用这种方式去做这个,呃,所以大家可以想象的到,就是now是什么呢?在区块链里边,时间其实就是区块对不对,对,这所有的我们这里边的就是时间其实都是跟着区块相关的,所以这里的now其实是区块那个时间处,所以这里边是不希望直接用这个系统的这种时间去做操作的,我们还是应该跟区块绑定在一起,这里我们就先不改了,就就用这个是没有问题的,好,这里已经编译成功,我们把它做一下migrate,对吧?
25:58
啊,当然这个过程当中,我们把这个migrant之后,其实是没有办法去做校验的,诶这个好像mrant又没有成功是吧?啊那大家可以看到,就是我们这个过程当中,既然没有办法做校验的话,那只要编译通过,那我们就到时候其他的把那个监视报价也写完之后,我们一起来做校验就好了,对吧。
我来说两句