我想在给时间戳之间取几块。目前我手动使用
fromBlock: (await web3.eth.getBlockNumber()) - 12343
toBlock: (await web3.eth.getBlockNumber()) - 6172昨天的街区。有没有办法在时间戳之间使用web3获取块?
发布于 2018-11-09 11:59:07
如果希望在timestamp1 <= block.timestamp <= timestamp2之间设置块,可以执行二进制搜索:
fromBlock上,您可以找到满足web3.eth.getBlock(fromBlock).timestamp <= timestamp1的toBlock上,您可以找到满足timestamp2 <= web3.eth.getBlock(fromBlock).timestamp的然后,根据您的Web3版本,您可以:
发布于 2020-03-16 12:45:48
如果您需要二进制搜索实现,这里是用于Python 3的:
web3 = Web3(WebsocketProvider("...."))
a = 1484362538 # 01/14/2017 @ 2:55am (UTC)
def estimate_block_height_by_timestamp(timestamp):
block_found = False
last_block_number = 9682416
close_in_seconds = 600
while not block_found:
block = web3.eth.getBlock(last_block_number)
block_time = datetime.datetime.fromtimestamp(block.timestamp).date()
difference_in_seconds = int((timestamp - block_time).total_seconds())
block_found = abs(difference_in_seconds) < close_in_seconds
if block_found:
return last_block_number
if difference_in_seconds < 0:
last_block_number //= 2
else:
last_block_number = int(last_block_number * 1.5) + 1
block = estimate_block_height_by_timestamp(
datetime.datetime.fromtimestamp(a).date()
)
print(block)
>>> 2994181
# https://etherscan.io/block/2994181
# Block time - Jan-14-2017 11:21:00 AM +UTC发布于 2021-08-30 15:29:57
实际上,可以利用块时间是局部的、大致线性分离的这一事实来优化,远远超过二进制搜索。
这段代码通常需要5个或更少的取数才能找到与给定unix时间戳最近的块,并且基准比二进制搜索快10倍:
import arrow
T = lambda i_block: web3.eth.getBlock(i_block).timestamp
ilatest = web3.eth.get_block('latest')['number']
def iblock_near(tunix_s, ipre=1, ipost=ilatest):
ipre = max(1, ipre)
ipost = min(ilatest, ipost)
if ipre == ipost:
print('Got it')
return ipre
t0, t1 = T(ipre), T(ipost)
av_block_time = (t1 - t0) / (ipost-ipre)
# if block-times were evenly-spaced, get expected block number
k = (tunix_s - t0) / (t1-t0)
iexpected = int(ipre + k * (ipost - ipre))
# get the ACTUAL time for that block
texpected = T(iexpected)
# use the discrepancy to improve our guess
est_nblocks_from_expected_to_target = int((tunix_s - texpected) / av_block_time)
iexpected_adj = iexpected + est_nblocks_from_expected_to_target
print()
print(f'target timestamp ({tunix_s}) lies {k:.3f} of the way from block# {ipre} (t={t0}) to block# {ipost} (t={t1})')
print(f'Expected block# assuming linearity: {iexpected} (t={texpected})')
print('Expected nblocks required to reach target (again assuming linearity):', est_nblocks_from_expected_to_target)
print('New guess at block #:', iexpected_adj)
r = abs(est_nblocks_from_expected_to_target)
return iblock_near(tunix_s, iexpected_adj - r, iexpected_adj + r)测试:
import arrow
tunix_s = arrow.get('2021-03-11T12:34:56').timestamp()
block = iblock_near(tunix_s)输出:

https://ethereum.stackexchange.com/questions/62007
复制相似问题