小Co:上一篇讲解了怎么根据比特币区块哈希生成幸运数的,哈哈小新听懂了没?
小新:说实话上篇的内容挺难理解的,新的知识点好多,我没有理解很透彻。
小Co:没关系,那些内容你只要着重关注2点就行了。第一,区块哈希和幸运数是一一对应的,因为未来的某个时间点的区块哈希事先完全预料不到,所以这个幸运数也是无法预料的,这也是抽奖算法公平的体现;第二,python里使用hash算法的步骤就是那么3步,现在你知道怎么大概用就行了,之后我会专门花一篇文章,来详细说说hash在python里怎么运用。
小新:嗯嗯,这就好。那现在幸运数也生成了,接下来就该详细说说怎么用它来产生每个人的分数了吧。
小Co:是的,终于来到对个人来说,最关心的部分了。记得上文说的for循环吧,对于循环里的每个奖券号,都会调用score_for_each_lottery函数计算分数。现在我们就看看它的实现:
注意函数入参包括了幸运数和某个人的奖券号:
33行创建了一个sha256算法的hash对象h,注意这里生成对象的方法和上一篇中h = hashlib.new(n)有些不同,这是因为上一篇需要使用不同hash算法,每次在for循环里产生不同hash对象,而这里已经确定使用sha256算法,所以直接生成sha256这个类型的对象。
34行把幸运数放进去进行hash计算,这一行执行之后,对象h的值实际上就已经变化了,但是对于不同的奖券号来说此时h的值还是一样。
35行把奖券号放进去继续计算后,每一张奖券号的h就截然不同了,这里要稍留意的是,上文也提到过,hash算法计算必须传入二进制的值,所以这里也用bytes函数,把lottery_id进行了转化。
37行把base设置成了10的11次方的一个超大数,**的就是乘方的意思。哈哈,这个数很大吧,下面就知道它的作用了。
38行符号比较多,我们从内到外分解来看。h.hexdigest()是把h的值用16进制表示出来,所以可以看到,hash算法里一般输入的是2进制,输出是16进制。而int(h.hexdigest(), 16)就是把16进制的h值转变成10进制的数,这样就把hash算法的结果变成了我们平时使用的数字了,最后把它除上base,也就是10的11次方,就得到了每个人的最终分数。
小新:哇,短短几行代码,背后体现的东西也不少呢。我真没想到hash算法算完之后数字会这么大,要拿base那么大的值去做除法。我都数不清了,这得是多少亿了啊。。。
小Co:确实是一个超大的数,最后实际上算出来的score分数的值,都还是亿的数量级,你想想没除以base之前有多大。
小新:My god,我脑袋不够用了。
小Co:说完了每个人的分数是怎么生成的,到这实际上奖券计算的主要流程就已经说完了。但是接下来还有一些工作没有完成。
小新:咦?分数不是都已经算出来了吗,还要干嘛?
小Co:你想想,分数是算出来的,那这些分数要怎么处理呢,是直接显示在屏幕上?还是找个地方保存起来?
小新:emm...应该是保存起来吧,显示在屏幕上别人又看不到。
小Co:是的,保存起来才是正确的选择,毕竟好几万人的得分结果,屏幕上显示是完全不合理的。一般来说我们会把结果数据保存到文件里去。下面我们看看得分算完之后,最后的步骤是怎么样的。
这是我们之前贴过的代码,在第2篇里也简要分析过,现在65行计算奖券分数已经完成了。再详细说说后面的内容:
66行的作用就是把所有奖券的分数从高到低进行排序。这一行的内容其实挺多,也有一丢丢复杂,我把设计到的知识点说出来,小新你有兴趣可以继续去了解。Sorted()函数是用来排序的,key = 表示是根据什么内容来排序的。lambda t: t[1]是lambda表达式,表示传入t的话,将会返回t[1],reverse =True表示进行倒序排序(也就是从大到小),由于reward_map是字典的数据结构,reward_map.items()表示其中的所有项,所以这里key(排序依据)就是分数。
最后再看看把分数保存到文件的函数:
58行用open新建了一个rewards.txt文件,’w’表示会对这个文件写入内容。
59到61行是一个for循环,遍历奖券结果rewards,r是每个奖卷的结果。f.write表示每次向文件里写入什么内容,这里可以看到依次写入了一个递增的数字(str(c)),airdrop_prefix(‘AA’),‘-’,奖卷结果(str(rewards[r])), 换行符'\n'。str(n).zfill(7)限制n的长度是7,向右对齐,左边不足的补0。
最后63行f.close()表示文件写完了,关闭这个文件。
好了,到这里整个EOS空投的算法就结束了,小新你感觉如何呀?
小新:就结束了吗?感觉还意犹未尽呢,好多懵懵懂懂的内容,不过我也会主动去学习文章里提到的python基础知识的,下次肯定不会这么小白了!
小Co:哈哈,那可要好好期待了。好了,小新,那我们下一个系列见吧。88~