- 区块链
【免费下载链接】dogecoin
very currency
导读
contrib/linearize目录下提供了一对 Python 脚本——linearize-hashes.py与linearize-data.py,用于把 Dogecoin 节点本地存储的blocks/blkNNNNN.dat区块数据,重排为一条线性、无分叉、可复现的"最佳版本"区块链(典型产物即用于快速同步的bootstrap.dat)。本文以 contrib/linearize/README.md 为主体骨架,完整讲解两阶段操作流程、全部配置项及其默认值,并结合 linearize-hashes.py、linearize-data.py 的源码与 chainparams.cpp 等链参数定义,深入说明脚本背后的原理与各参数的实际影响。读完本文,你将能独立配置并运行完整的区块数据线性化流程,生成可在其他节点上直接使用的 bootstrap 数据。
一、linearize 工具是什么
在 Dogecoin 这类基于工作量证明(PoW)的区块链中,节点在运行过程中可能因为分叉、重组或同步中断,把多条链上的区块写入本地的blkNNNNN.dat文件中。这些文件里的区块顺序是"磁盘写入顺序",而不是"链上高度顺序",其中夹杂着后来被丢弃的孤块。
linearize工具的作用正是解决这个问题:
linearize-hashes.py:通过 JSON-RPC 调用getblockhash,按高度从min_height到max_height逐块取得一条主链上的区块哈希清单(hashlist);linearize-data.py:以该哈希清单为准绳,扫描本地blocks/目录中的原始blkNNNNN.dat,把属于主链的区块按高度顺序重写为单一文件(如bootstrap.dat)或blocks/blkNNNNN.dat形式的目录输出。
两个脚本运行于 Python 3,同时保持与 Python 2 的兼容(脚本头部均声明#!/usr/bin/env python3,且通过from __future__ import print_function兼容旧版本)。脚本版权头同时标注了 Bitcoin Core 与 Dogecoin Core 开发者,说明该工具是 Dogecoin 从 Bitcoin Core 继承并持续维护的实用工具。
一个典型的应用场景:你希望把本机已同步完成的完整区块链导出,用于其他机器的离线快速同步,或者你需要一份干净的、只包含主链区块的数据集进行分析。linearize 就是为这类"构建 bootstrap 数据"的需求而设计的。
二、完整工作流程概览
整个流程分为两步,先跑哈希脚本,再跑数据脚本:
# 第 1 步:从运行中的节点获取主链哈希清单 $ ./linearize-hashes.py linearize.cfg > hashlist.txt # 第 2 步:依据哈希清单,把本地 blk*.dat 重排为线性区块链 $ ./linearize-data.py linearize.cfg两个脚本都只接受一个命令行参数:配置文件路径。若参数数量不对,脚本会打印用法并退出(见两个脚本主入口处的Usage:提示)。配置文件的解析规则也很简单:逐行读取,#开头的行为注释被跳过,其余按key = value形式解析(对应源码中re.search('^(\w+)\s*=\s*(\S.*)$', line)的正则逻辑),未识别的行直接忽略。
一个值得注意的先后依赖:linearize-data.py默认读取名为hashlist.txt的哈希清单文件(可通过配置项hashlist修改),所以第 1 步的重定向输出文件名需要与第 2 步配置中的hashlist保持一致。
三、第 1 步:下载哈希清单(linearize-hashes.py)
3.1 前置条件
linearize-hashes.py需要一个可用的 JSON-RPC 服务端点,本地或远程均可。只需运行dogecoind或带-server参数的dogecoin-qt即可满足:
# 启动带 RPC 服务的节点 $ dogecoind -server -daemon # 或 $ dogecoin-qt -server从源码看,脚本通过BitcoinRPC类(linearize-hashes.py)基于标准库http.client/httplib实现 HTTP JSON-RPC 调用,请求头使用 HTTP Basic 认证(Authorization: Basic base64(user:pass)),每次最多批量请求 10000 个区块哈希(max_blocks_per_call=10000参数),逐批推进高度直到max_height。
3.2 必需配置项
| 配置项 | 说明 |
|---|---|
rpcuser | RPC 用户名,与节点配置中的rpcuser一致 |
rpcpassword | RPC 密码,与节点配置中的rpcpassword一致 |
若配置文件中缺失rpcuser或rpcpassword,脚本会直接报错退出(源码中"Missing username and/or password in cfg file"分支)。
3.3 可选配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
host | 127.0.0.1 | JSON-RPC 服务地址 |
port | 22555 | JSON-RPC 服务端口。主网 RPC 端口为 22555,与 chainparamsbase.cpp 中nRPCPort = 22555一致;测试网为 44555(见同文件第 48 行) |
min_height | 0 | 起始高度(含) |
max_height | 313000 | 结束高度(含)。注意示例配置中的 313000 是一个较旧的链高上限,实际使用时应设置为不低于当前链高的值 |
rev_hash_bytes | false | 若为true,输出的区块哈希将做字节反转(即对getblockhash返回的哈希做字节序翻转)。默认关闭;设计初衷是生成独立哈希清单,但配合linearize-data.py使用也安全——数据脚本输出结果与字节格式无关 |
3.4 字节反转原理
rev_hash_bytes的实现对应源码中的hex_switchEndian函数:把哈希十六进制字符串按每两个字符(一个字节)切分后逆序拼接。getblockhash返回的是内部存储顺序的哈希,而区块头中hashPrevBlock等字段以相反字节序写入磁盘,某些下游工具需要磁盘序,此时可打开该开关。
3.5 常见错误排查
- RPC 连接被拒绝:脚本捕获
ConnectionRefusedError并输出 "RPC connection refused. Check RPC settings and the server status.",请检查host/port是否指向正在运行的节点、节点是否开启了server=1; - 某高度返回错误:脚本对每个响应检查
error字段,出错时打印JSON-RPC: error at height <h>并以状态码 1 退出; - 响应乱序:源码通过
assert(resp_obj['id'] == x)断言响应与请求同序。
四、第 2 步:重排本地区块数据(linearize-data.py)
4.1 必需配置项(二选一)
| 配置项 | 说明 |
|---|---|
output_file | 最终区块链写入的单个文件路径(如bootstrap.dat) |
output | 输出目录;启用后脚本会按blk%05d.dat命名规则写出多个文件(如blk00000.dat),此时output_file被忽略 |
若两者都未配置,脚本打印 "Missing output file / directory" 并退出。源码中通过self.fileOutput = False区分两种模式(linearize-data.py)。
4.2 可选配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
debug_output | false | 设为true时打印额外调试信息,例如扫描到哈希清单中不存在的未知区块时输出 "Skipping unknown block " |
file_timestamp | 0(关闭) | 设为非 0 时,在关闭每个输出文件时通过os.utime将文件访问/修改时间分别设为当前时间与"写入该文件的最新区块的时间戳" |
genesis | 主网创世块哈希1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691 | 用于校验哈希清单完整性:若哈希清单中不包含该创世块哈希,脚本输出 "Genesis block not found in hashlist" 且不执行复制。该默认值在 chainparams.cpp 的hashGenesisBlock断言中可交叉验证 |
input | input(相对目录) | 本地dogecoind的blocks/目录,内含blkNNNNN.dat。主网默认数据目录下通常为~/.dogecoin/blocks,测试网为~/.dogecoin/testnet3/blocks |
hashlist | hashlist.txt | 由linearize-hashes.py生成的哈希清单文本文件路径 |
max_out_sz | 1000*1000*1000字节(约 1 GB) | 单文件模式下,输出文件达到该大小后自动滚动到下一个文件。注意:在目录输出模式下该限制同样生效,滚动时文件名序号递增 |
netmagic | c0c0c0c0 | 网络魔法数。主网c0c0c0c0与 chainparams.cpp 中主网pchMessageStart一致;测试网对应值在 chainparams.cpp 中为fcc1b7dc(示例配置中给出的测试网0b110907为较早时期的值,实际配置请以源码链参数为准)。脚本会用它校验blk*.dat中每个区块的头部魔法数字,不匹配即停止并输出 "Invalid magic" |
out_of_order_cache_sz | 100*1000*1000字节(约 100 MB) | 乱序区块的内存缓存上限。自 Bitcoin Core 0.10 起区块可能乱序写入磁盘,遇到"尚未轮到输出"的区块时,若缓存未满则直接读入内存暂存,否则跳过磁盘偏移(f.seek),待轮到该高度时再从磁盘按记录的偏移量(BlockExtent)重新读取 |
rev_hash_bytes | false | 若为true,读取哈希清单时对每个哈希做字节反转,以匹配linearize-hashes.py生成时的设置(get_block_hashes中的hex_switchEndian调用) |
split_timestamp | 0(关闭) | 设为非 0 时,除了max_out_sz限制外,每当输出遇到新的月份(按区块头中的时间戳判断,源码通过struct.unpack("<I", blk_hdr[68:72])取nTime)即滚动到新文件 |
4.3 脚本的核心处理逻辑
linearize-data.py的主流程(BlockDataCopier.run,见 linearize-data.py)可以概括为:
- 建立高度索引:
mkblockmap把哈希清单构造成{hash: height}映射; - 顺序扫描输入文件:按
blk%05d.dat编号逐个打开输入文件,每个区块由 8 字节文件头(4 字节netmagic+ 4 字节小端长度)与 80 字节区块头组成;inLen为文件头声明长度减去 80 字节头部后的载荷长度; - 哈希校验:对每个区块头做双重 SHA-256(
calc_hdr_hash),再经bufreverse/wordreverse字节整理得到规范哈希字符串,与blkmap比对; - 顺序写入:若当前区块高度恰好等于已输出计数(
blkCountOut),直接复制;否则记录其BlockExtent(文件号、偏移、头部、大小)暂存,视缓存空间决定读入内存还是留待回读; - 进度反馈:每写满 1000 个区块打印一次进度(
%i blocks scanned, %i blocks written (of %i, %.1f%% complete)),全部完成后输出Done (%i blocks written)。
这个"乱序缓存 + 回读"设计保证了即使磁盘上的区块顺序杂乱,输出结果依然是严格按高度递增的线性链。
五、参考配置:example-linearize.cfg 逐项解读
仓库在 example-linearize.cfg 中给出了完整的示例配置,按模块拆分如下:
# ===== dogecoind RPC 设置(linearize-hashes 使用)===== rpcuser=someuser rpcpassword=somepassword host=127.0.0.1 port=22555 #port=44555 # 测试网 RPC 端口 # ===== 哈希清单设置(linearize-hashes 使用)===== max_height=313000 # ===== 输入 / 输出设置(linearize-data 使用)===== # 主网 netmagic=c0c0c0c0 genesis=1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691 input=/home/example/.dogecoin/blocks # 测试网(示例配置中的旧值,实际链参数请以 src/chainparams.cpp 为准) #netmagic=0b110907 #genesis=bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e #input=/home/example/.dogecoin/testnet3/blocks # "output" 选项启用后,区块链写入指定目录(此时忽略 output_file)。 # 若未使用 "output",则使用 "output_file"。 # output=/home/example/blockchain_directory output_file=/home/example/Downloads/bootstrap.dat hashlist=hashlist.txt # 乱序区块内存缓存上限(字节) out_of_order_cache_sz = 100000000 # 是否反转 getblockhash 返回的哈希字节序 rev_hash_bytes = False # 新月份时是否设置新区块链文件的访问/修改时间 file_timestamp = 0 # 是否按新月份或特定高度拆分区块链文件 split_timestamp = 0 # 是否打印调试输出 debug_output = False其中genesis的测试网取值bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e与 chainparams.cpp 中的测试网hashGenesisBlock断言完全一致,可作为交叉验证依据。
提示:
rpcuser/rpcpassword必须与节点实际启动参数或节点配置一致。节点侧 RPC 凭据可通过启动参数-rpcuser=<user> -rpcpassword=<pass>或配置文件中的同名选项指定(参见仓库根目录的 share/dogecoin.conf 模板)。
六、运行完整流程的实操步骤
步骤 A:准备节点与配置文件
- 确保节点已同步到目标高度,并开启 RPC:
dogecoind -server -daemon -rpcuser=<user> -rpcpassword=<pass>; - 复制 example-linearize.cfg 为你的配置文件(如
linearize.cfg),修改rpcuser、rpcpassword、input、output_file与max_height(设为当前链高,可通过 RPCgetblockcount查询); - 确认
input指向的blocks/目录真实存在且包含blkNNNNN.dat文件。
步骤 B:生成哈希清单
$ ./linearize-hashes.py linearize.cfg > hashlist.txt执行后检查hashlist.txt:第一行应为主网创世块哈希1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691(主网场景),总行数应等于max_height - min_height + 1。
步骤 C:生成线性化区块链
$ ./linearize-data.py linearize.cfg观察输出:
- 脚本先打印
Read N hashes,随后逐个打开输入文件(Input file <path>/blk00000.dat); - 遇到乱序区块会按缓存策略处理,遇到未知区块(孤块)在
debug_output=true时打印跳过信息; - 结束时打印
Done (N blocks written),其中 N 应等于哈希清单中的区块数。
产物即为你配置的output_file(如bootstrap.dat)或output目录下的blkNNNNN.dat系列文件,可以直接拷贝到其他节点的数据目录用于离线快速同步。
七、参数选择与调优建议
| 场景 | 建议 |
|---|---|
| 只想导出一个大文件 | 使用output_file,保持默认max_out_sz(1 GB)即可,超限会自动分卷;也可调大该值减少分卷数 |
| 需要按月份归档 | 打开split_timestamp = 1,配合output目录模式,产出按自然月拆分的区块文件 |
| 磁盘上乱序区块很多、内存充足 | 适当调大out_of_order_cache_sz,减少重复磁盘寻址回读,加快处理速度;内存紧张则保持默认 100 MB |
| 处理中途排查问题 | 打开debug_output = true,可看到被跳过的未知区块哈希,便于判断输入数据是否混杂了分叉块 |
| 不确定链参数 | 严格对照 chainparams.cpp 中的pchMessageStart与hashGenesisBlock取值填写netmagic与genesis |
max_out_sz与out_of_order_cache_sz的默认值均为 10 亿字节量级(1000*1000*1000与100*1000*1000),在 linearize-data.py 中可确认。两者的权衡本质是磁盘 I/O 与内存占用的互换:缓存越大,越少回读磁盘,但占用内存越多。
八、总结
contrib/linearize提供了从"运行中的 Dogecoin 节点"到"干净、线性、无分叉的区块链快照"的完整工具链:linearize-hashes.py负责按高度拉取主链哈希权威清单,linearize-data.py负责以该清单为准对本地blkNNNNN.dat进行重排、校验与输出。本文覆盖了两步流程的全部命令、必需/可选配置项及其默认值与源码出处、示例配置的逐项解读,以及乱序区块缓存、月份拆分、字节序反转等底层实现原理。结合 example-linearize.cfg、linearize-hashes.py、linearize-data.py 与链参数定义文件 chainparams.cpp、chainparamsbase.cpp,你可以直接照此流程生成属于自己的bootstrap.dat离线同步数据。
- 区块链
【免费下载链接】dogecoin
very currency
相关推荐
Bitcoin Core linearize 脚本实战:构建线性无分叉的 Bootstrap 区块链
Bitcoin Core linearize 脚本实战:构建线性无分叉的 Bootstrap 区块链 本篇围绕 contrib/linearize/README
区块链金融科技网络密码学Zcash contrib/linearize 详解:从本地区块数据构建线性 bootstrap.dat
Zcash contrib/linearize 详解:从本地区块数据构建线性 bootstrap.dat 本文围绕 contrib/linearize/READ
区块链金融科技密码学后端Dogecoin Core 仓库 contrib 目录全指南:开发、构建与验证工具链详解
Dogecoin Core 仓库 contrib 目录全指南:开发、构建与验证工具链详解 导读 本篇文章以 Dogecoin Core 源码仓库中的 contr
区块链
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考