一、安装Docker运行环境
1.使用apt-get命令安装Docker容器:
$sudo apt-get install docker.io
2.查看Docker版本
$docker –version
y@ubuntu:/usr/local/bin$ docker --version
Docker version 17.12.1-ce, build 7390fc6
y@ubuntu:/usr/local/bin$
看到类似信息说明安装成功
二、安装和运行比特币测试网络(bitcoin-testnet)
1.下载比特币测试网络(bitcoin-testnet)的Docker镜像
$sudo docker pull freewil/bitcoin-testnet-box
2.运行Docker镜像
$sudo docker run -t -i -p 19001:19001 -p 19011:19011 freewil/bitcoin-testnet-box
y@ubuntu:~$ sudo docker run -t -i -p 19001:19001 -p 19011:19011 freewil/bitcoin-testnet-box
tester@647e5bee8412:~/bitcoin-testnet-box$
该命令执行完后即进入Docker运行环境
注:该命令中的19001和19011是配置给两个节点提供RPC服务的端口。
3.进入Docker运行环境后,输入下面的命令来启动两个比特币节点,从而组成比特币测试网络:
$ make start
tester@647e5bee8412:~/bitcoin-testnet-box$ make start
bitcoind -datadir=1 -daemon
Bitcoin server starting
bitcoind -datadir=2 -daemon
Bitcoin server starting
tester@647e5bee8412:~/bitcoin-testnet-box$
启动成功后,将在本机模拟运行两个比特币测试钱包节点,组成一个私有范围的比特币测试网络。
输入下面的命令可以查看测试网络节点状态信息:
$ make getinfo
结果:
bitcoin-cli -datadir=1 getinfo //第一个钱包节点的信息
{
“version”: 120100,
“protocolversion”: 70012,
“walletversion”: 60000,
“balance”: 0.00000000,
“blocks”: 0,
“timeoffset”: 0,
“connections”: 1,
“proxy”: “”,
“difficulty”: 4.656542373906925e-10,
“testnet”: false,
“keypoololdest”: 1467253951,
“keypoolsize”: 101,
“paytxfee”: 0.00000000,
“relayfee”: 0.00001000,
“errors”: “”
}
bitcoin-cli -datadir=2 getinfo //第二个钱包节点的信息
{
“version”: 120100,
“protocolversion”: 70012,
“walletversion”: 60000,
“balance”: 0.00000000,
“blocks”: 0,
“timeoffset”: 0,
“connections”: 1,
“proxy”: “”,
“difficulty”: 4.656542373906925e-10,
“testnet”: false,
“keypoololdest”: 1467253951,
“keypoolsize”: 101,
“paytxfee”: 0.00000000,
“relayfee”: 0.00001000,
“errors”: “”
}
注意:在比特币0.16.0.之后的版本中bitcoin-cli getinfo命令已经被移除了,被bitcoin-cli getblockchaininfo,
bitcoin-cli getnetworkinfo,bitcoin-cli getwalletinfo替代,所以在新版本中直接运行上面的make getinfo命令会提示出错,这时需要修改docker环境中的 /home/tester/bitcoin-testnet-box 路径下的Makefile脚本,在该脚本中添加如下内容:
getblockchaininfo:
$(BITCOINCLI) $(B1) getblockchaininfo
$(BITCOINCLI) $(B2) getblockchaininfo
getnetworkinfo:
$(BITCOINCLI) $(B1) getnetworkinfo
$(BITCOINCLI) $(B2) getnetworkinfo
getwalletinfo:
$(BITCOINCLI) $(B1) getwalletinfo
$(BITCOINCLI) $(B2) getwalletinfo
这样就可以运行make getblockchaininfo, make getnetworkinfo, make getwalletinfo命令获取相应的信息了。
因此高版本的比特币客户端需要运行make getwalletinfo等命令来查看节点信息:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make getwalletinfo
bitcoin-cli -datadir=1 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 0.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 0.00000000,
"txcount": 0,
"keypoololdest": 1531366844,
"keypoolsize": 1000,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "0ac63ad922d529b4ff4be71a10f1751c3978b5f5"
}
bitcoin-cli -datadir=2 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 0.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 0.00000000,
"txcount": 0,
"keypoololdest": 1531366844,
"keypoolsize": 1000,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "78f6a0f992aae42ff3504477f150a65e86c1f287"
}
我们可以顺便查看下两个节点的bitcoin.conf文件是如何配置的
节点1的配置文件,路径:/home/tester/bitcoin-testnet-box/1/bitcoin.conf
# testnet-box functionality
regtest=1
dnsseed=0
upnp=0
# listen on different ports than default testnet
port=19000
rpcport=19001
# always run a server, even with bitcoin-qt
server=1
# enable SSL for RPC server
#rpcssl=1
rpcallowip=0.0.0.0/0
rpcuser=admin1
rpcpassword=123
节点2的配置文件,路径:/home/tester/bitcoin-testnet-box/2/bitcoin.conf
# testnet-box functionality
regtest=1
dnsseed=0
upnp=0
# don't listen on a port, just connect to node 1
listen=0
connect=127.0.0.1:19000
# listen on different ports than default testnet
port=19010
rpcport=19011
# always run a server, even with bitcoin-qt
server=1
# enable SSL for RPC server
#rpcssl=1
rpcallowip=0.0.0.0/0
rpcuser=admin2
rpcpassword=123
再顺便查看下节点1的对等节点的信息:
tester@0cc1d63a966c:~/bitcoin-testnet-box$ bitcoin-cli -datadir=1 getpeerinfo
[
{
"id": 0,
"addr": "127.0.0.1:52766",
"addrbind": "127.0.0.1:19000",
"services": "000000000000040d",
"relaytxes": true,
"lastsend": 1531383259,
"lastrecv": 1531383259,
"bytessent": 429,
"bytesrecv": 453,
"conntime": 1531383259,
"timeoffset": 0,
"pingtime": 0.002959,
"minping": 0.002959,
"version": 70015,
"subver": "/Satoshi:0.16.0/",
"inbound": true,
"addnode": false,
"startingheight": 0,
"banscore": 0,
"synced_headers": -1,
"synced_blocks": -1,
"inflight": [
],
"whitelisted": false,
"bytessent_per_msg": {
"feefilter": 32,
"getheaders": 93,
"ping": 32,
"pong": 32,
"sendcmpct": 66,
"sendheaders": 24,
"verack": 24,
"version": 126
},
"bytesrecv_per_msg": {
"feefilter": 32,
"getaddr": 24,
"getheaders": 93,
"ping": 32,
"pong": 32,
"sendcmpct": 66,
"sendheaders": 24,
"verack": 24,
"version": 126
}
}
]
节点2的对等节点的信息:
tester@0cc1d63a966c:~/bitcoin-testnet-box$ bitcoin-cli -datadir=2 getpeerinfo
[
{
"id": 0,
"addr": "127.0.0.1:19000",
"addrbind": "127.0.0.1:52766",
"services": "000000000000040d",
"relaytxes": true,
"lastsend": 1531383380,
"lastrecv": 1531383380,
"bytessent": 517,
"bytesrecv": 493,
"conntime": 1531383259,
"timeoffset": 0,
"pingtime": 0.000204,
"minping": 0.000204,
"version": 70015,
"subver": "/Satoshi:0.16.0/",
"inbound": false,
"addnode": true,
"startingheight": 0,
"banscore": 0,
"synced_headers": -1,
"synced_blocks": -1,
"inflight": [
],
"whitelisted": false,
"bytessent_per_msg": {
"feefilter": 32,
"getaddr": 24,
"getheaders": 93,
"ping": 64,
"pong": 64,
"sendcmpct": 66,
"sendheaders": 24,
"verack": 24,
"version": 126
},
"bytesrecv_per_msg": {
"feefilter": 32,
"getheaders": 93,
"ping": 64,
"pong": 64,
"sendcmpct": 66,
"sendheaders": 24,
"verack": 24,
"version": 126
}
}
]
4.初始化和测试区块链数据
查看钱包地址
比特币核心客户端维护的地址池以及自动生成的地址的相关知识可以参考
《精通比特币》钱包地址及接收交易
比特币核心客户端维护了一个地址池,地址池的大小可以用getinfo命令的返回结果的keypoolsize参数获取。这些地址是自动生成的,可以被用作公开接收地址或零钱地址。使用getnewaddress命令可以获得其中的一个地址:
$ bitcoin-cli getnewaddress
1hvzSofGwT8cjb8JU7nBsCSfEVQX5u9CL
现在我们可以使用这个地址从一个外部钱包(假设你在其他交易所、在线钱包或其他bitcoind钱包有一些比特币)向我们的bitcoind钱包发送一小笔比特币。
使用getnewaddress命令分别为两个钱包生成一个地址(或者用命令 make address1 也可以):
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ bitcoin-cli -datadir=1 getnewaddress
2NAUVNvRVKn2QT2yoKYo1LXBBHES1DiiAWp
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ bitcoin-cli -datadir=2 getnewaddress
2N5czXHSEFronnYvMHUhSinQW8jjp7UjRtu
查看地址对应的私钥:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ bitcoin-cli -datadir=1 dumpprivkey 2NAUVNvRVKn2QT2yoKYo1LXBBHES1DiiAWp
cP5cEwanYgwJTUA6RG43DQ9p3ErpmqdPrJK7kX48zaMKkEfoL8s3
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ bitcoin-cli -datadir=2 dumpprivkey 2N5czXHSEFronnYvMHUhSinQW8jjp7UjRtu
cQ8UyP5CoJ2SbHXdJagxxHSjYnxd69kaCaSU7uMPq6iRxpEhpuYP
注意:在正式的比特币网络环境下,平均是10分钟左右才能产生一个新的区块。但在这里的测试网络(testnet)特殊设定的环境下,区块是通过简单的命令控制就可以即时和批量产生的,方便程序开发测试。
生成一个区块:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make generate
bitcoin-cli -datadir=1 generate 1
[
"5db89a9818792f8665b6540d32c3834856cb6a07ed34aecb03128e96cbe3658a"
]
继续生成9个区块:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make generate BLOCKS=9
bitcoin-cli -datadir=1 generate 9
[
"61bc358db1ddb82972b830a00cb1dd27a7e6f3f5b409d667ff90af7a72caeb75",
"0eedb9ecb498df0e638013343ca97189ca768c54592ed5155a2ccbedf13f5309",
"7f74386d70b295102c5e44e373232648f7c07e00918c0b6de1ad033c3c121b38",
"7ca80b7bf1209d18e56b5c399992171c074c566e3109376b09877401b86a0b1d",
"61f0b2f3f4d2d4d199d7cbbed9bba721e65de3e30f474042c0eb4ce4cfc1ad54",
"2f97d16c46e5ccc46b795b9ee72f58720c494ae0f48d98d70a5b5a9e8b5be2ba",
"26edd9fd85b3e75ba7e731596ac065afbc29f68d8a6dd16f928d1e898ae18fb6",
"684fa2b10a662bffdd7e4e148e3a73c430cf7bbc14d0ed320200e008dd1ea625",
"2b62353790c59d2e643c815d56952264052dd99876a61e0d46e81accd7661262"
]
此时查看钱包信息:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make getwalletinfo
bitcoin-cli -datadir=1 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 0.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 500.00000000,
"txcount": 10,
"keypoololdest": 1531366844,
"keypoolsize": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "0ac63ad922d529b4ff4be71a10f1751c3978b5f5"
}
bitcoin-cli -datadir=2 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 0.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 0.00000000,
"txcount": 0,
"keypoololdest": 1531366844,
"keypoolsize": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "78f6a0f992aae42ff3504477f150a65e86c1f287"
}
结果显示钱包1的balance(余额)里根本没有任何比特币,但immature_balance(未成熟的余额)里有相应的500个比特币,这是为什么呢?
先查询区块信息:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make getblockchaininfo
bitcoin-cli -datadir=1 getblockchaininfo
{
"chain": "regtest",
"blocks": 20,
"headers": 20,
"bestblockhash": "2de6833c63b96e2c072fb1f21c1b596adfbd7c2798576375b56b1f024f7145ce",
"difficulty": 4.656542373906925e-10,
"mediantime": 1531368565,
"verificationprogress": 1,
"initialblockdownload": false,
"chainwork": "000000000000000000000000000000000000000000000000000000000000002a",
"size_on_disk": 6517,
"pruned": false,
"softforks": [
{
"id": "bip34",
"version": 2,
"reject": {
"status": false
}
},
{
"id": "bip66",
"version": 3,
"reject": {
"status": false
}
},
{
"id": "bip65",
"version": 4,
"reject": {
"status": false
}
}
],
"bip9_softforks": {
"csv": {
"status": "defined",
"startTime": 0,
"timeout": 9223372036854775807,
"since": 0
},
"segwit": {
"status": "active",
"startTime": -1,
"timeout": 9223372036854775807,
"since": 0
}
},
"warnings": ""
}
bitcoin-cli -datadir=2 getblockchaininfo
{
"chain": "regtest",
"blocks": 20,
"headers": 20,
"bestblockhash": "2de6833c63b96e2c072fb1f21c1b596adfbd7c2798576375b56b1f024f7145ce",
"difficulty": 4.656542373906925e-10,
"mediantime": 1531368565,
"verificationprogress": 1,
"initialblockdownload": false,
"chainwork": "000000000000000000000000000000000000000000000000000000000000002a",
"size_on_disk": 6517,
"pruned": false,
"softforks": [
{
"id": "bip34",
"version": 2,
"reject": {
"status": false
}
},
{
"id": "bip66",
"version": 3,
"reject": {
"status": false
}
},
{
"id": "bip65",
"version": 4,
"reject": {
"status": false
}
}
],
"bip9_softforks": {
"csv": {
"status": "defined",
"startTime": 0,
"timeout": 9223372036854775807,
"since": 0
},
"segwit": {
"status": "active",
"startTime": -1,
"timeout": 9223372036854775807,
"since": 0
}
},
"warnings": ""
}
结果显示,钱包1和钱包2都有20个区块了,没有什么问题,那么为什么钱包1的balance里没有比特币呢?
继续创建200个区块:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make generate BLOCKS=200
再查询钱包余额:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make getwalletinfo
bitcoin-cli -datadir=1 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 6000.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 3225.00000000,
"txcount": 220,
"keypoololdest": 1531366844,
"keypoolsize": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "0ac63ad922d529b4ff4be71a10f1751c3978b5f5"
}
bitcoin-cli -datadir=2 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 0.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 0.00000000,
"txcount": 0,
"keypoololdest": 1531366844,
"keypoolsize": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "78f6a0f992aae42ff3504477f150a65e86c1f287"
}
结果显示钱包1的balance(余额)里6000个比特币了。
到这里,可以初步得出结论是之前生成的20个区块还太”新鲜”,不够”老”,需要后面生成更多的区块来完成确认。
(参考New to zPool and mining in general. Have a few questions.
Wallet Balance ‘Immature’? )
(补充:后来查询资料知道,挖矿所得的coinbase交易中的奖励必须要在100个区块深度之后才能花费。)
给钱包2转账,这里转10个比特币:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make sendfrom1 ADDRESS=2N5czXHSEFronnYvMHUhSinQW8jjp7UjRtu AMOUNT=10
bitcoin-cli -datadir=1 sendtoaddress 2N5czXHSEFronnYvMHUhSinQW8jjp7UjRtu 10
967d37c71c1f768ff75e8ee675cf0dc5899a953bb4954b3b0f8ad3f25fc2aa52
这时,查询钱包余额:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make getwalletinfo
bitcoin-cli -datadir=1 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 5989.99996240,
"unconfirmed_balance": 0.00000000,
"immature_balance": 3225.00000000,
"txcount": 221,
"keypoololdest": 1531366844,
"keypoolsize": 1000,
"keypoolsize_hd_internal": 999,
"paytxfee": 0.00000000,
"hdmasterkeyid": "0ac63ad922d529b4ff4be71a10f1751c3978b5f5"
}
bitcoin-cli -datadir=2 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 0.00000000,
"unconfirmed_balance": 10.00000000,
"immature_balance": 0.00000000,
"txcount": 1,
"keypoololdest": 1531366844,
"keypoolsize": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "78f6a0f992aae42ff3504477f150a65e86c1f287"
}
结果显示钱包2的10个比特币还未确认。
好办,继续生成10个区块,使得交易得到确认:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make generate BLOCKS=10
bitcoin-cli -datadir=1 generate 10
[
"51179ee5ec0045fbf9d613cb5f198586a6eaabb0451c0cd01f5658d493b15b3a",
"150a194f26bfbf070462634385e9a0e6e84a37de8df8bb0da8d0493767c30e8e",
"509aebd0e4e4ccc26fbd79f3c650164a910bb8a655c3e7fd6a9b74d3233b2b6b",
"3251b42a85be56bb1090be4080c08404454dd93a6422d14dbf89b9adbb5820e9",
"6a62a1c5503e59f99dec0e7396e66bb382dcb9dad18f611a1016142caa846d4e",
"51238df8ad8ba89b80444bbcd481af73920d7ad719bb56be7e1699bb069c41fc",
"12b418901cab48d1762648ccc24e5ddf0dfe56f9c5784cafb3c1daa966d886fa",
"32792fc562d41dc27095a9e1da0d9a26c2cbb829a785adcf320c81b77163bf9a",
"46b60cac3acfcce51a2cde849ebce36467e6d845fc59b61b864209bec2dbc4fa",
"3b332474313427a28dc7a29b59a2fad10a8c4d75e5b6ce5f57b637d83234c4ce"
]
这时,再查看钱包余额:
tester@0f4ec9f7a91a:~/bitcoin-testnet-box$ make getwalletinfo
bitcoin-cli -datadir=1 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 6489.99996240,
"unconfirmed_balance": 0.00000000,
"immature_balance": 2975.00003760,
"txcount": 231,
"keypoololdest": 1531366844,
"keypoolsize": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "0ac63ad922d529b4ff4be71a10f1751c3978b5f5"
}
bitcoin-cli -datadir=2 getwalletinfo
{
"walletname": "wallet.dat",
"walletversion": 159900,
"balance": 10.00000000,
"unconfirmed_balance": 0.00000000,
"immature_balance": 0.00000000,
"txcount": 1,
"keypoololdest": 1531366844,
"keypoolsize": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0.00000000,
"hdmasterkeyid": "78f6a0f992aae42ff3504477f150a65e86c1f287"
}
从结果可以看到钱包2的10个比特币到账了,说明交易得到了确认。
参考:
比特币区块链开发由浅入深指南(二)
https://hub.docker.com/r/freewil/bitcoin-testnet-box/
https://github.com/freewil/bitcoin-testnet-box