Akawa

ETY001的博客

最近有个项目需要使用 eth 的智能合约,虽然我不看好eth,但是为了挣钱也不得不花些时间去学习下了。之所以选择 Docker 是因为我不喜欢删除的时候删不干净,毕竟不熟悉工具会安装哪些东西。使用 Docker 的话,基本上都被封装在容器里,不用了删掉容器和映射出来的目录数据就ok了。

去 eth 的 github 看了下,是有提供 Docker 镜像的,那么我们直接拉取官方做好的镜像包就好了

1
docker pull ethereum/client-go

由于我们是本地开发测试,所以我们启动测试节点

1
docker run -it --rm -v $(pwd)/eth:/root/.ethereum ethereum/client-go console --dev

其中 $(pwd)/eth 是用来存储区块数据的宿主机目录,设置成为自己的一个目录就好。
执行后,就会看到类似下面的样子

最后会出现一个 > 的控制符,这时候就可以输入命令了,比如查看下目前的账户

1
2
> eth.accounts
["0xeeffae8858bee06d1b4f57d7a2fbf3544a593f12"]

获取指定用户的 balance

1
2
> eth.getBalance(eth.accounts[0])
1.15792089237316195423570985008687907853269984665640564039457584007913129639927e+77

创建个密码是“ety001”的新用户来专门测试开发

1
2
> personal.newAccount('ety001')
"0x6ed051356a14c1354a95f3352856f05d622b1658"

转账给新账户,用于测试

1
> eth.sendTransaction({from: '0xb0ebe17ef0e96b5c525709c0a1ede347c66bd391', to: '0xf280facfd60d61f6fd3f88c9dee4fb90d0e11dfc', value: web3.toWei(1, "ether")})

从网上找一段合约代码试试创建合约,把下面的代码复制到 Remix 里,编译器选择 0.4.18 编译,之后点击“detail”

1
2
3
4
5
6
7
8
9
10
11
12
pragma solidity ^0.4.18;
contract hello {
string greeting;

function hello(string _greeting) public {
greeting = _greeting;
}

function say() constant public returns (string) {
return greeting;
}
}

点击“detail”打开一个浮层,里面找到 WEB3DEPLOY 的代码,复制出来,修改一下第一行,比如

1
var _greeting = 'hi, ety001'

修改完后解锁钱包,把代码复制进 console 里,回车,即可创建新的合约了

1
> personal.unlockAccount(eth.accounts[1],"ety001");

console 里输入 hello.say() 回车后,就能看到输出了 hi, ety001 了,这样一个智能合约的开发环境就搭建好了。

完工!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
function steem_per_mvests() {
$url = 'https://api.steemit.com';

$data = '{"jsonrpc":"2.0", "method":"database_api.get_dynamic_global_properties", "id":1}';
$options = array(
'http' =>
array(
'header' => "Content-Type: application/json\r\n".
"Content-Length: ".strlen($data)."\r\n".
"User-Agent:SteemMention/1.0\r\n",
'method' => 'POST',
'content' => $data,
)
);
$context = stream_context_create($options);
try {
$result = file_get_contents($url, false, $context);
$r = json_decode($result, true);
$result = $r['result'];
} catch (\Exception $e) {
return false;
}
return $result['total_vesting_fund_steem']['amount'] / ($result['total_vesting_shares']['amount'] / 1e6);
}

function vests_to_sp($vests) {
$steem_per_mvests = steem_per_mvests();
if ($steem_per_mvests) {
return $vests / 1e6 * $steem_per_mvests;
} else {
return false;
}
}

昨天刷机结束,成功root后,还没有来得及安装谷歌四件套,毕竟很多软件不敢从国内应用商店安装,有些软件则是国内应用商店没有的。

今天使用老方法,去 GoPlayCN 下载回App,然后安装,结果一直在 Google Play 服务那一步安装失败,于是又从网上搜了半天,最后发现正确的安装姿势应该是去 Open Gapps 下载卡刷包,然后进第三方Recovery 直接卡刷。在 Open Gapps 上只要选好自己的CPU是啥架构的,安卓版本是啥,选择什么体型的包,然后下载就ok啦~

最近为了研究 xposed 模块开发,我拿我的一块手机跟我妈换了下,把她手里的小米4C换过来,准备用这个作为开发机使用。折腾了一整天,终于是搞定了。

准备工作

  • 解锁BL
  • 线刷包 libra_images_6.1.7_20151221.0000.11_5.1_cn_b09dac70a0.tgz
  • cofface_twrp_recovery.img
  • SuperSU-v2.79-SR2-20170103_automode_by_kane.apk
  • XposedInstaller_3.0_alpha4.apk
  • xposed-v86-sdk22-arm64-MIUI-edition-by-Solar_-20160710.zip

下载所需的资源

准备工作中列出的各种工具,都已放到百度云了,链接: https://pan.baidu.com/s/1GPumHzCjc89o-jZlKh1V3g 提取码: 25xf。其中 cofface_twrp_recovery.img小米4C刷第三方recovery工具2.8.7.3.zip 中。

解锁BL

先去这里 http://www.miui.com/unlock/index.html 申请解锁手机BL的资格。BL 就是 BootLoader,解锁后才能修改 BootLoader。

获得解锁资格后如下图所示

然后下载解锁工具。解锁工具只有 Windows 版,因此如果你用的是非 Windows 系统,请自行准备 Windows 系统 或者虚拟机。启动解锁工具,会提示登陆

登陆后,将手机关机进入Fastboot模式(同时按电源键及音量减键),手机上会出现米兔在维修机器人的图标,

然后这时用数据线连接电脑和手机,然后在电脑上点击“解锁”

大约一分钟左右即可完成解锁,然后系统会自动重启。

刷入低版本系统

目前已知 6.1.7 及以下的版本是没有任何锁的,之后的版本都对 /system 分区加锁了,因此我们需要先刷入低版本的系统。从 http://www.miui.com/shuaji-393.html 这里可以找到通用刷机工具,按照这个网页中的教程操作即可。

刷完后,手机自动重启,第一次重启会很长时间,耐心等待直到进入系统。

做完系统初始化配置后,进入到设置里,找到“关于手机”,一直点击 MIUI版本上 直到开启“开发者选项”,切回设置主菜单,“其他高级设置”里面找到“开发者选项”,打开“USB调试”。

刷入第三方Recovery

再次进入 Fastboot 模式,手机线连接手机和电脑,在电脑上解压 小米4C刷第三方recovery工具2.8.7.3.zip,如果是 windows 系统,直接执行里面的一个 bat 脚本即可完成第三方 Recovery 刷入。

由于我 Mac 下有 ADBFastboot 工具,因此我是手动刷入并引导进入 Recovery 的,如下图:

对系统进行ROOT

刷入第三方 Recovery 后,会自动重启进入 Recovery,界面如下图

这时在我的电脑里应该能找到手机的SD卡的那个盘,把 SuperSU-v2.79-SR2-20170103_automode_by_kane.apk 拷贝进去,然后回到手机,点击“安装刷机包”,找到 SuperSU-v2.79-SR2-20170103_automode_by_kane.apk,并滑动滑块开始安装,等提示完成后,即可重启手机。进入系统后就能在桌面看到新安装的“超级授权”应用了。

安装 xposed

从我的电脑里,把 XposedInstaller_3.0_alpha4.apkxposed-v86-sdk22-arm64-MIUI-edition-by-Solar_-20160710.zip 复制进手机SD卡。在手机上安装 XposedInstaller_3.0_alpha4.apk

安装后,进入 Recovery 模式,即一直按住电源键和音量增键,直至出现开机Logo的时候,松开电源键,再等几秒后,进入 Recovery,这时松开音量增键。

点击进入“安装刷机包”,选择 xposed-v86-sdk22-arm64-MIUI-edition-by-Solar_-20160710.zip,滑动进行确认后开始安装,完成后重启手机。进入系统后,打开 xposed installer 点击“框架”,就能看到如下的字样

说明我们的 xposed 已经安装好了。

为了测试下是否安装正确,我安装了一个微信机器人的模块,并且把微信机器人放到了群里测试了下,效果如下:

至此,完成!

1. A valid provisioning profile for this executable was not found.

这个问题,在网上搜了很久,有很多种可能会导致这个问题。我遇到这个问题的解决方案是:

File > Workspace Settings > Set Build system to “Legacy Build System”

2. Cannot read property ‘semver’ of null

  • find the path /platforms/android/cordova/lib/emulator.js
  • find the line avd.target = 'Android ' + level.semver + ' (API level ' + api_level + ')';
  • replace it with avd.target = 'Android ' + (level ? level.semver : '') + ' (API level ' + api_level + ')';

3. 如果 build 的时候显示 Error: spawn EACCES

这个错误说明你正在使用的程序没有执行权限,通过给 cordova 命令增加 --verbose 参数,可以看到是哪个程序执行不了,然后给这个程序加上执行权限即可

4. cordova build 之前先配置好环境变量

详细的安装配置需要去看下 cordova 的官方文档,这里只是强调下环境变量的配置。这里分享下我的环境变量配置:

1
2
3
export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jre/jdk/Contents/Home
export ANDROID_HOME=/Users/ety001/Library/Android/sdk
export PATH=${PATH}:${JAVA_HOME}/bin:${ANDROID_HOME}:${ANDROID_HOME}/platform-tools:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin

把上面的配置加到你的 ~/.bashrc 或者如果你要用的是 zsh 的话就是 ~/.zshrc

5. 代码更新

代码修改后,需要先 npm run build ,也就是先把 js 编译好,编译好后的静态文件会在项目根目录的 www 目录中,再执行 cordova prepare -d 就会把静态文件复制到各个 platformwww 目录里面。

6. 如何使用 Safari 和 Chrome 调试 app

  • ios的话,先在手机上找到 “设置” => “Safari浏览器” => “高级” => 把 “Web 检查器” 选中,然后用手机线把手机和电脑连接,电脑上打开 “Safari 浏览器”,”偏好设置” => “高级” => 选中 “在菜单栏显示开发菜单”,最后打开手机上的 App,这样在 Safari 的 “开发” 菜单中就能看到你的手机名的菜单了,选中其中的 app 名字就能打开 inspect 进行调试了。
  • android的话,也差不多的流程,在 Chrome 浏览器里访问 chrome://inspect,使用 debug 模式打开模拟器里要调试的 app 后,在 Chrome 浏览器里就能看到信息了,点击 inspect 就能打开针对这个 app 的调试窗口。需要注意的是,调试窗口里面的调试器需要翻墙,可以先用浏览器访问 https://chrome-devtools-frontend.appspot.com/serve_rev/@180870/devtools.html ,然后把这个网址加入到白名单里面,再回到 inspect 就可以看到调试界面了(这里我折腾了一天多,最终才发现是墙的问题😂)。

今天才发现,自从上次重装服务器后,一直忘记恢复 Steem 见证人的喂价程序了。之前一直使用的是 @furion 开发的 conductor,并且之前没有用 Dockerfile 封装成镜像,而是直接在 ubuntu:16.04 的镜像上启动容器,添加的命令。这次就直接做成镜像方便以后使用。

镜像文件

  • 你可以自己编译,Dockerfile 如下:

    1
    2
    3
    4
    5
    6
    7
    FROM alpine:3.6
    RUN apk add --no-cache python3 python3-dev gcc git musl-dev libffi-dev openssl-dev \
    && pip3 install -U git+git://github.com/Netherdrake/steem-python \
    && pip3 install -U git+https://github.com/Netherdrake/conductor \
    && apk del git gcc musl-dev libffi-dev python3-dev
    ENV UNLOCK=123456
    CMD ["conductor"]
  • 也可以直接用我封装好的,docker pull ety001/steem-conductor

使用方法

  • 添加 active_key 。

    1
    docker run -it --rm -v ~/.local/share/steem:/root ety001/steem-conductor /bin/ash

    执行后,进入容器,再执行

    1
    steempy addkey

    输入 active key 后就可以把你要操作的用户加入到本地数据库里了,数据库文件最终会存储在你宿主机的 ~/.local/share/steem/.local/share/steem 位置。添加好以后,执行 exit 退出容器环境即可,效果如下图:

  • 初始化 conductor

    1
    docker run -it --rm -v ~/.local/share/steem:/root ety001/steem-conductor conductor init

  • 测试喂价程序

    1
    docker run -it --rm -v ~/.local/share/steem:/root ety001/steem-conductor conductor feed


    可以工作

  • 启动喂价容器

    1
    docker run -itd --name steem-feed -v ~/.local/share/steem:/root --restart always ety001/steem-conductor conductor feed

完工!以后再部署喂价程序,两行命令就搞定了。

最近接手的 Stellar 钱包的外包小活需要搭建个 API 服务,考虑再三,由于 Stellar SDK 中我只会 Javascript,因此打算使用 Nodejs 去完成这个服务搭建工作。

大约5年前曾经用 Express 框架搭建过一个记事本网站,不过这次是做 API,用 Express 感觉好像太重了,于是搜索了下,发现了 hapi 这个框架。

说干就干。

首先初始化一个 Nodejs 项目

1
npm init

然后安装一下 hapi

1
npm install hapi -s

创建一个 index.js 文件,并粘贴下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
'use strict';

const Hapi = require('hapi');
const server = Hapi.server({
port: 8877,
});

server.route({
method: 'GET',
path: '/',
options: {
cors: true
},
handler: (request, h) => {
return 'Hello, ' + request.query.r;
}
});

const init = async () => {
await server.start();
console.log(`Server running at: ${server.info.uri}`);
};

process.on('unhandledRejection', (err) => {
console.log(err);
process.exit(1);
});

init();

启动一下,并访问 http://localhost:8877/?r=ety001,会看到 Hello, ety001

这样最简单的 API 服务就搞定了。

这里需要注意下 cors 这个配置,这个设置为 true,就可以避免跨域的报错,不过安全性需要注意,详细的配置参数请看 hapi 的文档。

除此之外,我还加入了缓存。因为每次去获取 Trade Aggregation 数据都需要大约5–6秒,这样的性能还是不行的。因此加入一个10秒的缓存,10秒内访问,将会返回缓存数据。

加入方法很简单,大致的代码结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const getTradePair = async (pointPair) => {
// the code to get trade pairs and trade aggregation
}
const traidPairCache = server.cache({
expiresIn: 10 * 1000,
segment: 'customSegment',
generateFunc: async (pair) => {
return await getTradePair(pair);
},
generateTimeout: 20000
});
server.route({
method: 'GET',
path: '/v2/api/trade_aggregations',
options: {
cors: true
},
handler: async (request, h) => {
return await traidPairCache.get('pair');
}
});

这里说明下。 traidPairCachegenerateFunc 方法就是在缓存未命中的时候,去获取新数据的方法。第一个参数相当于是缓存的标示,generateTimeout 就是 generateFunc 的执行超时时间。

hapi 使用 catbox 来实现缓存,框架默认使用 memory 作为缓存介质。

以上就是目前我所用到的功能,hapi 框架真的很轻,在处理些类似我这样的需求的时候,最省时间,尤其再配合 Docker,把服务直接做成镜像,部署起来也就一句话的事儿~~

昨天买了《浮生六记》回来看,最早听到《浮生六记》应该是在语文课上的课文里,“余忆童稚时,能张目对日,明察秋毫……”,这也是这次买这本书的原因了。

一直好奇《浮生六记》讲了什么,买回来看了序才知道原来写的是夫妻之间的家庭生活之事。于是有些怀疑写一些琐事是如何能获得200来年里各种大文学家的好评的。于是耐下心去读,看看到底是个什么。

读完前两记,起初还是有些不耐烦的,但是随着阅读反而平静了下来。文字虽不奢华,但是叙事中却不让人觉得是在记流水账。读完真的是可以感受到了一股浓浓的生活气息。

与其说这个是部散文选,不如说这其实是一部纪录片,就好像我们每天在用微信发朋友圈来记录我们的生活似的,但是《浮生六记》却不给人一种无聊的感觉,又能记录下精彩丰富的生活,实在是很让人惊叹。

继续阅读剩下的四记去了。

媳妇有个好习惯,就是每次去超市都会把要买的东西记录到纸上。

但是每次到了超市就会发现,不是忘带了那张纸,就是纸找不到放到哪里了😂。

于是我花了一天多的时间给媳妇做了个微信小程序用来实现记录要买的东西。

现在公开出来,大家也可以使用了,微信扫描文末的小程序码即可~

下面是演示视频:

Youtube

优酷

因为最初也是为了自己用,因此把需求砍到了最精简,直接输入添加要买的东西即可。
删除的话,只需要长按就可以了。
由于考虑到经常去超市购买的物品大致相同,所以增加了一个历史记录的功能,
这样下次再添加要买物品的时候,可以从历史记录里直接点按即可添加。
另外把小程序添加进“我的小程序”中,可以从微信首页下拉菜单中快速进入~

欢迎各位家庭煮妇(夫)使用,也欢迎分享给更多的家庭煮妇(夫)~

PS:据说有人还要用这个来记录其他的东西,而不仅仅是超市购物使用🤔。

起因

昨天收到了新买的二手网件路由,预刷的梅林系统,今天上午花了一个多小时把家里的主路由(米3)替换成新买的网件,在配置梅林的时候,发现梅林支持USB 3G Dongle。突然就想到了我之前买的,已经闲置了的优酷路由宝L1,里面我刷了不死 breed,可以考虑拿那个路由折腾下,正好手里有联通的大天王卡(每天3块钱无限流量)可以测试。

其实这个月初就在考虑怎么用这个天王卡,但是由于急着去青岛度假,时间匆忙,就拿了个 Android 手机当路由使。实际的体验效果是,手机终归是手机,可以带的设备数还是很有限的,同时4台手机上网就很卡了。这次正好发现梅林支持我手里的华为E1750C,于是就准备拿已经闲置的优酷路由宝L1开试(路由宝的配置对于这个价位还是很良心的)。

开始

首先要做的就是刷入系统。从网上搜索了下,路由宝的Flash容量不足以装下梅林系统,但是可以装下老毛子的 Padavan ,所以去下载了 Padavan 的固件(Google搜索 rt-n14u-gpio-1-youku1-128m_3.4.3.9-099.trx 即可找到)。因为我之前路由宝里已经刷入了 breed,所以写入新固件很轻松,只需要断电状态下,按住 Reset 键,然后送电,等待大约 2s 松开 Reset ,然后网线连接路由的 Lan 口,访问 192.168.1.1 打开 Breed,上传固件刷入即可。

写入成功后,路由会自动重启,重启后,找到新的IP地址是 192.168.123.1 访问下,在 高级设置 > USB应用程序 中,找到 USB调制解调器 ,国家选择 China,应用设置即可。

回到 网络地图,点击那个地球,就能看到连接方式变成了 USB调制解调器(总是),过一会 连接状态 就会显示 已连接

这时就能开心的使用流量上网了。由于是个3G的卡托,所以速度还是不理想,对于4G卡来说有些浪费了。以后再有机会的时候,换个4G卡托。目前来看,虽然带宽小了些,但是浏览网页看个视频还是没有问题的。

最后附一张设备图

d0.jpg

0%