为什么从 ethers.js 获取的区块时间戳不等于 etherscan.io 中显示的时间戳?

cru*_*age 4 ethereum etherscan ethers.js

import {providers} from "ethers";

const provider = new providers.InfuraProvider("homestead")

async function main() {
    provider.on("block", (blockNum)=> {
        console.log(blockNum+ ": " +new Date(Date.now()))
    })
}

main()
Run Code Online (Sandbox Code Playgroud)

从上面的代码输出:

13261128: Mon Sep 20 2021 14:57:42 GMT+0800 
13261129: Mon Sep 20 2021 14:58:14 GMT+0800 
13261130: Mon Sep 20 2021 14:58:42 GMT+0800 
13261131: Mon Sep 20 2021 14:58:58 GMT+0800 
Run Code Online (Sandbox Code Playgroud)

来自 etherscan.io:

Sep-20-2021 06:57:12 AM +UTC (https://etherscan.io/block/13261028)
Sep-20-2021 06:57:23 AM +UTC (https://etherscan.io/block/13261129)
Sep-20-2021 06:58:07 AM +UTC (https://etherscan.io/block/13261130)
Sep-20-2021 06:58:38 AM +UTC (https://etherscan.io/block/13261131)
Run Code Online (Sandbox Code Playgroud)

我的问题

  1. 我的电脑的时钟是准确的时间,为什么这两种方式有差异?

  2. 我可以从 ethers.js API 获取准确的区块时间,还是可以从其他方式获取?

小智 9

  1. 该块的时间戳采用 UTC(因此是 @Dmitriy Kashirin 提到的时区偏移),并不代表该块被挖掘的确切时间,因为它是由矿工设置的。因此,允许轻微的偏移,并且时间戳不应该用作敏感合约的随机性来源。在这里阅读更多内容。

  2. 是的,使用 ethers.js 和 RPC 提供程序可以相当简单地获得确切块的时间戳:

const RPC = "RPC_OF_THE_NETWORK";
const blockNumber = 1; // number of the block you want to get timestamp of
const provider = new ethers.providers.JsonRpcProvider(RPC)

const timestamp = (await provider.getBlock(blockNumber)).timestamp;
Run Code Online (Sandbox Code Playgroud)