使用Bitcoin做一个小游戏的记录
这是用来熟悉比特币核心的课程作业。由于在实现过程中遇到了一些坑,所以记录一下。
搭建比特币核心私有链开发环境
首先,需要编译比特币核心。我预测到了在自己mac上编译极有可能出错,于是一开始就选择在服务器上编译了,其环境是 Ubuntu 16.04 。
想来大家都不想因为一个作业去买比特币吧,所以需要在私有链中开发。
我根据 搭建比特币私有链开发环境 - 小一辈无产阶级码农 完成搭建,
补充:
- apt install 直接复制并不能全部下载好,要逐一Y/n
- 编译过程中cpu不行,根据报错去找一下博客,可以解决
- Build.md 里有autogen.sh的用法
API列表
可以看见上面的博客中的命令都是 bitcoin-cli
命令,Bitcoin 提供了两种 API ,另一种是 cURL 命令。
更多的命令可以到官网查看 Bitcoin Core APIs 。
从 Bitcoin Cour APIs remote-procedure-calls-rpcs 可以看到 cURL 是和 bitcoin-cli 一致的。
确认交易
在进行几次交易后我发现钱包的余额并没有改变,根据 比特币 BTC本地测试节点 知道了需要生成区块来进行确认。
1
2
#生成一个区块,使得交易得到确认(测试网络使用)
bitcoin-cli -regtest generate 1
好了,本地比特币核心私有链开发环境搭建好了,接下来需要做的是远程访问它的接口。
远程访问
首先我配置了 bitcoin.conf ,这个根据一些博客就可以做到。
- 比特币节点远程访问 https://imzy.vip/posts/42988/
- 比特币核心部署并通过RPC在远程机器调用
碰到了问题:Connection Refused。
What causes the ‘Connection Refused’ message?
- Nothing is listening on the IP:Port you are trying to connect to.
- The port is blocked by a firewall.
我排除了防火墙,由于这个服务器本来就是用来翻强的,所以其中的一个端口也能正常访问(就是下面的1024端口)。
查看端口是否开放
ubuntu 下查看哪些端口是开放的,分别是什么进程在监听,发现8332(我虽然用的是regtest模式,但还是用了这个端口)只有本地能访问,不对全网开(更多可见 Linux的netstat查看端口是否开放见解(0.0.0.0与127.0.0.1的区别))。
1
2
3
4
5
6
7
8
9
10
# sudo netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:18444 0.0.0.0:* LISTEN 21877/bitcoind
tcp 0 0 127.0.0.1:8332 0.0.0.0:* LISTEN 21877/bitcoind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1173/sshd
tcp 0 0 0.0.0.0:1024 0.0.0.0:* LISTEN 1656/python
tcp6 0 0 :::18444 :::* LISTEN 21877/bitcoind
tcp6 0 0 ::1:8332 :::* LISTEN 21877/bitcoind
tcp6 0 0 :::22 :::* LISTEN 1173/sshd
尝试了几次修改 bitcoin.conf 没有成效之后,我就在命令行里直接设置 rpcallowip 了。
1
bitcoind -regtest -datadir=/data/bitcoin/ -rpcuser=user -rpcpassword=password -rpcport=8332 -daemon -rest -deprecatedrpc=accounts -rpcallowip='0.0.0.0/0'
但是有点奇怪,tcp里面8332端口没了。
1
2
3
4
5
6
7
8
9
root@vultr:~# sudo netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:18444 0.0.0.0:* LISTEN 15480/bitcoind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1173/sshd
tcp 0 0 0.0.0.0:1024 0.0.0.0:* LISTEN 1656/python
tcp6 0 0 :::18444 :::* LISTEN 15480/bitcoind
tcp6 0 0 :::8332 :::* LISTEN 15480/bitcoind
tcp6 0 0 :::22 :::* LISTEN 1173/sshd
在自己电脑上尝试连接:
1
telnet 45.77.36.113 8332
结果连上了。查了一下,虽然只显示了8332的ipv6的地址,但是通过ipv4也能访问。我看到为什么 netstat 对某些服务只显示了 tcp6 监听端口说,netstat 只是很真实的显示监听的端口而已,但是需要注意 ipv6 实际上在 Linux 上也支持 ipv4 。
用 curl 远程访问 API
1
curl --user user:password --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getnetworkinfo", "params": [] }' -H 'content-type: text/plain;' http://45.77.36.113:8332/
在 Python 里访问 API
在python里写requests访问请求的时候,发现了一个好用的工具:curl to python requests
小游戏实现过程
小游戏模仿了 silly-gamble ,逻辑简单不复杂,不过这个 silly-gamble 是玩真的,它使用的 API Server 也没法为私有链提供服务,但是可以用 test mode 试玩一下。
游戏规则:
4张卡片中有一张是有奖励的,奖励/赌注是随机的,你可以选择一张,选对了你将获得奖励,选错了你的赌注就没了。(这真的是稳赚不赔)
我先写了一个封装远程访问请求的类,再写了小游戏的代码。由于赶时间,一切从简。