MAC下使用plyvel出错解决

2021-04-21 13:34:31 浏览数 (1)

近期在研究bitcoin比特币,想将所有地址的余额(UTXO)导出来。

网上找了一下,找到了这个开源库:btcposbal2csv

https://github.com/graymauser/btcposbal2csv

这个库是python写的,它依赖一个第三方组件plyvel。plyvel提供了操作leveldb的接口。按作者的说明,安装是很简单的,就是

代码语言:javascript复制
> pip install plyvel

安装完后,运行:

代码语言:javascript复制
> python btcposbal2csv.py

然后就抛错了:

代码语言:javascript复制
Traceback (most recent call last):
  File "btcposbal2csv.py", line 5, in <module>
    from utils import parse_ldb
  File "/Users/zhangsan/Desktop/bitcoin-research/btcposbal2csv/utils.py", line 3, in <module>
    import plyvel
  File "/Users/zhangsan/Library/Python/2.7/lib/python/site-packages/plyvel/__init__.py", line 6, in <module>
    from ._plyvel import (  # noqa
ImportError: dlopen(/Users/zhangsan/Library/Python/2.7/lib/python/site-packages/plyvel/_plyvel.so, 2): Symbol not found: __ZTIN7leveldb10ComparatorE
  Referenced from: /Users/zhangsan/Library/Python/2.7/lib/python/site-packages/plyvel/_plyvel.so
  Expected in: /usr/local/opt/leveldb/lib/libleveldb.1.dylib
 in /Users/zhangsan/Library/Python/2.7/lib/python/site-packages/plyvel/_plyvel.so

错误是Symbol not found: __ZTIN7leveldb10ComparatorE

就是有个方法找不到了,反复折腾重装了pip、python、leveldb和plyvel后,并用nm命令查看了.dylib、.so里用的方法后,突然搞明白了原因,leveldb近期升级到了1.23版本,去掉了一些旧方法,而plyvel版本没更新仍依赖这些旧方法

搞明白了原因,接下来就是要安装leveldb的旧版本了。

mac下安装leveldb的旧版本有两种方法,一种是直接下载对应版本的源码包,自己make。另一种是用brew来安装。

为了便于系统管理软件,我决定用brew来安装旧版的leveldb。

网上找到的一般方法是用brew info来查看包地址,然后在git里查找对应的历史记录,执行`brew install 记录地址`来安装:

代码语言:javascript复制
> brew info leveldb

leveldb: stable 1.23 (bottled)
Key-value storage library with ordered mapping
https://github.com/google/leveldb/
/usr/local/Cellar/leveldb/1.23 (31 files, 879.8KB) *
  Poured from bottle on 2021-04-20 at 19:17:56
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/leveldb.rb
License: BSD-3-Clause
==> Dependencies
Build: cmake ✔
Required: gperftools ✔, snappy ✔
==> Analytics
install: 1,657 (30 days), 5,164 (90 days), 14,479 (365 days)
install-on-request: 1,422 (30 days), 4,381 (90 days), 12,358 (365 days)
build-error: 0 (30 days)

在浏览器打开 https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/leveldb.rb

点History,找到对应的版本,例如我的目标版本是1.21,点今后去选择View,最后点Raw,得到下面的url

https://raw.githubusercontent.com/Homebrew/homebrew-core/75277166a28d6a948b045d18e94e1832761d2974/Formula/leveldb.rb

最后执行下面命令来安装:

代码语言:javascript复制
> brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/75277166a28d6a948b045d18e94e1832761d2974/Formula/leveldb.rb

却再次抛错:

代码语言:javascript复制
> brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/1478ac3410e452961f8a9c9640716542f6acd710/Formula/leveldb.rb

Traceback (most recent call last):
	9: from /usr/local/Homebrew/Library/Homebrew/brew.rb:122:in `<main>'
	8: from /usr/local/Homebrew/Library/Homebrew/cmd/install.rb:131:in `install'
	7: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:303:in `parse'
	6: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:634:in `formulae'
	5: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:634:in `map'
	4: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:638:in `block in formulae'
	3: from /usr/local/Homebrew/Library/Homebrew/formulary.rb:374:in `factory'
	2: from /usr/local/Homebrew/Library/Homebrew/formulary.rb:155:in `get_formula'
	1: from /usr/local/Homebrew/Library/Homebrew/formulary.rb:159:in `klass'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:250:in `load_file': Invalid usage: Installation of leveldb from a GitHub commit URL is unsupported! `brew extract leveldb` to a stable tap on GitHub instead. (UsageError)
	12: from /usr/local/Homebrew/Library/Homebrew/brew.rb:155:in `<main>'
	11: from /usr/local/Homebrew/Library/Homebrew/brew.rb:157:in `rescue in <main>'
	10: from /usr/local/Homebrew/Library/Homebrew/help.rb:64:in `help'
	 9: from /usr/local/Homebrew/Library/Homebrew/help.rb:83:in `command_help'
	 8: from /usr/local/Homebrew/Library/Homebrew/help.rb:103:in `parser_help'
	 7: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:303:in `parse'
	 6: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:634:in `formulae'
	 5: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:634:in `map'
	 4: from /usr/local/Homebrew/Library/Homebrew/cli/parser.rb:638:in `block in formulae'
	 3: from /usr/local/Homebrew/Library/Homebrew/formulary.rb:374:in `factory'
	 2: from /usr/local/Homebrew/Library/Homebrew/formulary.rb:155:in `get_formula'
	 1: from /usr/local/Homebrew/Library/Homebrew/formulary.rb:159:in `klass'
/usr/local/Homebrew/Library/Homebrew/formulary.rb:250:in `load_file': Invalid usage: Installation of leveldb from a GitHub commit URL is unsupported! `brew extract leveldb` to a stable tap on GitHub instead. (UsageError)

我在stackoverflow里找到了答案,MAC新版已经禁止直接通过url这种方式来安装指定版本软件了。现在必须通过brew extract命令来安装。

命令如下:

代码语言:javascript复制
#下载指定版本的安装包,存到cask
> brew extract --version=1.21 leveldb homebrew/cask

运行完毕后,会提示你文件会保存到了/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask/Formula/leveldb@1.21.rb

现在可以正式安装了:

代码语言:javascript复制
> brew install /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask/Formula/leveldb@1.21.rb

现在终于安装好leveldb了,别忘了重装一下plyvel:

代码语言:javascript复制
> pip uninstall plyvel
> pip install plyvel

再来运行一下试试:

代码语言:javascript复制
> python btcposbal2csv.py 

Traceback (most recent call last):
  File "btcposbal2csv.py", line 5, in <module>
    from utils import parse_ldb
  File "/Users/zhangsan/Desktop/bitcoin-research/btcposbal2csv/utils.py", line 3, in <module>
    import plyvel
  File "/Users/zhangsan/Library/Python/2.7/lib/python/site-packages/plyvel/__init__.py", line 6, in <module>
    from ._plyvel import (  # noqa
ImportError: dlopen(/Users/zhangsan/Library/Python/2.7/lib/python/site-packages/plyvel/_plyvel.so, 2): Library not loaded: /usr/local/opt/leveldb/lib/libleveldb.1.dylib
  Referenced from: /Users/zhangsan/Library/Python/2.7/lib/python/site-packages/plyvel/_plyvel.so
  Reason: image not found

为啥会Library not loaded:/usr/local/opt/leveldb/lib/libleveldb.1.dylib呢?

进目录看一下,发现原来指定版本安装的情况下,安装目录变成了 /usr/local/opt/leveldb@1.21

我们建个软链就行了:

代码语言:javascript复制
> ln -s /usr/local/opt/leveldb@1.21 /usr/local/opt/leveldb

最后运行命令来做我们最初的目标:

代码语言:javascript复制
python btcposbal2csv.py --lowmem --keep_sqlite="./balance.db" /Users/zhangsan/Desktop/Bitcoin-data/chainstate /Users/zhangsan/Desktop/addresses_with_balance.csv

这下终于没有报错了,终于可以愉快的将bitcoin的所有地址的余额导出来了!

【相关参考】

https://stackoverflow.com/questions/3987683/homebrew-install-specific-version-of-formula

https://www.cnblogs.com/nnylee/p/13379617.html

0 人点赞