前两天,我想查一下自己在 STEEM 区块链上一些重要记录对应的区块号,比如:
当时手头只有时间戳,却不知道对应的是哪个区块,于是我想到可以用二分查找(binary search)算法来定位。
其实,这个思路在其它区块链上同样适用,并不依赖于特定的链(如 Steem、以太网/Ethereum、比特币/Bitcoin 等)。虽然具体的实现细节(RPC 方法名、时间戳格式等)会有所不同,但整体逻辑是一致的:通过 RPC API 获取某个区块的时间戳;获取最新区块作为上界;然后在区间内使用二分查找。通过多次查询区块时间戳,就能把给定的时间戳映射到最接近的区块号,算法复杂度约为 O(log N)。
当然,大多数区块链也会提供专门的 API 服务,可以直接通过时间返回区块号。我自己就跑过几个程序,从创世区块开始依次获取数据并写入数据库,这样查询时只需要查数据库就能立即得到结果。
可以使用二分搜索算法的场景
在一个搜索空间里,如果自变量 x 随着变化而单调递增或单调递减,那么函数值 f(x) 也会呈现出规律性的单调变化。这种情况下,就可以使用二分搜索算法来快速定位目标值或满足条件的区间。
二分搜索常见的应用场景包括:
- 在区块链上通过时间戳查找区块号(时间戳随区块号递增)。
- 在有序数组中查找目标值或边界。
- 在单调函数(如计算成本函数、概率函数)中寻找满足条件的阈值。
- 在优化问题中缩小答案区间,比如最小化某个代价函数。
总结来说,只要问题满足单调性,二分搜索就能在 O(log N) 的时间复杂度下快速求解,比线性扫描高效得多。
思路概述
- 通过 RPC 获取某个区块号的时间戳(或用索引器 API 直接查询)。
- 查询最新区块,作为二分查找的上边界。
- 在区间 [1, latest_block] 中做二分查找,比较中点区块的时间戳与目标时间戳,收窄区间直到找到最接近(或精确匹配)的区块号。
示例 Python 通用框架
下面给出一个通用的 Python 框架。实际使用时,请把 rpc_call 部分换成目标链对应的 RPC 方法或索引器 API 调用。
def rpc_call(method, params):
"""
通用 RPC 调用函数示例。
根据你使用的链替换为 requests.post(...) 并解析返回。
"""
pass
def get_timestamp_from_block(block_num):
"""
返回给定区块号的时间戳(Unix 秒或 ISO8601 字符串),取决于链的返回格式。
需要把链的时间格式统一成可比较的 datetime / timestamp。
"""
# 示例(伪代码):
# resp = rpc_call("get_block", [block_num])
# ts = parse_timestamp(resp["timestamp"])
# return ts
pass
def get_latest_block_and_timestamp():
"""
返回最新区块号和对应的时间戳,例如 (latest_block, latest_ts)
不同链可能有不同的 RPC 方法,如 get_block_count / get_chain_head / eth_blockNumber + eth_getBlockByNumber 等。
"""
pass
def get_block_from_timestamp(target_ts):
"""
在 [1, latest_block] 区间内使用二分查找定位与 target_ts 最接近的区块号。
返回找到的区块号(若需要,可返回左右两个候选块以便进一步选择)。
"""
latest_block, latest_ts = get_latest_block_and_timestamp()
left, right = 1, latest_block
result = None
while left <= right:
mid = (left + right) // 2
mid_ts = get_timestamp_from_block(mid)
if mid_ts < target_ts:
left = mid + 1
result = mid
elif mid_ts > target_ts:
right = mid - 1
else:
return mid # 精确匹配
# 返回 result(它表示最后一个 timestamp < target_ts 的区块)
# 视需求,你可能还要检查 result+1 是否更接近 target_ts
return result
如何通过二分查找算法根据时间戳获取区块?
按STEEM区块链来举例。
获取区块的时间戳
通过调用 `steemd` 或其它区块链 API,我们可以轻松获取任意区块对应的时间戳。
找到最新区块
这一步为二分查找提供了一个上界。
对目标时间戳进行二分查找
与其线性扫描区块(会非常慢),不如在每一步将搜索区间减半。这样可以将复杂度降低到大约 `O(log N)`,其中 `N` 是当前区块高度。这正是二分查找的魅力——它被认为是迄今为止人类发明的十大算法之一。
为什么这很重要?
如果你想把真实世界的事件(带有时间戳)映射到对应的区块号,这种方法高效而且不需要任何特殊的数据库权限——只需要公共 RPC 节点即可。
英文:How would you do Binary Search to Locate a Block given a TimeStamp (for Any Blockchain)?
强烈推荐
- 英国代购-畅购英伦
- TopCashBack 返现 (英国购物必备, 积少成多, 我2年来一共得了3000多英镑)
- Quidco 返现 (也是很不错的英国返现网站, 返现率高)
- 注册就送10美元, 免费使用2个月的 DigitalOcean 云主机(性价比超高, 每月只需5美元)
- 注册就送10美元, 免费使用4个月的 Vultr 云主机(性价比超高, 每月只需2.5美元)
- 注册就送10美元, 免费使用2个月的 阿里 云主机(性价比超高, 每月只需4.5美元)
- 注册就送20美元, 免费使用4个月的 Linode 云主机(性价比超高, 每月只需5美元) (折扣码: PodCastInit2022)
- PlusNet 英国光纤(超快, 超划算! 用户名 doctorlai)
- 刷了美国运通信用卡一年得到的积分 换了 485英镑
- 注册就送50英镑 – 英国最便宜最划算的电气提供商
- 能把比特币莱特币变现的银行卡! 不需要手续费就可以把虚拟货币法币兑换
微信公众号: 小赖子的英国生活和资讯 JustYYUK