00:00
那接下来我们继续看,竞价已经写完了,那接下来就应该揭示出价了,揭示出价这一块代码还是稍微有点多啊,有点复杂,大家可以瞄一下这个这个代码就也有个二三十行是吧,稍微逻辑看起来好像复杂一点啊,那么大家先梳理一下啊,先梳理一下我们在这样的一个情形当中,如果去揭示出价的时候,可能有哪些场景呢?可能有哪些状况呢?首先比如说。首先我们先想清楚接受出价的时候,用户要提交什么东西对吧?用户提交的肯定就是自己当时报价的时候给的那个数量,还有它的密码,呃,他知道这两个,把这两个给我们,给我们的时候,合约首先要给他,就是我们首先要把这个就是前端了,前端直接给他处理一下,把它做一个沙三,然后相当于是变成我们要的哈希,对吧?那传给后台合约的时候,我们其实就应该是直接拿到哈希就可以了,那拿到哈希之后,我们肯定就要先去判断了,先要根据这个哈希去找对应的那个报价对不对,找那个数据结构,那就首先有可能找不到,找不到的话,那我们就认为,呃,你这个状况就是一个异常,你根本就没有出过价,那怎么可能对吧?这个时候去揭示报价呢,那我们抛一个一场就可以了,那如果说我们能找到这样的一个哈希,大家就会看到,我们就可以查到。
01:33
当时他到底发了多少以太对吧,然后还能知道他现在的那个报价到底是多少,这就有两种情况了,一种情况是他当时的那个报价报价。比我们就是他当时发出来的以太还要多,那这种的话,我们认为你这种是一个无效的一个报价,对吧?因为我这里边没有办法让你再补以太了,我只能从你以太里面扣,所以说这种情况我们认为你这是无效,那我们就把它当时给过来的以太直接给你返回,对吧,我们可以处理这种情况并不报错,那他打过来的以太也不能就丢了嘛,对吧?那另外一种情况,只要你比这个当时发的以太是比报价是要多的,大于等于,那我们认为这就是有效的报价,有效报价就进入我们筛选的这个流程了,对吧?那首先假如说我之前从来都没有报价,你这是我当前的第一个报价,那就没什么好说的,你这个有效报价一定是当前的最高价,对不对,那这个时候写入当前最高价,然后呢,当前的第二高报价是什么呢?因为大家想到第二高报。
02:43
这是最后他如果竞拍成功要支付的那个价格,所以我们这里不能默认的初始我们都给的是零,对吧,大家记得我们初始化那个产品的时候,那几项都给的零,那我们不能给零了,对吧,因为这个时候你到时候那那这个默认的这个数的钱就成了零了,这肯定不行,对,所以大家会想到我们会把初始的那个stock price起拍价给到。
03:11
当前的第二报价。啊,所以是这样的一种处理的模式啊,那呃,然后呢,大家就会想到,如果说不是当前。就是已经就是一个报价都没有,我就是最高报价,如果不是这种情况的话,已经有别人报价了,那我就得跟最高报价去比了,对吧,一比发现如果比最高报价还高。啊,那没什么好说的,把最高报价顶下来,最高报价就变成了第二高报价,对不对啊,那我们当前的报价变成了最高报价,那如果说它比最高报价低的话。那又得分两种情况,因为还有可能它比第二高报价高对不对,如果比第二高报价高的话,就应该把第二高报价顶掉,那如果比第二包报价还低的话,那就没什么好说的,你这个就是一个无效的,对吧,我直接把你发过来的以太给你退回去就完了,那更复杂的情况可能就是说,我们假如说它比最高报价要高,或者说在最高报价和第二高报价之间的时候,给他返回的那个以态数怎么算呢?啊,那这个过程当中就是我们等一下实现的这个过程,我们来看一下具体怎么实现,好,接下来我们就来码代码了。
04:36
呃,揭示初夏这个过程当中,大家会想到就是首先我们肯定还是一上来应该要去做一些各种各样的校验,对吧,好方式,呃,我们这个应该揭示报价就用这个词啊,Review be的吧,首先我们会想到它的输入的是什么呢?你揭示报价是不是还是要先指明我揭示的哪个产品啊,对吧,那这个还是一样的啊,Product ID还是得给过来,另外我要揭示的时候,是不是应该把我当时给的那个金额和我当时的那个密码要传过来啊,所以这两个,呃,当然这里如果要是前台直接传的话,我们一般都是直接传这个就是就是传一个string对吧,前台传的话,我们一般是传string会好一点,所以我们这里就直接定义成string了。
05:37
然后后边还会有一个它的这个amount,我们不要跟前面的变量重了啊,我们加一个下划线,然后我们会定义一个它当时定义好的这个密钥secret,好这样一个函数,那肯定就是一个public类型了,对吧?呃,那大家可以想到这个不光是哦,它就是一个public类型,不应该是那个view对吧?因为揭示报价的时候,我们应该还有可能会改一些数据,对不对,所以是这样的一个状态啊,那同样大家就会想到,我既然传进来的这个,呃,产品的ID我是不是还是跟上面一样,我应该先拿到产品的这个对应的数据啊,Product,等于大家这个就照着抄就可以了,对吧?那上面这个过程就是我们经常会用到in。
06:37
Store,然后后边product ID,然后下划线product ID,好,那有了这个product之后,那么我们就要来判断一些信息了,对吧?首先require require什么呢?呃,我们现在是揭示报价,揭示报价前面我们去做这个要的时候,是不是要求这个时间必须得大于起拍的时间小于等于结束的时间,那我们现在要揭示报价是不是一定得大于。
07:14
这个结束时间啊,对,一定要在结束之后,对吧?Now大于等于,呃,product.option and,好,这是我们的一个要求,然后大家可能,呃,还能想到什么样要求吗?呃,暂时好像想不到这个跟产品相关的一些要求了,对吧?但是可能会想到我们之后应该跟他要揭示的那个报价那个B的里边的一些信息可能会有要求,对吧?所以我们这里要做的是这样啊,我们这里要做的是先要拿到我们的那个B的对不对?我们怎么样去拿到B的呢?大家看一下我们定义的这个B的数据结构,这里边儿我们也没有办法根据B直接去查,我们得用什么去查呢?
08:14
啊,是不是得用啊,得用地址,然后对应的那个哈希去查,所以我们是不是应该先得把这个哈希算出来,因为这里啊,这里没有用,就是在前台把它直接算出来,传过来的方式,我们这里是后台直接拿这个,拿到了这个数,那我们是不是就得后台先做一个哈希把它算出来,所以大家会想到我们来一个bits by by32,然后我们定义一个。呃,叫S就B的对吧,就是加密之后的这个B的,呃,那它用什么来加密呢?那同样还是S3的这个算法对不对啊,当然就是等一下这个肯定也会报警告啊,就是在呃,大家会发现就是在当前的这个solidity里边,其实推荐的不要用S3,其实要用呃,就是CATCH256的对吧?所以我们现在还是用这个S3啊,就是给大家举个例子,大家想要去自己做调整做改变的话,自己去改一改就可以好,那么S3要给定的这个参数是什么呢?就是给amount和我们这里的secret对吧?把这两个参数传进来,去做一个哈希加密运算好了,有了这个运算之后,是不是我们就可以就是拿到这个B的了,好,这个B的我们。
09:42
可能就不需要改对吧,所以我们来一个好,那我们叫一个B的因数啊,product.bs就可以在be子里边查出来了,对吧,那bes里边它是一个mapping,从什么到什么的mapping呢?从一个用户,从一个竞拍者到他所有的。
10:07
竞拍的一个mapping对吧?所以前面是message.sender那他所有的竞拍我们又是做了一个mapping来做查询的,对不对?那它的K用的是不是就是上面的这个我们做哈希运算之后的这个哈希字符串啊,所以把它传进来,我们就拿到了对应的那个B的结构体对吧?B的信息,它的这个竞拍的信息就全拿到了,好,这是我们前面的一些数据的基本的处理啊呃,拿到这个B的信息之后,我就肯定就会想到,那我们就可以去校验一些事情了,对吧?我这里是不是得校验require一下是不是,首先你这个B的iner里边它不是有这个bit吗?之前我们在去往进存东西的时候,要求要求这个B是等于零的,不能有BI,那现在是不是要求bider不能等于零啊,对,所以大家会想到我们这里啊,不用不等于零了,直接大于零好了,因为它肯定这个地址是大于零的对吧?那后面我们给一串这个信息,就是BI的数的exist,好,接下来大家会发现啊,我们除了对这个BI有要求之外,是不是首它还得就首先我们这个BI是有效的对吧,它是这是一个有效的infer,一个一个B的结构体,另外它的还有几项,这product ID value,这个都都不用怎么说对吧,那下面这个reviewed。
11:52
是不是还得要求它得是false啊,不能已经揭示了对吧,所以大家这里面还需要去判断一下B的in.review的等于false,那当然其实大家其实就是另外的那两项,我们是不是在这里也可以去做要求,就是product ID是不是也得等于product ID对吧?这个其实也是可以做要求的,我们这里就先先,因为我们就是根据这个查出来的,我们就不专门去。
12:29
就是要求这个了啊,那value呢,是查出来我们等下要用的value,这个肯定就是没有别的要求的,所以我们这里给就是B的should not be revealed,对吧?好,现在我们前序的这些要求和这些就是这些判断都已经做了,然后我们该拿的数据也都已经拿到了,接下来我们就是需要去处理我们真正的逻辑了,对吧?好,那么我们首先大家会想到第一步逻辑,我们是不是要求这个B的英符里边,我们是不是能拿到那个value,就是当时它传过来的以太数量对吧?这个以太数量如果说要比我们传过来的这个amount小的话,是不是我们就直接给它退回去就好了,那大家这里要稍微注意一下,我们这里的amount是一个string,我们这里直接去比这个有点不对。
13:30
对吧,所以我们再多加一个一个函数吧,就是我们定义另外定义一个mount变量,这个mount变量就是要把我们的我们定义一个,自己定义一个工具函数啊,String to unit,我们把传进来的这个字符串转换成我们要的unit,对吧?SP to unit,那这里我们就不要这个amount了,呃,就是下划线的amount,我们要这个转换之后的unit直接来比这个就方便一些,对吧?那同同时大家就会想到如如果我们这里比它小的话,是不是我们就应该直接把所有的这些amount直接返回啊,啊,但是我们这里直接返回的话,呃,其实还是有点有点不方便,那我们能够想到一个比较好的程序结构是什么呢?我们再定义一个变量定义好。
14:30
好,我们要返回多少数,最后处理完我们这里核心逻辑之后,在最后统一返回对不对,这个会就是从逻辑上来讲会比较顺些,对吧,我们就不需要在里边每一次算出来之后都直接去调什么什么点transfer对吧,ME3点点点transfer,这个就很麻烦,我们在前面直接定义一个U叫refund,就是退回的这个回款对吧,Refund。
15:01
呃,一开始可能我们不需要给它定义值,对吧,定义出来就可以了,不需要赋值,那如果说我们这里它小于amount的话,我们是不是就可以直接把这个refund就等于amount就完了,这是我们最后要transfer回去的值对不对啊,这这就是我们如果说诶,呃,不是啊,小于amount,我们不应该是按照amount来返回,因为amount是它的报价,对吧,我们要返回的是当时他给的这个数对不对?对对,这个写错了啊,大家得梳理清楚,别给错了,要不然别人。当时转那个一个以太,然后里边写说我我报价是100个以太,我们直接把100个以态给他转回去了,这肯定是不行的,好,那么这这个if是我们它的当时给的以态不够的时候,那这是一个非法的静态报价,那接下来如果else的话,肯定这就是一个合法的竞拍了,对不对,那就是说它这个value是比这个amount至少要大大于等于的,那接下来我们就会想到这就有好几种情况了,对吧?首先我们会想到if同样还是判断这个amount对吧?Amount如果要比我们。
16:23
B的,呃,这这个不能从B的里面找啊,就是如果比我们当前产品的最高竞价还要高的话,诶,我们一开始可能还判断不到这个最高竞价,我们可能是先判断它是不是第一次竞价,对吧?因为我们还记得就是还有一个第一次竞价的时候,它的第二高我们要给他的那个start price对吧,我们这里先判断这种初始的情况,所以这种情况我们怎么去判断呢?什么情况下它就是第一次竞价呢?大家会想到我们是不是得从产品的信息里边去找啊,Product里边的什么信息能够体现他没有人报过价。
17:08
大家看一看product里边对有total bes,还有这个highest be highest be,这些其实都能够表现,对吧?Total be如果是零的话,那就说明他没有人竞价对吧?或者是highest bier如果是空的话,是不是也是没有人竞价啊,有人竞价highest be肯定就有,对不对?所以这里我们都可以拿这个指示,比如说我们课件里面应该是用highest speed的,对吧?呃,大家可以看到这个对highest bit对吧?等大家实现的时候可以用total bit子啊,试一试不同的方法,好product.highest bitter对吧?它如果要等于零,这个时候大家要注意,我们做一个强制类型转换,因为它是个地址类型,对不对?好,我们把它做一个强制类型转换,那么如果它是等于零的话。
18:06
我们要做的是不是就是把最高的那个直接就是当前的这个最高的价就是当前的amount对吧?当前的竞价,然后第二高的竞价要给start price对吧?好,就是这样的过程,所以我们就要写这个product了,对吧?为什么我们前面这个product给storage类型呢?这里要写了product.highest BI就等于message点3product.high is big就等于应该是等于这个B的in.value呢?还是等于amount呢?大想一下我们这里有两个数对吧?一个叫B的in.value value,一个叫amount,大家想一下我们应该给哪个,哎,逻辑有点顺不过来是吧?行,那我先讲,我先把这个全敲完,大家等一下就是或者下午的。
19:06
时候第一节课给大家时间,大家再好好的梳理这个逻辑啊,我们这里给的应该是amount,为什么呢?因为B的iner.value这个是当时给的那个仪态数,这个数量有可能给多了,对吧?那我们真正的他的这个竞拍的价格其实是他这里报出来的这个价格对不对?这里才是真正竞拍的价格,他给多的我们这里就要返回去的,所以大家注意啊,好,Product点还有一个参数叫second highest b对吧?第二高价这个我们是不是就给到了product.start price啊。这个就比较好理解了,对吧?好,那接下来这些东西都定义好了,我们是不是得把多出来的钱,每一步我们都得注意,这个多出来的钱要退回去,对不对,要不然的话,你到时候的话给每个人退钱,这个可是做不了的,对吧?所以一定要在他揭示报价的时候,把他多余的钱就给他退回去啊,这个是我们一定要在这一步做完的,要不然我们去便利所有人,然后给他去退退钱,这个是做不到的啊好,那么我们还是这个refund就可以,等于是不是就是应该是我们多出来那笔钱啊,对,多出来的钱是当时他给的是b iner.value然后减去我们这里的amount,这就是多出来的钱,对吧?好,这种情况我们考虑完了,那else啊,这打的好,我们其实还应该就是。
20:44
好else话,那其实前面这个我们说的是第一次对吧?Else的话,那就是不是第一次,那我们就直接L就好了,我们就不用else if了,对吧?那else的话,在这种情况下我们不是第一次,这种情况其实我们又得分类了啊,大家直接如果愿意直接写那个l if也可以,但是我可能更习惯于就是我们按照这个逻辑,大的逻辑上分代表块对吧?前面这是第一次,下面else里边全是非第一次的情况,非第一次的情况又分至少两种,就是你要不比最高价就高对吧,要不你比最高价低,那另外大家可能想到还比最高价低,你还得分它是不是比第二高价高对不对?那所以至少应该有三种情况,好了,我们继续来分吧,If if什么呢?Amount比我们的最高价高,最高价是什么?对product.high。
21:44
Is b的对不对?这前面我们都已经有过的啊,好,那接下来我们先把这个大的框架都搭起来吧,Else if是不是else,如果前面是比它大,那else是不是就应该是比它小了?对,就比第一个最高的进价要小,那剩下的里边是不是我们还应该else if,它比第二高价高啊,对,所以product.second highest bit对吧?那这里我们再给他来一个判断,那最后的else是不是就比第二高价都低了?对,这个里面那就是纯粹比第二高价都低,什么都不用做,直接返回,所以这个里边最简单,我们先写上啊,那就是refund,是不是直接等于amount就可以了,是不是这样,对,所以大家就是我们直接。
22:37
把它那个要返回的值直接都退回去就可以了,那接下来大家注意我们这里,呃,上面如果说要去它比这个最高价都高的话,那大家想一下我们应该怎么做呢?如果比最高价都高,是不是最高价就应该替换掉啊啊但是大家这里注意,我们直接就product,哎,我们直接就product.highest b,然后直接把它这个更改掉吗?其实不行,因为highest b我们还得替换,把它顶成第二高架对吧?对,所以我们要做的第一步其实是应该把high speed的保存到第二高架去,对,第二高架现在没用了,对吧?所以我们可以先highest second highest BI等于product.highest speed对吧,是吧,大家。
23:37
梳理逻辑,把当前的最高价付给第二高价,把第二高价先顶掉,然后才是用我们当前的报价顶掉这个最高报价,对不对啊,这里大家首先先注意,我们先把这个啊大,大家如果要是觉得可以这么写的话,那我们可以先把这个highest speed等于当前的这个amount我们先写进来啊,然后大家会想到我们是不是highest bit也得换啊,对,所以product.highest be应该等于谁?对,应该等于message点三对吧?好好,这里大家要注意,我们这里是不是大家还得还得考虑一种情况,就是说我们如果要是说嗨。
24:37
BI已经替换掉的话,那当时的highest BI它是不是还有钱被我们锁定在这个合约里面的?那我们是不是应该把原先的那个highest bitter资金先释放掉啊,要不然的话,我们之后怎么样去在什么时候再去释放这个资金了,就没办法了,对吧,只有在这个时候我们知道确定的把它顶掉了,而且我们知道他当时给的是多少钱,我们可以是不是把这个钱退回给他,所以大家注意我们这里是不是还应该得有一部叫做。
25:14
需我们得把当前的那个highest be得拿出来,对吧,product.highest be.transfer啊,我们是不是得对,我们得把把这样的一个钱。退回给到原先的highest be,那大家会发现我们那是不是就不能在这之前改highest BI啊,要不然的话,这反而就给到当前的这个mes center了,对吧,就不是之前的。之前的那个还比了对不对,最高价竞价之前的竞拍成功的人了,所以我们把这个替换到上面去啊,他得放到这里来,对不对,先就把这个transfer掉,那他要transfer的数量是什么呢。
26:03
对,是不是应该是当时他的high speed的呀,应该是当时他给出的那个最高价对不对,当时他出的最高价,剩下的钱我们是都应该锁定在合约里边的,对吧?当时我们大家看到这个给这个初始的时候,是不是是把这个amount他出的这个价格给到了highest币里边,然后剩下的钱给他返回去了。那是不是它的这个最高出价全锁定在我们的合约里边了,所以这个时候你如果要把它顶掉的话,要返回的是不是也应该是product.highest speed啊,那大家会发现那highest speed也不能乱换,对不对对,还得再上一个,所以大家注意啊,这个就是注意这个逻辑,这个顺序还不能随便调。
27:02
我们会发现,我们首先把highest b存到这个highest b就是第二高价里面去,最高价存到第二高价里边去,然后原先的最高价还不能先改,我们先把这个最高价就直接返回给原先的最高价的那个竞价人,对吧?因为他这个已经失败了,有人比他更高了,所以这个钱我们不应该再锁定,给他退回去就可以了。然后我们会把当前的最高价改掉,用当前的这个amount,对吧,这才是现在的最高报价,然后我们再改这个highest be,用当前的这个me center。改掉啊,这个逻辑相相对来讲稍微有点复杂,对吧?那改掉了这个messages send和和这个highest bit之后,我们还应该有个什么呢?应该把当前给这个最高竞价人要返回的钱是不是也应该算出来啊对,他也应该有有这个要返回的钱的,那他的这个refund应该等于什么呢?对,他是不是也是当前给了一个这个B的iner里边有一个value啊对,所以我们能够想到B的iner.value我们应该减掉这个amount,对不对,这样就把它直接返回去,好,那接下来大家就会想到了,如最复杂这种情况处理完了,对吧?这是最高价,那如果要不是最高价呢,我们把这这部分讲完啊,快速讲完,如果不是最高价,那么它就不是high。
28:42
Speed啊,那这个时候high speed就不变对吧,但是如果说它比第二高竞价要高的话,那他是不是得把第二高竞价顶掉啊。对,所以product大家能想到second second highest speed就应该等于我们当前的amount,对不对,那同样大家会想到他当前的这个这个竞价应该给给返回多少钱呢?诶大家先想一下,除了这个给到他之外,还需要给那个第二高的竞价人去返回返回钱吗?
29:19
应该不需要对吧?对,因为他就没有竞价成功,我们之前在判断他没有竞价成功的时候,就应该把所有钱都返返回给他,对吧,就应该是这样的,好,那接下来大家就会注意,我们是不是就直接可以把refund给到他了,对吧?Refund就直接把amount全退回给他,所以接下来大家就会发现,如果说他连第二高价都不是的话,那我们就直接把所有的mon发给他就完了,好那大家可以看到所有的这一串。到这个地方为止,If else就全处理完了,对吧?把我们的这个refund就处理完了,那大家会想到你处理完这个所有的这些信息之后,定义好refund处理完了,我们是不是应该统一把这个返回去啊,给这个当前的material sender应该返回去对吧?所以我们定义一个if refund大于零的话,如果要是它是零或者说小于零的话,我们就不要再去做这种无用功了,对吧?那需要怎么做呢?message.sender给他发发语态对不对,是不是transfer啊,大家记得这个用法啊,要传的值是要发以态数量re放对吧?呃,那当然了,这个时候就是我们还应该有一个操作,大家会想到还有一个地方一个标志位没有置对吧?是不是对有一个review的对吧?我们把那个。
30:54
加一吗?是对,那个是我们在竞价的时候加一对吧,现在是揭示报价已经不加一了,但是大家应该记得我们在这个里边是不是有一个是否已经揭示的一个标志位啊,对,这个东西我们是要去把它支出的啊,所以这里product点,呃,Bes对吧,大家记得它里边有一个bes bes是根据这个报价人来定的mepi s,然后它是不是根据他的那个哈希来定的sal be的对吧,我们这个sal be前面定义过的吧,诶,S be这里对,就是根据我们这里取出来这个对不对,然后去查,查到的这个就是我们对应的那个进价的那个数据结构对吧,完整的那个structure b的ru,那么它的review的。
31:50
就得是处对吧?好,所以这样的话,就把我们这个整个揭示报价的这个函数就已经写完了啊,所以大家可以看到,呃,回过头来我们看一下这个教案里边,好,当然教案里边它是会把这个放在前面写,对吧?大家知道这个为什么吗?就是因为下边这个动作是一个transfer一个动作,这个动作要消耗的盖其实是比较多的,对吧,所以其实是可以把它放在最后。
32:26
然后这一步如果要出错的话,前面其实是全部都应该回滚的,对不对对,所以说这个就保证了我们前面的东西都不会出错,那你前面如果要是这一步出错放在后面的话,前面这个交易都已经发生,那其实是会有问题的,对吧?所以说我们把这个最后的这个transfer放在最后一步来做这样的一个过程啊啊,那大家也学习学习一下这个写法,我们把这个放到上面去,好,这就是我们整个这一个揭示报价和这个竞价的这个过程。
我来说两句