这是用来熟悉比特币核心的课程作业。由于在实现过程中遇到了一些坑,所以记录一下。

小游戏源代码

搭建比特币核心私有链开发环境

首先,需要编译比特币核心。我预测到了在自己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 ,这个根据一些博客就可以做到。

bitcoin.conf详解

碰到了问题:Connection Refused。

What causes the ‘Connection Refused’ message?

  1. Nothing is listening on the IP:Port you are trying to connect to.
  2. 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张卡片中有一张是有奖励的,奖励/赌注是随机的,你可以选择一张,选对了你将获得奖励,选错了你的赌注就没了。(这真的是稳赚不赔)

我先写了一个封装远程访问请求的类,再写了小游戏的代码。由于赶时间,一切从简。