哈弗兰大的博客


  • 首页

  • web前端

  • 其他

  • 关于

基于以太坊却不上链的抽奖服务,是不是有一点可疑。

发表于 2019-03-03 | 分类于 其他 |

前言

本文是随笔,记录了一次基于以太坊的抽奖服务的方案讨论。从常规的智能合约的实现方案,到最终改用不上链的实现,主要是分享一下思路,包含了一点不看也没事的技术细节,以及一点区块链相关的内容。

因为抽奖主题的区块链开发入门文章已经泛滥了,所以文章尽可能避免变成教程。

背景

之前一位做论坛的同学说他们那个论坛经常会做一些活动,抽奖什么的。如何让用户能感受到公平公正,让大家信任。之前一个的办法是在指定时间录视频,并且边上放个北京时间,表示这个是准时开奖没有作弊。这个和澳门最大线上赌场异曲同工,边上搞台电视放新闻的直播,令人信服。

但是总一直这样也不行,我们可是搞技术的,而且这种方式扩展性太弱。于是他们想做一个公正公开可信任,简单易用易理解的抽奖系统,选定的方案是区块链。我听了觉得很有意思,而且公正公开不可变,区块链太合适不过了,说就研究研究吧。不过为啥不找区块链团队帮忙,可以部门间合作合作。他说这个需求太简单了,就不麻烦其他部门的人了。

方案

虽然现在公链有很多了,而且性能一个比一个强,但是实际上有大量应用的目前也就两三个,我个人比较喜欢古典一些的ETH。

其实需求很简单,方案也预定了一下。基本的逻辑是,用指定eth地址将帖子id作为参数来执行合约函数,得到随机数结果。指定eth地址是用来做权限控制,私钥不公开,可以防止被无关人员开奖。因为合约是公开的,执行函数的时间也是公开的,执行结果也是公开的,所以开完奖之后,大家可以直接查询验证结果。

只要在活动开始时提前公布用来开奖的地址与开奖时间与帖子id,预定时间开奖之后,大家一查就有了,简直完美。 其实当时想了有一个缺点,就是得花钱,执行合约是要付费的,大概算了下按当前eth的价格开一次奖得花一块人民币,会不会太浪费,他说完全ojbk。

阅读全文 »

使用telegram bot实现的报警工具

发表于 2018-03-11 | 分类于 其他 |

个人的程序的报警很多人都用的 server 酱 之前我也是用这个的 个人使用的时候确实非常方便 但是因为 server 酱是基于微信公众号的 所以如果要发送个多人 或者分组发送消息 还是不是很方便 于是自己开始准备用 wepy 来做这个工具

结果发现貌似itchat接口被封掉了 issues 不得不寻求其他的方法

最终找到了telegram 不得不说 虽然是聊天工具 但是对开发者还是相当友好的 各种接口都有提供 而且提供了一个非常强大的机器人系统 可以进行各种操作 而且流程非常简单

创建自己的机器人

搜索BotFather 这个帐号 然后发送/start开始对话 BotFather是telegram的一个机器人帐号 用来管理所有用户创建的机器人 开始对话之后 会提示你进行各种操作 来创建和管理自己的机器人 设置机器人的用户名 创建完成之后会得到一个机器人token 之后所有的操作都是使用这个token来做

创建频道

telegram和微信不同 除了组之外还有频道的概念 频道里只有管理员可以发送消息 其他人可以订阅这个频道 接受消息 非常符合报警这个使用场景 创建完了之后设置频道的名称 并且将你的机器人设置为频道的管理员

发送消息

然后就可以测试了 用的是python-telegram-bot这个库

1
2
3
4
from telegram import Bot

bot = Bot(token = "tokenofyourtelegrambot")
bot.send_message("@channelname", "测试内容测试内容")

是不是简单到爆炸。。。。 然后在使用flask之类的封装一下成http接口简直好用到不行

阅读全文 »

js的GPU计算2之webgl

发表于 2017-12-17 | 分类于 web前端 |

上篇讲了个如何使用gpu.js这个库来进行简单的gpu计算 虽然简单易用 但是本身的局限也很多 目前这个库也不是非常完善 有待改进 那咱就从原理开始 来自己搞一个吧 当然 并不是指实现一个这个的通用的库 而是使用相关原理 完成一个是用GPU计算的demo 当然还是矩阵的乘法

前端使用GPU的能力是通过webgl实现的 更加广泛的理解的可以认为是通过canvas来说实现的 canvas估计对大多数前端来说并不陌生 canvas有许多个像素组成 每个像素的颜色可以有RGBA四个维度表示 每个维度范围为0-255 既8位 把RGBA表示成数值的话 那每个像素可以存32位 这就是前端使用gpu计算最为核心的一点 每个像素可以存储一个32位的值, 刚刚好就是一个int或者uint

0.基本WebGL绘制

首先从最简单的绘制一个图像开始 webgl绘图的流程 最简单的就这样

1.jpg

其中两个vertex shader和fragment shader为两个GLSL代码片段 分别处理坐标数据和颜色数据 vertex shader和fragment shader的执行是以像素为单位

canvas开始绘制的时候 vertex shader中得到 每个需要绘制的像素的坐标 视需要可以对坐标进行各种转换 最终得到一个最终位置 这个过程中可以将数据作为输出传入fragment shader 参与下一步的计算

fragment shader接受各种输入 最终输出一个RGBA颜色数据作为该像素点的颜色值

当所有像素都绘制完成之后 画布绘制完成

阅读全文 »

使用JS的进行GPU计算

发表于 2017-10-22 | 分类于 web前端 |

前端是可以接触到GPU的 于是也是可以使用GPU的计算能力的 对于我这种没有很深入的GPU运算了解的程序员来说 完全从底层开始怕是也不太可能 好在已经有大神把相关的内容以及封装成库了 gpu.js 于是本文的初识的意思就是就从这个库开始 首先说明 这个库其实也还在开发当中的 也没有一个很稳定的正式版 所以很多功能都是有欠缺的 但是了解个GPU计算是啥来说 绰绰有余了

因为js是单线程的 所以并不适合处理CPU密集型的程序 但是GPU是有非常高的并行线程数 所以GPU计算的基本思想就是把计算任务分拆成N多个线程任务 每个线程返回一个结果 然后吧每个线程的结果再汇总 这个基本的思路不管是哪平台上的应该都是一样的

啥是线程的概念 咱先直接看一段代码来先感受一下

1
2
3
4
5
6
const gpu = new GPU();
const myFunc = gpu.createKernel(function() {
return this.thread.x;
}, { output: { x: 100 } });
myFunc(); // [0,1,2,3,...98,99]

每个线程都会执行这个传入的函数 具体起多少个线程有参数output决定 可以有x,y,z三个维度 上面这个例子只取了x方向上数量100个

在函数里this.thread.x可以获取到当前执行这个函数的线程x维度上的地址 如果有多个方向的话 还有类似this.thread.y和this.thread.z的

函数接受的参数为外部调用的时候传入的参数 函数返回的值为当前线程返回的值 所有线程按照各个维度上的位置 向最外面返回一个最终的数组 就是上面那个执行的效果 每个线程直接返回了线程在x维度上的位置 最终吧所有线程按照维度的顺序合并起来 如果有两个维度 最终的值就是个二维数组 同理三个维度也是

要注意的是 这个执行的函数 最终会被库转化进入到GPU中执行 所以 所有外部js的参数和函数 还有该函数里的语句语法是有限制的 具体的解决方法可以参考文档 有向内部传入数据的方法

阅读全文 »

从pyhton的生成器到js的生成器

发表于 2017-09-03 | 分类于 web前端 |

从pyhton的生成器到js的生成器

说起这个generator啊 本不是js的东西 而是从其他语言中借鉴来的 当初初es6标准的时候想必大家都看过了 也都知道所谓生成器 但是估计大家和我一样 可能从来也没用过吧 最大的用处估计就是在async/await实现之前来替代的处理异步吧 比如koajs1.x 但是这并不是generator本身应该的正确用法 如果你是generator 你心里会怎么想 本来我估计也用不到这东西 但是最近我不是后来去写了python嘛 也终于在一次认识到了这个东西 然后再次从js的角度看待generator

首先来个例子 redis中每个用户有一个物品列表list user:$userId:items 每个物品有物品详情hashset item:$itemId 现在需要遍历所有物品 为了减轻内存负担 所以要一条一条取

js 回调参数 内部回调函数版

1
2
3
4
5
6
7
8
9
10
11
12
function getAllItem(userId, callback){
redis.lrange(`user:${userId}:items`, 0, -1, function(err, itemIds){
if (err) return callback(err);
for (let itemId in itemIds){
redis.hgetAll(`item:${itemId}`, callback);
}
});
}
getAllItem(1234, function(itemDetail){
console.log(itemDetail);
});

这个版本因为整个函数都是异步的 获取所有物品后再执行后面的过程 这个操作是没法处理了 需要对回调参数函数进行再次封装 即使内部换成Promise也是一样的

阅读全文 »

从官方文档解释弱等于

发表于 2017-08-27 | 分类于 web前端 |
本文的目的是为了和大家分享如何从官方文档中获得答案  
至于标题中和本文其他的语法也是非常不规范  
在平时开发中需要极力避免使用`==`与不必要的类型转化

demo

我先抛出一个例子 大部分人估计会很疑惑 在语言大战中 很多其他语言的人也经常抓住类似的例子来攻击js

但是js作为一个有规范的语言 所有的结果都要遵循规则吧 然后咱就来带大家看看 关于==语法在es 2017中的定义

为啥是2017呢 因为本文写的时候最新的标准就是这个版本 ECMAScript® 2017 Language Specification (ECMA-262, 8th edition, June 2017) 但是没有关系啊 我会截图给大家的

首先先看==的标准 Abstract Equality Comparison

阅读全文 »

一道简单的笔试题

发表于 2017-05-02 | 分类于 web前端 |

这段时间各种面试 杭州在网易之上的 当然只有阿里一家了 就找了学长帮投了阿里云的简历 没想到投的是资深全栈工程师 有点点虚 ——你一个刚毕业一年不到的也敢投资深全栈?? 不过最后还好 挂在了hr上 吐槽一句:阿里的hr果然名不虚传,算是见识到了。 技术的几面还是挺顺利的 技术官也都非常厉害 可惜忘了要联系方式了 我感觉所有的hr都有毒,我挂在hr上已经不止一两次了 十几次都有了吧??

跑题了 笔试出了三题 都不难 和面试官共享页面 也可以对话什么的 这种笔试方式 与其说是笔试 更像是面试的时候拿张草稿写解决方法的感觉 我觉得非常棒 (最后我会对比另外一家的笔试题目 真的太垃圾了)

其中第一题 让我就非常欣赏 题出的太棒了

实现一个函数,传入一个数组,元素均为字符串,把数组中的所有星号(*)移到末尾,其他值的次序不变,如下图

javascript数组重排序

这个题目非常简单啊 但是我觉得这个是个非常好的题 具体好在哪呢

阅读全文 »

关于协同过滤的推荐算法

发表于 2017-05-02 | 分类于 其他 |

这个主题想写已经很久了

自从换了新部门之后 也没有写过前端 因为部门总共6个人 有两个前端 然后后端和算法人员不足 因为我技术比较强 就被安排到了新的任务 老大和我说 做数据和算法比前端有前途 话是这么说的 但是我从大一起开始写前端写了这么多年 突然让我去写其他的 那我前端领域的优势就没了啊 而且就算我继续算法这些写个三年四年 到时候仍然随便一个刚刚毕业的专门研究算法的就能把我干趴下了好吗 毕竟我也没怎么专门研究过这些东西 不过既然部门有任务安排 那只能写了 这段时间经历了 python从入门到精通 hbase从入门到精通 hadoop从入门到精通 什么kafka 什么zookeeper 让我作为一个前端大开眼界 有点偏主题了。。。。

我的主要工作有三点本文只是涉及其中一点 就是基于协同过滤的推荐算法 我们部门是推荐技术部 各种推荐算法当然是我们部门的核心技术 协同过滤这一块没那么核心 但是也非常重要

这个相关的文章 网上也是一抓一大把 主要的原理是通过用户对物品的行为来计算物品与物品之间以及用户与用户之间的相似度 算法的核心数学公式有好几种 我就不重复写了 我负责的这一块是从其他项目中借鉴过来的 发现对应的数学公式和现有的一些公式并不一样 我也不便透露了 不过各种公式的功能是一样的 都是为了计算相似度 不同公式对不同对场景会有优劣而已

阅读全文 »

前端组件的本质到服务端组件渲染

发表于 2017-03-18 | 分类于 web前端 |

先说结果 为ejs-mate实现了一个组件加载函数 实现了服务端组件化的渲染 按组件加载js与css资源

目前很多前端标准各大浏览器都有部分支持 心想试一下 然后试试看把vue的组件改成原生的前端组件吧 然后看了一下WebComponents 发现Shadow DOM离我上次看的标准又有变化了 没办法 目前这些基本还处于草案的阶段 只有template标签因为属于HMTL5的标准 目前是比较稳定放心可用的状态 具体就不多说了 写了两个组件 弄了个demo thesadabc.github.io/blog-demo/webcomponents 代码在这github.com/thesadabc/blog-demo/tree/master/webcomponents chrome56+

然后我发现并不能把vue的组件完全移植到原生的组件上 后来发现事情并没有这么简单 重新审视一番发觉 vue 的这些所谓的组件实质上是 模板 之所以不能移植到原生组件 很大一部分原因是诸如v-if、v-for等语法 而这些在模版引擎里非常常见 包括router-view这种 原生组件是根本没法搞的

vue ng之类的 本质上是前端的组件化渲染 组件本质就是模板 相比后端组件化渲染还只是停留在非常低级的includehtml模板文件的阶段 对组件的js与css的处理几乎没有

所以我在想 按照各自框架渲染组件的方式 如果移植到服务端渲染 那岂不是很爽吗 然而vue是有服务端渲染的 不过这个服务端组件渲染和前端组件渲染不太一样 服务端渲染只是把html相关的渲染完成 而事件属性之类的传递和前端组件渲染并没有区别 也还是包含了一个完整的Vue对象 所以其实这种渲染并不是完全的服务端渲染 而是分步渲染 反而觉得这种方式非常多余 为了seo的一种妥协

于是开始搞一个吧 完全后端渲染的 组件化的解决方案 各自模板引擎其实都有提供include方法 不过这只是html的模块化 事件以及数据传递相当成问题 弄了一个简单的 包含了这种思想的 demo

阅读全文 »

WEB API权限整理

发表于 2017-02-28 | 分类于 web前端 |

最近整理一篇关于 一些 浏览器html5 相关api 的权限的东西 虽然大部分都可以用了 但是基本上还是草案居多

本文所有的demo都在 这里 blog-demo/permission 代码在这github.com/thesadabc/blog-demo

有几个权限的demo还没有写好 之后会单独写出来

w3c.github.io/permissions: Editor’s Draft, 17 October 2016

事实上不止链接中的这几个权限, 比如usb, 本文就只对下面列出的这几个权限进行介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
enum PermissionName {
"geolocation",
"notifications",
"push",
"midi",
"camera",
"microphone",
"speaker",
"device-info",
"background-sync",
"bluetooth",
"persistent-storage"
}

push background-sync需要配合service worker工作

notifications 在service worker与浏览器环境中有不同

检查权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
navigator.permissions.query({
name: "notifications", // ["notifications", "push", "midi", "background-sync"]
//not support now: ["camera", "microphone", "speaker", "device-info", "bluetooth", "persistent-storage"]
userVisibleOnly: false, // for "push"
sysex: false, // for "midi"
deviceId: null, // for ["camera", "microphone", "speaker"], 可以从`navigator.mediaDevice`接口获取
}).then((permissionStatus) => {
let {
state // ["granted", "denied", "prompt"]
} = permissionStatus;
permissionStatus.onchange = function () {}
});
// 请求权限 目前没有浏览器实现这个接口 所以在各个接口有自己的实现
navigator.permissions.request({})
阅读全文 »
12…5
JunpengXu

JunpengXu

45 日志
2 分类
168 标签
RSS
Weibo GitHub
© 2021 JunpengXu