Ordinals 使用指南

Ordinals 上手门槛有点高了。希望你最好是学 CS 的。

安装

1. 准备工作

  • 足够大足够快的硬盘:ord 需要开启 txindex,这个选项和区块存储修剪互斥,所以需要存储全量数据。截止2023-02,单 btc 数据量是 527GB,ord 索引 117 GB,为了不至于频繁升硬盘,建议硬盘 2TB 或以上,nvme 接口,不建议 sata 硬盘尝试;
  • 豁出去 SSD 写入量,完整 index 写入量在 20TB 左右;
  • 足够多的内存:至少 32GB 内存;少于 32GB 会频繁走虚拟内存,耗时非常久,而且很容易把 SSD 干废,不建议尝试;16G 内存绝对玩不成,千万不要尝试;
  • 如果是未开采过 ord 的 raw btc ,按现在的供应量来看,大概每 25 个 btc 会有一个最低配的稀有 sat。如果你的 btc 数量比较少,或者 btc 是刚从交易所提的,那可能折腾了也白折腾;
  • 多台电脑使用 ord 的话,建议将数据存放在外接 SSD 上,USB 接口速度至少需要 10Gbps,最好 20Gbps(That is,移动硬盘盒和 USB c to c 线都应该是至少 3.2 gen1 标准,nvme PCI-e 3.0 x 4 或以上)。

2.1 安装 Core 钱包

  1. ord 要求 core 最低版本 24.0.0,目前 bitcoin.org 最新版本还是 22.0.0,所以得在 github 上下一个 24.0.1;
  2. 安装好 core 后启动,第一次启动会弹出选项:
    1. 第一个选项选 使用自定义的数据目录,位置选择我们准备的这块足够大的硬盘/分区;这个路径后面称为 BTC_SANDBOX;
    2. 第二个选项不要勾选 将区块存储限制到_GB,因为 txindex 和区块裁剪参数冲突,ord 要求开启 txindex。

2.2 Windows 安装 Core 钱包后的一些准备工作

为避免后续命令行输入 bitcoin daemon 完整路径,将 bitcoin daemon 加入环境变量:

  1. 打开 设置 -> 系统 -> 关于,右边栏 高级系统设置
  2. 高级 选项卡下 环境变量
  3. 选中 Path 点击 编辑
  4. 点击 新建,输入 C:\Program Files\Bitcoin\daemon,点击 确定 确定 确定
  5. cmd 窗口顶部白条右键,点默认值,关闭快速编辑模式,再顶部白条右键,点属性,关闭快速编辑模式。否则安装 rust/编译 ord/ord indexing可能会卡住。

3. bitcoin.conf 设置

BTC_SANDBOX 中新建文件 bitcoin.conf,内容是:

1
2
txindex=1
server=1

txindex=1 是 ord 要求的模式,server=1 是为了等下 bitcoind 启动时,bitcoin-cli 能正常连接需要加的选项,这个是 Windows 版本独有的坑。

4. 建立 core 沙箱软连接

将实际的沙箱路径做一个软链接,链到默认位置,可以避免后面用 ord 时要输入 --bitcoin-data-dir BTC_SANDBOX

Windows:

1
mklink %appdata%\Bitcoin BTC_SANDBOX

Mac:

1
ln -s BTC_SANDBOX ~/Library/Application\ Support/Bitcoin

4.1 Mac 使用 APFS(Encrypted) 加密钱包文件

在移动硬盘划出 partition,格式 APFS encrypted,名称为 encrypted_apfs_vol,然后:

1
ln -s /Volumes/encrypted_apfs_vol/wallets BTC_SANDBOX/wallets

5. 安装 ord binary,或编译后安装 ord

0) 不想装 Visual Studio 可以下载已编译好的 ord 文件

下载列表
或者继续往下看完整编译方法:

1) 安装 rust

rust-lang.org 下载最新版 rust 安装包,默认安装需要装 Visual Studio,装就装,由它去吧。

2) clone ord

1
git clone https://github.com/casey/ord.git

考虑到 Windows 可能没装 git,直接 https://github.com/casey/ord/ 下载个 zip 包解压也行。

3) 编译 ord

1
2
cd "ord 的 clone 或解压路径"
cargo build --release

3.1) Windows 安装 ord

如果没报错,完成后在 .\target\release 下会有一个 ord.exe,这个文件可以拷贝到 C:\Program Files\Bitcoin\daemon 使用(因为这个加过 PATH 了)。

如果要把 ord.exe 安装在没有安装 Visual Studio 的电脑,需要一并拷贝 vcruntime140.dll(在安装过 Visual Stutio 的 PC 的 system32 文件夹里)。

3.2) Mac 安装到 ord

./target/release 下会生成名为 ord 的可执行文件,复制到一个加过 PATH 的路径下,比如 ~/bin

启动

1.0. 如果是 mac,Bitcoin Core 的安装包默认不附带 bitcoind 和 bitcoin-cli,需要自行编译。首先安装 Xcode 最新版和 home brew,然后:

1
2
3
4
5
6
7
8
9
10
xcode-select --install
brew install autoconf automake pkg-config libtool boost libevent
curl -O https://codeload.github.com/bitcoin/bitcoin/zip/refs/tags/v24.0.1
unzip v24.0.1
cd bitcoin-0.24.1
sh ./autogen.sh
./configure
make 
sudo make install
which bitcoind

1.1. 启动 bitcoind,同步区块

命令行执行:

1
bitcoind -datadir=BTC_SANDBOX -txindex

等待同步结束,网好的话大概需要2-3天。

2. bitcoin-cli 测试是否已经追上最新区块

1
bitcoin-cli -datadir=BTC_SANDBOX getblockcount

如果一切正常,这个命令会显示当前区块数量。

3. 创建 ord wallet

保持 bitcoind 启动状态:

1
ord wallet create

成功后,会显示助记词,同时在 BTC_SANDBOX 下生成名为 ord 的钱包。钱包名称不可修改,所以再执行 ord create wallet 会报错文件已存在。

4. 建立索引

1
ord --index-sats index

这个命令默认将索引文件写入 %appdata%\ord~/Library/Application Support/ord。如果想把索引文件也存放在 BTC_SANDBOX,使用 --data-dir 指定索引位置:

1
ord --data-dir BTC_SANDBOX ord --index-sats index

索引过程会比较久,外接硬盘速度不是瓶颈的话,用 2021 款 m1 pro 大概需要一周时间。过程中 ord 可以关闭,再次打开时会从上次的高度继续建立索引。

索引每隔 5000 个区块写入磁盘,但是高度越高的 5000 个区块需要索引的数据就越多,内存开销是随索引区块高度上升而线性上升的。如果索引的时候遇到内存不足,虚拟内存开销吃满磁盘的情况,关掉 ord 重新打开(重新打开的时候会重新从磁盘读一遍索引,IO 耗时很久);或者如果你真的有闲没内存,可以尝试改 rust 代码把 5000 调成 500(当然我没试过,加内存的成本低多了)。

索引完建议找个移动硬盘把这个宝贝 ord/index.redb 文件保存起来,万一硬盘噶了,你会感谢我这个建议的。

5. 生成收款地址,打钱!

1
ord wallet receive

成功后会生成收款地址。

可以通过 bitcoin-cli 查看已经生成的收款地址:

1
bitcoin-cli listreceivedbyaddress 1 true

然后:

  • 备份钱包文件和助记词;
  • 然后把你想筛选的 btc 打到你的地址;
  • 不用折腾导入 descriptors 了,生命是很值钱的。

6. 筛选稀有 sats

1
ord wallet sats

如果 ord index 的时候没加 --index-sats 那就骚了,会报错索引在建立时需要传入 --index-sats,需要删了索引重新来。别问我怎么知道的。

如果你钱包里没有稀有 sats 或带铭文的 sats,输出是这样的:

1
[]

有的话是这样的(*是打码了,其实是有值的):

1
2
3
4
5
6
7
8
[
  {
    "sat": 1888888880000000,
    "output": "b***************************************************************5:0",
    "offset": 1********9,
    "rarity": "uncommon"
  }
]

其中 output 是包含这枚稀有 sat 的转账脚本的 output。

7. 发送稀有 sats

首先新建一个专门用来保存 sats 的钱包;这个钱包其实没有什么特别的要求,任何钱包都可以。但是为了未来转出方便 + 保存助记词方便,用 ord wallet create 新建一个是最省心的。第一次玩不建议读那篇 sparrow 的指引。

这段用 mac 命令了,过程和原理和 windows 是一样的。

备份原 ord 钱包:

1
$ mv ~/Library/Application Support/Bitcoin/wallets/ord ~/Library/Application Support/Bitcoin/wallets/backup
1
$ ord wallet create # 创建用于接收藏品的钱包

获取接收地址,记住这里生成的地址 bc1**kq6pn :

1
2
3
4
$ ord wallet receive
{
  "address": "bc1**kq6pn"
}

将接收藏品的钱包改名为 collection:

1
$ mv ~/Library/Application Support/Bitcoin/wallets/ord ~/Library/Application Support/Bitcoin/wallets/collection

还原备份的 ord 钱包:

1
$ mv ~/Library/Application Support/Bitcoin/wallets/backup ~/Library/Application Support/Bitcoin/wallets/ord

这些做完后,在 ~/Library/Application Support/Bitcoin/settings.json 中增加 collection 钱包,以便 core 能默认加载:

1
2
3
4
5
6
{
    "wallet": [
        "ord",
        "collection"
    ]
}

ordinals.com 搜索 sat 的值(例子中为 1888888880000000),查询稀有 sats 的 location,如果是稀有 sats 或刻有铭文,会展示 location:

1
2
location:
b41f***********515:0:1********9

转移稀有 sat 到 collection 钱包:

1
$ ord wallet send --fee-rate 3 bc1**kq6pn b41f***********515:0:1********9

其中:
* fee-rate 为 transaction fee,单位是 sats/vB,这个选项是必选项只能手动填入,最好先在 mempool.space 查了最新的 transaction fee 再填入一个合适的值,目前(2023 Mar 25)可以填 3;不确定手抖填成一个很大的值会不会把所有 btc 当 gas 花了,以前 eth 上有人犯过这个错误,按回车前请 check twice;
* bc1**kq6pn 为用于接收藏品的地址;
* b41f***********515:0:1********9 为藏品的 location。

其他同 ordinals.com 官方文档。

8. 踩坑记录

  1. thread ‘main’ panicked at ‘internal error: entered unreachable code’:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
thread 'main' panicked at 'internal error: entered unreachable code', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/redb-0.13.0/src/tree_store/btree_iters.rs:125:26
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: PoisonError { .. }', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/redb-0.13.0/src/tree_store/page_store/page_manager.rs:1420:43
stack backtrace:
   0:        0x10134a884 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hb33e6e8152f78c95
   1:        0x101367950 - core::fmt::write::hd33da007f7a27e39
   2:        0x10134471c - std::io::Write::write_fmt::h7edc10723862001e
   3:        0x10134a698 - std::sys_common::backtrace::print::h895ee35b3f17b334
   4:        0x10134be0c - std::panicking::default_hook::::h3b7ee083edc2ea3e
   5:        0x10134bb64 - std::panicking::default_hook::h4e7c2c28eba716f5
   6:        0x10134c430 - std::panicking::rust_panic_with_hook::h1672176227032c45
   7:        0x10134c250 - std::panicking::begin_panic_handler::::h0b2d072f9624d32e
   8:        0x10134acec - std::sys_common::backtrace::__rust_end_short_backtrace::he9abda779115b93c
   9:        0x10134bfac - _rust_begin_unwind
  10:        0x101396c28 - core::panicking::panic_fmt::h23ae44661fec0889
  11:        0x101396f48 - core::result::unwrap_failed::h414a6cbb12b1e143
  12:        0x1011cc9dc - <redb::tree_store::page_store::page_manager::TransactionalMemory as core::ops::drop::Drop>::drop::hd4155d9a09147fc3
  13:        0x1011aead0 - core::ptr::drop_in_place<redb::tree_store::page_store::page_manager::TransactionalMemory>::hc9994b501db30c04
  14:        0x1011afe38 - redb::db::Database::new::hd9226a254847dc1d
  15:        0x100e92e90 - redb::db::Builder::open_mmapped::hf7af593908fc963b
  16:        0x100d63898 - ord::index::Index::open::h82502a0a002c9e81
  17:        0x100e17804 - ord::subcommand::wallet::sats::Sats::run::hd007bcbcb69665aa
  18:        0x100eaa2fc - ord::subcommand::wallet::Wallet::run::hae5f90e2815111f4
  19:        0x100d06fec - ord::subcommand::Subcommand::run::h604659fac7645f9a
  20:        0x100e5855c - ord::main::h4e19bbf0c73ea265
  21:        0x100c6618c - std::sys_common::backtrace::__rust_begin_short_backtrace::hc6261e5bd0791a80
  22:        0x100c661a4 - std::rt::lang_start::::h5fdc322bd55738b8
  23:        0x10133ea3c - std::rt::lang_start_internal::h00a235e820a7f01c
  24:        0x100c66208 - _main
thread panicked while panicking. aborting.
[1]    47597 abort      ord --data-dir /Volumes/ord/ord wallet sats

index.redb 数据库文件损坏,如果没备份的话,就得重新 index 一个了。

  1. 每隔 60 秒定时更新 index,避免每次使用的时候等待索引时间较久:
1
2
pip3 install cccrontab
python3 -m cccrontab 60 sh -c "ord --data-dir /Volumes/IndexData/ord wallet sats || ord --data-dir /Volumes/IndexData/ord wallet sats"

  1. restore 后 bitcoin core 客户端找不到 UTXO:

Restore 时高度大于 UTXO 的 tx 高度,core 钱包不会再扫描这笔 tx 了。需要用 rescanblockchain 命令重新扫描 tx:

1
2
3
# bitcoin-cli -rpcwallet=WALLET_NAME rescanblockchain START_HEIGHT END_HEIGHT
# START_HEIGHT 不填则从 0 开始扫,END_HEIGHT 不填则扫到最后一个区块
bitcoin-cli -rpcwallet=my_wallet_name rescanblockchain 777000
  1. 查看 rare sats 开采量:
1
2
3
4
5
6
7
8
curl -O https://ordinals.com/rare.txt
echo '已开采:'
cat rare.txt | grep ":0$" | grep -v ":0:0$" | wc -l
echo '沉睡:'
cat rare.txt | grep ":0:0$" | wc -l 
echo '未开采:'
cat rare.txt | grep -v ":0$" | wc -l
rm rare.txt

Over

Comments