首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在时间戳之间获取块

问如何在时间戳之间获取块
EN

Ethereum用户
提问于 2018-11-09 07:31:44
回答 4查看 5.9K关注 0票数 5

我想在给时间戳之间取几块。目前我手动使用

代码语言:javascript
复制
fromBlock: (await web3.eth.getBlockNumber()) - 12343
toBlock: (await web3.eth.getBlockNumber()) - 6172

昨天的街区。有没有办法在时间戳之间使用web3获取块?

EN

回答 4

Ethereum用户

回答已采纳

发布于 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版本,您可以:

票数 4
EN

Ethereum用户

发布于 2020-03-16 12:45:48

如果您需要二进制搜索实现,这里是用于Python 3的:

代码语言:javascript
复制
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
票数 4
EN

Ethereum用户

发布于 2021-08-30 15:29:57

实际上,可以利用块时间是局部的、大致线性分离的这一事实来优化,远远超过二进制搜索。

这段代码通常需要5个或更少的取数才能找到与给定unix时间戳最近的块,并且基准比二进制搜索快10倍:

代码语言:javascript
复制
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)

测试:

代码语言:javascript
复制
import arrow

tunix_s = arrow.get('2021-03-11T12:34:56').timestamp()

block = iblock_near(tunix_s)

输出:

票数 2
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/62007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档