比特币客户端&比特币回归测试网络
实验概述
区块链技术需要协调一个庞大的去中心化网络以实现功能复杂的分布式状态机副本,必然涉及频繁的指令交互。在此过程中,除了设计功能完备、高鲁棒性的客户端程序,作为构建和调试分布式系统的重要协议,RPC(远程过程调用)也是实现上述功能不可或缺的工具。
本实验以比特币的开源客户端 Bitcoin Core 为例,介绍回归测试网络的搭建方法以及重要 RPC 指令的使用技巧,进而部署一个多节点的本地区块链网络,测试区块链账本层的诸多功能。以此加深学生对于区块链基础协议的理解,提高对于区块链功能的实践能力,实验传授的基本技能也是区块链复杂协议调试过程中的必备积淀。
实验内容概述如下:
A. 掌握 Bitcoin Core 的基础知识、安装与配置方法
B. 利用 Bitcoin Core 搭建多节点回归测试网络,实现挖矿与交易
C. 了解 RPC 的作用,通过控制台与测试链进行更加丰富的交互
D. 拓展实验:利用回归测试网络模拟并测试复杂的区块链状态与功能(分叉、多签交易、局域网联机测试等)
预备知识
1.RPC:远程过程调用(Remote Procedure Control),该类协议可完成网络环境下的对象之间的消息传递工作,传递调用的语义和数据,并从远程计算机程序上请求服务,调用该计算机上提供的函数/方法。
经典的场景下,RPC 最多应用于客户端与服务端间的交互:
在区块链网络中,由于所有的全节点都是对称的,无论是轻节点还是全节点本身在发送一条 RPC 指令时,都需要将该指令广播给尽可能多的全节点,每个节点按照最新的区块链状态独立验证并处理该指令,最终通过区块链的共识算法完成对于该指令执行结果的共识。
2.Bitcoin Core:比特币官方开发的节点客户端,提供了成为全节点所需的全面功能,并为比特币的开发、测试和实际运行提供了友好的工具,包含 3 个主要程序:
1)bitcoin-qt:封装了完整的比特币全节点,并提供了一个带有 GUI 的钱包程序,可以对交易数据可视化,在钱包的帮助菜单中提供了控制台以发布多类RPC 指令,对普通用户更加友好。
2)bitcoind:提供了一个轻量级的封装好的比特币全节点,在部署后可以通过向其发布 RPC 指令与之交互,对开发者更加友好。
3)bitcoin-cli:提供了通过命令行全节点发送 RPC 指令的功能,一般用于与bitcoin-d 配合进行调试。
3.Bitcoin 支持的部署类型:
1)主链模式(Mainnet Mode)-原生态的区块链网络,运行需要庞大的存储、通信以及算力开销,其中流通的代币具备经济价值。
2)测试网络模式(Testnet Mode)-由热心开发者组成的全球测试环境,用于在真实的分布式场景下对区块链进行测试,其网络拓扑与区块产生过程都与主链类似,差别是代币没有任何价值。
3)回归测试模式(Regtest Mode)-用于开发者测试区块链功能的本地测试环境,测试者具备完整的权限,可以通过指令随意产生区块、创建没有实际价值的代币或测试任何区块链的实际功能。
以上模式的切换由改写比特币的配置文件的相关参数进行控制。
实验 3-1 熟悉 Bitcoin Core 的基本配置方法
3-1.1 熟悉比特币客户端的配置方法
比特币客户端的配置可以通过在命令行指令中赋值选项参数的方法进行配置,打开命令行,尝试输入口令 bitcoind -h,即可查阅所有的指令。
不过,每次重复输入已有的配置相对非常低效,更加常用的手段是将配置信息写入配置文件 bitcoin.conf 中,再通过命令行工具中的-datadir=
练习3-1.1
尝试打开以上地址,新建文件 bitcoin.conf,右击通过常用文本编辑器进行编辑(没有则用系统自带的记事本也可以),在文件第一行添加:regtest=1,保存后调出 cmd 命令行,运行指令:bitcoind,观察以上文件夹内的变化。
正常的情况下,比特币的回归测试模式被激活,bitcoind 建立了一个全节点,可以发现默认路径下出现了 regtest 目录,打开目录,目录中的前三个文件夹分别对应记录了该节点存储的区块数据,链上交易状态以及钱包的配置状态,打开debug.log,便可以阅读在这次测试过程中的调试日志信息。
实验流程
-
将比特币安装路径和比特币安装路径\daemon\添加到变量中,并检测环境是否配置成功;
-
打开地址%APPDATA%\Bitcoin\,新建文件 bitcoin.conf,右击通过常用文本编辑器进行编辑,在文件第一行添加:regtest=1,保存后调出 cmd 命令行,运行指令:bitcoind观察以上文件夹内的变化;
-
打开debug.log,阅读在这次测试过程中的调试日志信息。
实验结果截图
-
检测环境配置是否成功:
-
编辑%APPDATA%\Bitcoin\bitcoin.conf的文件内容:
- 运行指令:bitcoind,观察文件夹%APPDATA%\Bitcoin内的变化:
可以看到新增了regtest目录。
查看regtest目录内容:
查看debug.log,查看该次测试过程中的调试日志信息:
思考题
解读当前日志信息,回答以下问题:
1)测试中为存储链上交易状态初始化的数据空间是多少?
2)初始化过程中,节点钱包密钥池最终保存了多少对密钥?
3)简述回归测试模式下,程序添加 P2P 节点的步骤?
思考题回答
1)测试中为存储链上交易状态初始化的数据空间是多少?
答:
由上图可知,测试中为存储链上交易状态初始化的数据空间为8MiB。
2)初始化过程中,节点钱包密钥池最终保存了多少对密钥?
答:
答:由上图可知,节点钱包密钥池最终保存了2000对密钥。
3)简述回归测试模式下,程序添加 P2P 节点的步骤?
答:在区块链中增加新的区块并与ip端口绑定,然后加载P2P地址,重建peers.dat和banlist.dat;启动网线程,完成加载,然后开启其他线程,寻找新鲜的更新信息,最后接受版本信息。
3-1.2 学习 bitcoin.conf 的配置方法
练习3-1.2
实验流程
- 在%APPDATA%\Bitcoin\目录下,新建alice、bob、network三个文件夹,每个文件夹中分别建立一个bitcoin.conf文件,并进行配置;
- 三个节点皆配置完成后依次通过命令行输入 bitcoind -conf=%APPDATA%\Bitcoin\文件名启动三个全节点;
- 检验连接是否成功。
实验结果截图
- 对alice、bob、network三个文件夹下的bitcoin.conf文件分别进行配置,配置内容如下所示:
- 依次通过命令行启动三个节点:
- 打开任意一个节点的日志,发现如下节点成功连接的提示消息:
实验3-2 掌握常用 RPC 指令,利用回归测试网络实现挖矿与交易
练习3-2
实验步骤
-
进行regtest指令的优化;
-
为 alice 生成至少 150 BTC 的可用余额;
-
生成交易,由 alice 分别支付给 bob 2.5BTC,network 1.5BTC,并使交易入块获得确认;
-
展示时请分别用指令获取 bob 和 network 的余额,并展示承载上述关键
交易的区块原始数据。
实验结果截图
- 建立regtest.bat文件,文件内容如下所示:
- 将regtest.bat文件路径添加进入注册表:
- 同时运行alice、bob、network三个节点,保证全程一直开启;
1)为 alice 生成至少 150 BTC 的可用余额
- 使用节点alice生成300个区块:
- 查看alice的余额:
2)由 alice 分别支付给 bob 2.5BTC,network 1.5BTC
- bob和network分别生成一个新的地址:
- alice分别向bob、network生成的地址支付2.5、1.5个比特币:
- bob和network分别产生一个新的区块,使得交易入块:
3)用指令获取 bob 和 network 的余额,并展示承载上述关键交易的区块原始数据
- 查看bob和network的余额:
- 查看承载上述两次交易的区块原始数据:
实验 3-3 通过控制台与测试链进行更加丰富的交互
练习3-3
实验流程
-
关闭之前打开的运行 bitcoind 的命令行,启动alice、bob、network节点的qt客户端;
-
选择任意节点的钱包-帮助-调试窗口,切换到控制台菜单下,输入 getbalance 指令使前端更新正确的余额;
-
利用 rpc 指令将如下交易源数据解析为 JSON 格式:010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98b
fa76e290000000000ffffffff0280969800000000001976a914fdc7990956642433ea75ca
bdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a4
2b8ad44ce76b67a88ac00000000
实验结果截图
- 启动alice、bob、network三个节点的qt客户端,更新前端数据之后查看交易记录:
- 利用decoderawtransaction指令解析上述交易源数据可得:
思考题回答
**a.该交易的输入输出情况; **
答:该交易的输入为
"vin": [
{
"txid": "296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
],
包含交易的id和序列号;
输出为
"vout": [
{
"value": 0.10000000,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 fdc7990956642433ea75cabdcc0a9447c5d2b4ee OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"n4epMtJQQE2WkvjgspLnyoTWw6z9qbvdWF"
]
}
},
{
"value": 0.09890000,
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 d6c492056f3f99692b56967a42b8ad44ce76b67a OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"n16YP4DTiYAbYbdd7f3G7UjwCoCkwwhEiN"
]
}
}
]
包含两次交易的交易值、scriptPubKey、收款方地址。
b.该交易的数据量大小;
答:由size的大小可知该交易的数据量大小为119。
实验 3-4:利用回归测试网络模拟并测试复杂的区块链状态与功能
拓展实验 3-4.1
实验步骤
- 配置A、B、C三个节点,使得A与B、C相连但B与C不相连。
- 当三者均在线时,挖的区块均在一条链上。
- 将A下线,B和C继续挖一个区块。
- A重新上线,观察各节点所在链的数据块数量。
实验结果截图
- A、B、C同时上线并挖矿,可以看到A、B、C所在支链的数据块的数量相同。
- A下线,B、C各自挖不同数量的数据块(假设B>C),可以看到B、C所在的支链的数据块数量不再相同。
- A再次上线,可以看到,A、B、C所在支链的数据块数量立即取得同步,且数量与A未上线时B所在支链(较长)的数据块的数量相同,即较短的一条支链被遗忘,三节点在最长的链上继续往后的挖矿操作。