dan-da / hd-wallet-addrs
一款命令行工具,用于查找已收到资金的比特币钱包地址。
Requires
- php: >=8.0
- ext-json: *
- dan-da/strictmode-php: ^1.0.2
- protonlabs/bitcoin: ^1.0.10
README
用于查找已收到资金的比特币HD钱包地址的命令行工具。
此工具主要做两件事
- 根据bip32规则推导出HD钱包地址(包括更改和接收)。
- 检查区块链以找到实际使用过的地址。(至少收到过一次资金)
该工具的Web前端可在以下位置找到:https://mybitprices.info/hd-wallet-addrs.html
支持常规HD钱包(单个地址)和多签钱包(例如Copay)。
如果提供了ypub或zpub密钥,将生成segwit地址。(ypub:segwit-p2sh,zpub:bech32)
报告可用格式为json、纯文本和html。可以通过命令行更改或重新排序列。
hd-wallet-addrs适用于任何需要发现其钱包中实际使用的地址(包括更改地址)的人。
构建此工具的动机是为了简化用于会计目的的已用钱包地址的提取。特别是与
- bitprices - 一个用于钱包定价历史和基于成本的会计的命令行实用程序。
- mybitprices.info - bitprices的简单易用的Web前端。
另请参阅:hd-wallet-derive -- 一个推导bip32地址和私钥的工具。
让我们看一些示例。
$ ./hd-wallet-addrs.php -g --xpub=xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR --logfile=/tmp/log.txt
--- Wallet Discovery Report ---
Found 3 Receive addresses and 2 Change addresses.
Receive -- Used: 3 Unused: 0
Change -- Used: 2 Unused: 0
+------------------------------------+---------+----------------+------------+------------+---------+
| addr | type | total_received | total_sent | balance | relpath |
+------------------------------------+---------+----------------+------------+------------+---------+
| 1Ge6rDuyCdYVGhXZjcK4251q67GXMKx6xK | Receive | 0.00120000 | 0.00100000 | 0.00020000 | 0/0 |
| 1NVsB73WmDGXSxv77sh9PZENH2x3RRnkDY | Receive | 0.00130000 | 0.00100000 | 0.00030000 | 0/1 |
| 1BkgqiHcvfnQ2wrPN5D2ycrvZas3nibMjC | Receive | 0.00040000 | 0.00000000 | 0.00040000 | 0/2 |
| 12SisoiXLUEbkytL5Pzia1jBY8gJP5XN8D | Change | 0.00184874 | 0.00000000 | 0.00184874 | 1/0 |
| 1CkvACVpFwkPnMG13w9kXXE9YcsiyL4pcY | Change | 0.00194876 | 0.00000000 | 0.00194876 | 1/1 |
+------------------------------------+---------+----------------+------------+------------+---------+
我们可以更改字段并指定使用bip44推导来生成绝对路径。
提示:当--derivation=relative(默认值)时,abspath列是空的。
$ ./hd-wallet-addrs.php -g --xpub=xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR --cols=type,abspath,relpath,addr --derivation=bip44 --logfile=/tmp/log.txt
--- Wallet Discovery Report ---
Found 3 Receive addresses and 2 Change addresses.
Receive -- Used: 3 Unused: 0
Change -- Used: 2 Unused: 0
+---------+--------------+---------+------------------------------------+
| type | abspath | relpath | addr |
+---------+--------------+---------+------------------------------------+
| Receive | m/44/0/0/0/0 | 0/0 | 1Ge6rDuyCdYVGhXZjcK4251q67GXMKx6xK |
| Receive | m/44/0/0/0/1 | 0/1 | 1NVsB73WmDGXSxv77sh9PZENH2x3RRnkDY |
| Receive | m/44/0/0/0/2 | 0/2 | 1BkgqiHcvfnQ2wrPN5D2ycrvZas3nibMjC |
| Change | m/44/0/0/1/0 | 1/0 | 12SisoiXLUEbkytL5Pzia1jBY8gJP5XN8D |
| Change | m/44/0/0/1/1 | 1/1 | 1CkvACVpFwkPnMG13w9kXXE9YcsiyL4pcY |
+---------+--------------+---------+------------------------------------+
或获取一个列表以方便复制/粘贴。
$ ./hd-wallet-addrs.php -g --xpub=xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR --format=addrlist --logfile=/tmp/log.txt
--- Wallet Discovery Report ---
Found 3 Receive addresses and 2 Change addresses.
Receive -- Used: 3 Unused: 0
Change -- Used: 2 Unused: 0
1Ge6rDuyCdYVGhXZjcK4251q67GXMKx6xK
1NVsB73WmDGXSxv77sh9PZENH2x3RRnkDY
1BkgqiHcvfnQ2wrPN5D2ycrvZas3nibMjC
12SisoiXLUEbkytL5Pzia1jBY8gJP5XN8D
1CkvACVpFwkPnMG13w9kXXE9YcsiyL4pcY
或JSON
./hd-wallet-addrs.php -g --xpub=xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR --cols=type,abspath,relpath,addr --format=jsonpretty --derivation=bip44 --logfile=/tmp/log.txt
[
{
"type": "Receive",
"abspath": "m\/44\/0\/0\/0\/0",
"relpath": "0\/0",
"addr": "1Ge6rDuyCdYVGhXZjcK4251q67GXMKx6xK"
},
...
]
或CSV
./hd-wallet-addrs.php -g --xpub=xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR --cols=type,abspath,relpath,addr --format=csv --derivation=bip44 --logfile=/tmp/log.txt
type,abspath,relpath,addr
Receive,m/44/0/0/0/0,0/0,1Ge6rDuyCdYVGhXZjcK4251q67GXMKx6xK
Receive,m/44/0/0/0/1,0/1,1NVsB73WmDGXSxv77sh9PZENH2x3RRnkDY
Receive,m/44/0/0/0/2,0/2,1BkgqiHcvfnQ2wrPN5D2ycrvZas3nibMjC
Change,m/44/0/0/1/0,1/0,12SisoiXLUEbkytL5Pzia1jBY8gJP5XN8D
Change,m/44/0/0/1/1,1/1,1CkvACVpFwkPnMG13w9kXXE9YcsiyL4pcY
多签示例。
到目前为止,多签已与copay(bip44和bip45)进行了测试。使用bip45的较旧版本的Copay需要--derivation=copaylegacy标志。
多签需要多个xpub密钥和--numsig标志来指示所需的签名者数量(m of n)。
发现一个空的Copay 1.6.3+(bip44)2 of 3钱包。
此测试钱包没有任何资金,因此我们使用--include-unused来获取初始地址直到差距限制。差距限制的默认值为20,但在这里我们使用2以简化。
$ ./hd-wallet-addrs.php -g --numsig=2 --gap-limit=2 --xpub=xpub6CZte6DfeMoVwxv3ShiMwQjET47nRENqrkZaSXTcP7Yaja6sxyRbiyqPD7kfy4W2dTTuTdV4jHMmSe1k1qteTMN7qDLndt1RfQ8RLM3pjzb,xpub6DUGj5hRwp7t3DoH554Ce7p3KLepccYfG5BVbvyPSArTepacc3aPRDTMz3GSdoX1HgVYKBSaR6fFDm1daEtSQFBSNTq4X93pd8dBFyPW2gz,xpub6DRFPDtHueJ5sfqzcLSyoKL6TQZMofvjpLzsVXsWqjgYuAtUtdU8YjWFvpa2xegWLFeLQ38KLJzWdKQ3CsAQQLoMYnBsQy3FCeTDuxgcsfK --include-unused --logfile=/tmp/out.txt
--- Wallet Discovery Report ---
Found 2 Receive addresses and 2 Change addresses.
Receive -- Used: 0 Unused: 2
Change -- Used: 0 Unused: 2
+------------------------------------+---------+----------------+------------+------------+---------+
| addr | type | total_received | total_sent | balance | relpath |
+------------------------------------+---------+----------------+------------+------------+---------+
| 339H3pYP9AKiEo74D1BWiSK8jhWXsrJ3yk | Receive | 0.00000000 | 0.00000000 | 0.00000000 | 0/0 |
| 3NcBBWtDscKchgkUCY3eEQZgYh8STtcona | Receive | 0.00000000 | 0.00000000 | 0.00000000 | 0/1 |
| 3QtjkbY8Km4v5KCgTZxD7VW2vPCsBqkV3V | Change | 0.00000000 | 0.00000000 | 0.00000000 | 1/0 |
| 3B7xNx7dCT6ydcVF1xQpEtG8UFeeh2PyAk | Change | 0.00000000 | 0.00000000 | 0.00000000 | 1/1 |
+------------------------------------+---------+----------------+------------+------------+---------+
发现一个空的Copay 1.1.x(bip45)1 of 1钱包。
Copay的旧版本使用bip45的特殊方式,工具无法在未经帮助的情况下检测到。
注意使用--derivation=copaylegacy
(Copay 1.6.3+ 1 of 1钱包使用bip44推导,不需要任何特殊参数。)
$ ./hd-wallet-addrs.php -g --derivation=copaylegacy --gap-limit=2 --xpub=xpub697odnriKgTgWE4my6au8nd8haUfAMzLGFpDemAkRbCMgGVxANuj9DffNLgDjPA1dnxzi8oFmM79ZPgKVfCV7Saj8sQUL7tJfeZDuyQNGDm --include-unused --logfile=/tmp/out.txt
--- Wallet Discovery Report ---
Found 2 Receive addresses and 2 Change addresses.
Receive -- Used: 0 Unused: 2
Change -- Used: 0 Unused: 2
+------------------------------------+---------+----------------+------------+------------+----------------+
| addr | type | total_received | total_sent | balance | relpath |
+------------------------------------+---------+----------------+------------+------------+----------------+
| 3LHgjejeCnQEhLGpmc1q4RmPXypKhjbgpY | Receive | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/0/0 |
| 3Jdd25xHSCDFrMeCoW62963vf22UoKBmtP | Receive | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/0/1 |
| 3JZ3YR6sgyqq6xcGtpcAvYBCX7gM9cPU3c | Change | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/1/0 |
| 32KNwkcQzBHYejvnJpWDwUWMbHGZd4Q6fH | Change | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/1/1 |
+------------------------------------+---------+----------------+------------+------------+----------------+
对Copay 1.6.2及以下版本用户的警告
较旧的Copay版本允许生成大于20的差距。这是因为每次查看接收屏幕时都会生成一个新的地址,并且不尊重标准的20差距限制。
只检查20个地址可能会让您错过发现资金。如果您怀疑这可能正在发生,可以通过gap-limit参数指定更大的差距限制,例如100。
发现一个空的Copay 1.1.x(bip45)2 of 2钱包。
我们再次必须使用--derivation=copaylegacy
$ ./hd-wallet-addrs.php --derivation=copaylegacy -g --gap-limit=2 --xpub=xpub68bjYyPhqAwK4T8WtXuGvruSQoJu1vdLD7DYc591MkFCR7wD9gyzteFYmzRyytWJ2SzTqZNTgggvPEyqEy9oArjLF7xhte5js1Lp1EPipwJ,xpub68ufoGjY41tQqP4LpeyYornuNxm8DNy2Rn7KAPUTAwFouj821eqcVpWw1jonrm2Xg5jnnSrd1QPQzGve3f66ZLf6Ni9VY6aN3AjYa4e7XTE --numsig=2 --include-unused --logfile=/tmp/out.txt
--- Wallet Discovery Report ---
Found 2 Receive addresses and 2 Change addresses.
Receive -- Used: 0 Unused: 2
Change -- Used: 0 Unused: 2
+------------------------------------+---------+----------------+------------+------------+----------------+
| addr | type | total_received | total_sent | balance | relpath |
+------------------------------------+---------+----------------+------------+------------+----------------+
| 35uhrWpDTj3Y7EwR9AWjACGfT47txtpH1v | Receive | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/0/0 |
| 3BnXxkW9CVCLn1EboGDJ8434eKFWZGHsjn | Receive | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/0/1 |
| 38dzdCQXatNdT9nWG7thpGC9KjBVLphZRP | Change | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/1/0 |
| 3CfbgQ5BxWRFBYXJxEVAmVCZsatdJfc2rS | Change | 0.00000000 | 0.00000000 | 0.00000000 | 2147483647/1/1 |
+------------------------------------+---------+----------------+------------+------------+----------------+
发现工作原理
简单地说,发现通过数学推导您的钱包地址的顺序并检查每个地址是否被使用。
对过程的简要技术描述
- 从扩展公钥(xpub)开始
- 然后是接收地址,然后是更改地址
- 推导xpub子地址批次(bip32:0/*)
- 对于每一批
- 检查每个地址是否已收到资金(调用oracle/服务器API)
- 直到找到20个(默认)未使用的连续地址。
隐私影响
一个重要的事情是要认识到,除非你在本地运行toshi或insight服务器,否则发现过程会将你的公共地址发送给第三方。例如:BlockChain.info、BitPay(insight)或CoinBase(toshi)
第三方无法花费你的资金。
第三方可以跟踪你的请求并猜测/假设你的地址与你的IP相关联,或者相互关联。
如果你关心这一点,那么你应该调查如何在本地运行toshi或insight,并使用--toshi或--insight标志来指定本地服务器URL。
现在有一个功能可以帮助在使用第三方API服务器时提高隐私。--api=roundrobin标志将遍历可用的区块链提供者并将单个地址发送到每个提供者。这样,就没有单个提供者可以访问所有查询的钱包地址。
查询单个地址很慢。可以使用--batch-size标志来增加发送到每个提供者的地址数量。
自行承担风险。
作者不对正确性做出任何声明或保证。
输出格式
报告可以以下列格式打印
- 纯文本 - 如上所示的ASCII格式表格,用于人类。
- csv - CSV格式。用于电子表格程序。
- json - 原始json格式。用于程序轻松读取。
- jsonpretty - 美观的json格式。用于程序或人类。
- addrlist - 单列地址列表。用于轻松剪切/粘贴。
此外,报告可能只包含传入交易、只包含传出交易或两种类型的交易。
用法
$ ./hd-wallet-addrs.php
hd-wallet-addrs.php
This script discovers bitcoin HD wallet addresses that have been used.
Options:
-g go! ( required )
--xpub=<csv> comma separated list of xpub keys
--xpubfile=<path> file containing xpub keys, one per line.
note: multiple keys implies multisig m of n.
--derivation=<type> bip32|bip44|bip45|copaylegacy|relative.
default=relative
--numsig=<int> number of required signers for m-of-n multisig wallet.
(required for multisig)
--gap-limit=<int> bip32 unused addr gap limit. default=20
--include=<type> include which addresses. one of [used, unused, both]
note that unused addresses are subject to --gap-limit
--include-unused equivalent to --include=both
--gen-only=<n> will generate n receive addresses and n change addresses
but will not query the blockchain to determine if they
have been used.
--type=<type> receive|change|both. default=both
--api=<api> toshi|insight|blockchaindotinfo|btcd|roundrobin
default = blockchaindotinfo (fastest)
roundrobin will use a different API for each batch
to improve privacy. It also sets --batch-size to
1 if set to auto.
--batch-size=<n> integer|auto default=auto.
The number of addresses to lookup in each batch.
--cols=<cols> a csv list of columns, or "all"
all:
(addr,type,total_received,total_sent,balance,relpath,abspath,xpub)
default:
(addr,type,total_received,total_sent,balance,relpath)
--outfile=<path> specify output file path.
--format=<format> txt|csv|json|jsonpretty|html|addrlist|all default=txt
if all is specified then a file will be created
for each format with appropriate extension.
only works when outfile is specified.
--toshi=<url> toshi server. defaults to https://bitcoin.toshi.io
--insight=<url> insight server. defaults to https://insight.bitpay.com/api
--blockchaindotinfo=<url>
blockchain.info server. defaults to https://blockchain.info
--btcd=<url> btcd rpc server. specify as http://user:pass@host:port. https ok also
btcd does not return balance or total sent/received.
--oracle-raw=<p> path to save raw server response, optional.
--oracle-json=<p> path to save formatted server response, optional.
--logfile=<file> path to logfile. if not present logs to stdout.
--loglevel=<level> debug,info,specialinfo,warning,exception,fatalerror
default = info
安装和运行。
需要PHP的gmp扩展。以下是在ubuntu上安装的方法。
sudo apt-get install php-cli php-gmp composer
基本用法
git clone https://github.com/dan-da/hd-wallet-addrs
cd hd-wallet-addrs
composer install
尝试一个示例
./hd-wallet-addrs.php -g --xpub=xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR
或隐藏日志消息
./hd-wallet-addrs.php -g --xpub=xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR --logfile=/tmp/log.txt
运行测试用例
cd tests
./test_runner.php
在PHP中生成密钥真的很慢。为了大幅提高速度,你可以从以下链接安装secp256k1扩展:
https://github.com/Bit-Wasp/secp256k1-php
区块链API提供商说明。
提示!使用--api标志在区块链API提供商之间切换。
每个API都有优点和缺点。有些比其他更快,或者更容易/更难在本地运行。建议使用blockchain.info服务,因为它目前有最快的API,并且是默认的。
为了最佳隐私,应该查询运行在本地的预言机。Esplora、Insight、toshi和btcd可以以这种方式运行。
blockchain.info
截至2024-06-03:已测试,正常工作。
截至2015-12-30
- 支持单次调用中的多地址查询。
- 每次调用的最大地址数:未知。
- 返回额外的非必需信息,例如最后50笔交易。
- 返回的地址顺序与请求的顺序不同。
esplora(由blockstream.info提供)
截至2024-6-03:已测试,正常工作。
截至2019-08-06
- 不支持单次调用中的多地址查询。功能请求。
- 开源,可以在本地运行。
btc.com
截至2024-06-03:已测试,无法工作。
截至2019-08-06
- API返回403禁止错误,除非通过浏览器请求。视情况而定。
截至2018-07-23
- 支持单次调用中的多地址查询。
- 每次调用的最大地址数:未知。
- 对于未收到资金的任何地址,返回的索引中包含NULL值。
bitcoin-core
截至2019-08-06
- 仍然不支持地址索引或API。
- 有可能这个拉取请求会被合并。
截至2015-12-30
- 不提供查询地址总接收额的合适API。
- 没有公共地址索引。实现API会比较困难。
- 存在一些第三方补丁或外部解决方案可以创建地址索引。
- hd-wallet-addrs不支持(遗憾的是)。
blockcypher.com
截至2024-06-03:已测试,无法工作。
截至2018-07-23
- 支持通过批处理在单个调用中查找多个地址。
- 每个批处理调用最多可处理100个地址。然而
- 每个地址在内部都被计算为一个请求,超过3个会触发速率限制,导致请求失败。因此,只有使用API密钥才能达到100个,免费使用的限制实际上是3个。
- 请参阅blockcypher/explorer#245
Insight
截至2024-06-03:测试未正常工作。
截至2019-08-06
- 项目页面表示insight已被bitcore-node取代。
- insight 公共API仍在工作。
截至2015-12-30
- 不支持在单个调用中查找多个地址。
- 每个候选地址必须单独查询。
blockr.io
截至2017-09-04
- 已死亡。被Coinbase.com淘汰。
- 阅读讣告。
- R.I.P. blockr
截至2016-02-16
- 支持单次调用中的多地址查询。
- 每个调用限制地址数量为20。
- 不会返回不必要的交易数据。
btcd
截至2017-05-21
- btcd现在可以从hd-wallet-addrs查询以找到已使用的钱包地址,但余额/发送/接收的值是空的。
- 不支持多地址查找,因此速度不是很快。
- 可能是运行本地预言机最简单的方式。
- 请参阅此问题。
截至2015-12-30
- 不提供查询地址总接收额或余额的合适API。
- 确实有一个公共地址索引,这可能使得实现这样的API成为可能,尽管可能性能不是很好。
Toshi
截至2019-08-06
截至2017-05-21
- toshi.io自2016年12月31日起不再存在。
- toshi仍然可以通过从GitHub安装本地运行。
- 请参阅Coinbase公告这里。
截至2015-12-30
- 不支持在单个调用中查找多个地址。
- 每个候选地址必须单独查询。
嵌入到您的PHP项目中
以下是一个快速示例,说明如何直接访问API而不调用CLI程序。
在您的项目的composer.json中
{
"require": {
"dan-da/hd-wallet-addrs": "0.2.0"
}
}
yourproject.php
require_once 'vendor/autoload.php'; // normally a single xpub is used. multiple can be provided for multisig key generation. $xpub_list = ['xpub6BfKpqjTwvH21wJGWEfxLppb8sU7C6FJge2kWb9315oP4ZVqCXG29cdUtkyu7YQhHyfA5nt63nzcNZHYmqXYHDxYo8mm1Xq1dAC7YtodwUR']; $params = walletaddrs::default_params(); // modify params here if you need to. see default_params() for keys. $wa = new walletaddrs($params); $data = $wa->discover_wallet_addrs( $xpub_list ); echo json_encode($data, JSON_PRETTY_PRINT); // or for fancier printing, you could use: // walletaddrsreport::print_results($wa->get_params(), $data);
谢谢
非常感谢bitwasp/bitcoin-php的作者。这个库处理了处理确定性密钥和多签名的繁重工作,以及其他一些工作。
待办事项
- 添加选项以返回仅接收或更改,而不是两者。
- 测试与额外的钱包软件。
- 添加对bip39的支持以从秘密单词中获取xpub。也许?
- 向btcd添加合适的API。