时间戳
Rooch 的 Framework 提供了一个时间戳功能,位于 frameworks/rooch-framework/sources/timestamp.move
,它保存的是 Unix 时间。UNIX 时间,或称 POSIX 时间是 UNIX 或类 UNIX 系统使用的时间表示方式:从 UTC1970 年 1 月 1 日 0 时 0 分 0 秒起至现在的总秒数,在多数 Unix 系统上 Unix 时间可以透过 date +%s
命令来检查。
该模块保存一个全局挂钟,以毫秒为单位存储当前 Unix 时间。
通过时间戳,能确切定位到 Rooch 网络的创世时间。作为 Layer2,Rooch 需要同步 Layer1 上的区块信息,则时间戳是其保持数据同步的关键因素。
Rooch 需要通过 Layer1 的区块头的时间戳来更新或者检查自身的时间戳。
在未来 Rooch 还将实现 TickTransaction
,则可以通过时间的偏移量来更新自身的时间戳。
中继以太坊区块信息
目前 Rooch 已经实现了中继以太坊区块信息的功能,可以通过下面这条命令来源源不断地获取以太坊上的区块交易信息:
rooch server start --eth-rpc-url https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161
注意观察区块高度
number
之后的timestamp
。
如何查看当前时间戳
在启动中继服务后,我们可以使用 rooch object --id 0x2::timestamp::Timestamp
命令来获取时间戳对象返回的一些信息,在这些返回信息中就包含了当前的时间戳。
rooch object --id 0x2::timestamp::Timestamp
{
"value": "0x711ab0301fd517b135b88f57e84f254c94758998a602596be8ae7ba56a0d14b300000000000000000000000000000000000000000000000000000000000000000060f968ce8b010000",
"value_type": "0x2::object::ObjectEntity<0x2::timestamp::Timestamp>",
"decoded_value": {
"abilities": 0,
"type": "0x2::object::ObjectEntity<0x2::timestamp::Timestamp>",
"value": {
"flag": 0,
"id": "0x3a7dfe7a9a5cd608810b5ebd60c7adf7316667b17ad5ae703af301b74310bcca",
"owner": "0x0000000000000000000000000000000000000000000000000000000000000000",
"value": {
"abilities": 8,
"type": "0x2::timestamp::Timestamp",
"value": {
"milliseconds": "1699975068000" <== Note!
}
}
}
}
}
注意
milliseconds
这一行数据,这就是 Rooch 记录的时间戳!
因为 Rooch 的时间戳最小粒度是毫秒,如上面的输出结果 1699975068000
,所以我们把最后三个零去掉即是实际上的时间戳了,即 1699975068
。
让时间戳向前推进
Rooch 的时间戳模块目前提供了一个改变当前时间戳的入口函数:
public entry fun fast_forward_seconds_for_local(ctx: &mut Context, timestamp_seconds: u64)
我们尝试在命令行调用一下这个函数:
rooch move run --function 0x3::timestamp::fast_forward_seconds_for_local --args u64:22222222222
再次查看时间戳:
rooch object --id 0x2::timestamp::Timestamp
{
"value": "0x711ab0301fd517b135b88f57e84f254c94758998a602596be8ae7ba56a0d14b3000000000000000000000000000000000000000000000000000000000000000000d09941d2c1150000",
"value_type": "0x2::object::ObjectEntity<0x2::timestamp::Timestamp>",
"decoded_value": {
"abilities": 0,
"type": "0x2::object::ObjectEntity<0x2::timestamp::Timestamp>",
"value": {
"flag": 0,
"id": "0x3a7dfe7a9a5cd608810b5ebd60c7adf7316667b17ad5ae703af301b74310bcca",
"owner": "0x0000000000000000000000000000000000000000000000000000000000000000",
"value": {
"abilities": 8,
"type": "0x2::timestamp::Timestamp",
"value": {
"milliseconds": "23922200386000"
}
}
}
}
}
此时,时间戳确实已经前进了非常多。但是要注意,这个特性只能在本地网络上使用,因为现实的时间不会因为我们的一条命令而改变!
这个功能也许在日后开发游戏方面的场景会应用比较多。
使用时间戳函数
在启动中继服务后,我们可以调用时间戳函数来获取当前的时间戳。
下面简单地编写了一个入口函数来演示获取时间戳的值:
module timestamp::timestamp {
use std::debug::print;
use moveos_std::timestamp::{Self, Timestamp};
use moveos_std::object::Object;
use moveos_std::object;
entry fun get_timestamp(timestamp_obj: &Object<Timestamp>) {
let timestamp = object::borrow(timestamp_obj);
let now_seconds = timestamp::seconds(timestamp);
print(&now_seconds);
}
}
这里使用了 std::debug::print
函数,可以通过观察服务端中的输出,来确定是否准确获取到了时间戳。
因为 Rooch 的时间戳最小粒度是毫秒,所以我们还需要使用模块内提供的 seconds
函数转换一下,如此就能得到我们实际上的时间戳了。
将测试的合约部署后,我们来尝试调用这个函数,并观察终端里的输出。
启动中继服务后,执行 Shell 命令:
rooch move run --function 0x9fd886140ae373a85101d2c7a5f2eda077ca9a05c3b1c221594ff4473a702c83::timestamp::get_timestamp --args object:0x2::timestamp::Timestamp --sender-account default
可以从服务端看到 debug
消息,我们已经成功获取到时间戳的值了。