Ethereum 开发工具

Ethereum 是市值仅次于Bitcoin的区块链项目。相比Bitcoin的货币功能,Ethereum引入了只能合约的概念,Ethereum更像是一个分散式的处理各种只能合约的分布式计算机。
使用Ethereum开发智能合约,则需要对Ethereum这一长串工具有个充分的了解。

Go-ethereum

官方版Ethereum 的 golang 实现。full-node。

Mist

钱包。需要链接到Node。但是Mist不仅仅是钱包,Mist更是提供了编辑,编译只能协议的功能,相当于钱包+IDE。

Solidity

开发智能合约的语言。

Parity

轻量客户端。比起Go-ethereum建立本地节点,parity直接连接到其他节点。并提供了钱包的一系列功能。

web3.js

Client Library。 Parity虽然有钱包功能,可以调用协议,追踪token,但是我们要进行开发,制作我们自己的客户端,还是需要用到web3.js这个库。

Truffle

开发智能合约的框架。

faucet

可以在faucet获取testnet kovan 上的以太币。 直接回复自己的地址就行了。记得24小时才能获取一次。

Apache rewriteRule 配合url 添加proxy header

问题描述

我们有类似 get /index.php -> https://backend.example.com/index.php 的需求。但是apache的DNS服务器并不知道backend。只知道它ip地址。所以我们这个时候需要添加Host header来访问backend。

`curl -H”backend.example.com” backend_ip_address/index.php”

那么配置该如何写呢?

解决方法

思路是使用RequestHeader添加host的header。然后使用RewriteRule来forword这个request。

1
2
3
RequestHeader set Host backend.example.com
ProxyPreserveHost On
RewriteRule ^\/index.php$ https://backend.example.com/index.php [p]

RequestHeader 和 Header 的区别?

RequestHeader 顾名思义是添加Request的header。 而Header是添加response的header。

ProxyPreserveHost 是什么意思?

我们修改了RequestHeader,但是默认这个RequestHeader 不会传给proxy。我们需要保持我们修改后的header然后传给backend.example.com

如何根据条件设置RequestHeader?

有时候,我们除了get /index.php需要forword,其他都是参考本地的静态文件,这个时候就不需要修改RequestHeader。所以我们需要根据条件判断是否添加header。
最简单的方法是使用apache的环境变量。

1
2
3
4
SetEnvIf REQUEST_URI "^\/index.php$" BACKEND=1
RequestHeader set Host backend.example.com ENV=BACKEND
ProxyPreserveHost On ENV=BACKEND
RewriteRule ^\/index.php$ https://backend.example.com/index.php [p]

以上。

Ethereum 入门备忘

Timestamp

timestamp和挖矿难度成反比。在决定采用哪个block的时候,会选取难度最大的block。所以一般来说矿工都会根据当前的时间戳来计算难度,然后挖矿。那么难度岂不是越来越小? 放心,时间戳是递增的,所以只要找到个反比的映射函数,比时间增长的加速度低就行了。

neocomplete 相关的设定

加载自定义词典。

词典可以在github上找到很多整理好的。比如下面配置的词典可以在这里找到。

1
2
3
4
5
6
7
8
" ~/.vimrc
let s:neco_dicts_dir = $HOME . '/dicts'
if isdirectory(s:neco_dicts_dir)
let g:neocomplete#sources#dictionary#dictionaries = {
\ 'ruby': s:neco_dicts_dir . '/ruby.dict',
\ 'javascript': s:neco_dicts_dir . '/jquery.dict',
\ }
endif

当用户按下.以及::的时候弹出补完提示。

1
2
3
4
 if !exists('g:neocomplete#force_omni_input_patterns')
let g:neocomplete#force_omni_input_patterns = {}
endif
let g:neocomplete#force_omni_input_patterns.ruby = '[^. *\t]\.\w*\|\h\w*::'
vim

使用puppeteer操作headless chrome获取coincheck聊天版内容

交易所的聊天版是涨跌信息材料的重要来源,这次我们用puppeteer来获取coincheck的聊天版信息。

puppeteer可以很方便操作headless-chrome来爬取网页,另外可以很方便监听页面上的各种事件,ajax和websocket也不需要担心跨域问题。

经过调查发现,coincheck的聊天版通过定时调用ajax获取聊天信息更新。获取这个ajax的内容使用puppeteer非常简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://coincheck.com/ja/chats');
page.on('response', response => {
response.text().then(function (textBody) {
try {
chats = JSON.parse(textBody).chats;
for(let i=0; i < chats.length; i++) {
console.log(chats[i].name + ": " + chats[i].content)
}
} catch(e) {
}
})
})
})();

为了大家方便使用上传github了。
自取

启用ufw屏蔽来自特定IP的恶意攻击

最近发现服务器很卡,看了一下access log发现有F5侠持续不断地请求大容量的request。

1
2
3
4
5
6
7
8
9
$ tail -f /var/log/nginx/access.log

54.173.0.75 - - [26/Sep/2017:06:25:05 +0900] "GET /content.json?q=%E6%B1%9F%E6%B3%BD%E6%B0%91&start=1&num=10 HTTP/1.1" 200 147128 "-" "-"
54.173.0.75 - - [26/Sep/2017:06:25:05 +0900] "GET /content.json?q=%E6%B1%9F%E6%B3%BD%E6%B0%91&start=1&num=10 HTTP/1.1" 200 81592 "-" "-"
54.173.0.75 - - [26/Sep/2017:06:25:05 +0900] "GET /content.json?q=%E6%B1%9F%E6%B3%BD%E6%B0%91&start=1&num=10 HTTP/1.1" 200 147128 "-" "-"
54.173.0.75 - - [26/Sep/2017:06:25:05 +0900] "GET /content.json?q=%E6%B1%9F%E6%B3%BD%E6%B0%91&start=1&num=10 HTTP/1.1" 200 147128 "-" "-"
54.173.0.75 - - [26/Sep/2017:06:25:14 +0900] "GET /content.json?q=%E6%B1%9F%E6%B3%BD%E6%B0%91&start=1&num=10 HTTP/1.1" 200 166855 "-" "-"
54.173.0.75 - - [26/Sep/2017:06:25:14 +0900] "GET /content.json?q=%E6%B1%9F%E6%B3%BD%E6%B0%91&start=1&num=10 HTTP/1.1" 200 166855 "-" "-"
...

这个时候就应该由ufw这个iptable的wrapper登场了。

开启防火墙

1
$sudo ufw enable

修改默认策略

默认策略是全部拒绝,所以,为了防止把自己关在墙外,首先将默认策略改成全部allow。

1
sudo ufw default ALLOW

屏蔽特定ip

1
sudo ufw deny from 54.173.0.75

更多参考

ufw

微信小程序真机测试的一些坑

wx.request 只支持get和post

在官方IDE中我们使用patch和delete都是ok的,但是一旦到了真机,发现wx.request根本不发出相应的request。
如果后端主导权在开发者,那很简单了,添加post的endpoint就是。否则就哭去吧。

自定义font需要转成base64放入

官方IDE中导入了fontawesome,直接把fontawesome的字体文件下下来在fontface中引用完全没问题,到了真机就不行了。
具体做法可以参照这里

开发环境和生产环境的切换

global的配置总是没有一个好的方法,建议直接写死,发布之前用sed替换掉。
比如下面的例子

1
grep -rl <dev_host> . | xargs sed -i '' 's/<dev_host>/<prod_host>/g'

之后逐渐补充

Ethereum 入坑的基本备忘

最近开始学习Ethereum(以太坊)以及智能协议。由于以太坊相比比特币要复杂太多,所以梳理清楚概念尤其重要。

什么是Smart Contracts(智能协议)

可以把contract看成是持久化在ethereum 的blockchain的一段程序。智能协议和普通的用户节点一样,拥有地址,可以向智能协议转账,智能协议也可以向用户转账。用户可以调用智能协议定义的函数完成一系列功能。

智能协议下的Transaction(转账)

智能协议下的转账可以分为,单纯转出转入以太币,协议的部署,更新 这集中。协议的部署即把编译好的协议写入到以太坊的blockchain中。而协议的更新就是更新已经持久化在blockchain中的一些变量的数值。我们可以把智能协议看成是一个永远不会被释放的运行在内存中的程序。我们可以改变变量的值,调用程序中的函数。

智能协议的书写方式

智能协议多采用Solidity书写。Solidity是面向智能协议编程的静态编译语言。solidity的编译器为Solc,一般简单的项目可以使用钱包自带的强大的IDE一般的功能书写。比如Mist钱包

如何调用已经存在BlockChain上面的智能协议?

调用智能协议需要知道智能协议的地址,以及ABI(源码通过编译器在本地编译的时候会产生ABI, Mist钱包会自动帮你记录ABI), ABI就像是C语言的头文件一样,知道了智能协议地址以及ABI,就可以调用ABI中定义的函数了。

gas 和 ether

部署,执行智能协议需要消耗gas,gas相当于燃料一般,需要用ether换取。一般gas 和 ether之间又稳定的换取价格。
那么为什么执行智能协议不直接消耗ether,而要在中间放一个gas呢? 那是因为ether的价格变动很大,而执行智能协议的cost相对是固定的,如果用ether来计算,那么执行智能协议的cost也会有很大波动。

Ethereum Token的实现方式

基于以太坊智能协议,用户可以发行自己的货币。
具体例子可以参考这里, 我们发现用mist钱包可以很方便追踪自己有多自己创建的货币。我们知道,我们自己发行的货币也是一个智能协议,需要调用智能协议必须知道智能协议的地址和ABI,那么当我们watch一个自己持有的货币的数量,以及转账的时候,mist钱包是怎么知道这个货币协议的ABI的呢?原来其中有个公认的标准协议,只要按照这个标准协议来设计函数,那么MIST钱包就可以很方便套用上固定的ABI啦,我们只需要提供协议地址即可。

暂时先写这么多。