Let'sMove0基础web2向web3迁移指南(4)实战篇时间戳
<!--StartFragment-->
对于web2时代,我们无论是前端还是后端,都经常和时间戳打交道,比如计算时间差,计算时间点等. 前端方面也经常对时间戳进行格式化,比如时间差,时间点等. 后端一般把时间戳作为一个字段入库,并制作API接口供前端调用.
到了sui web3时代,我们同样需要和时间戳打交道,sui提供了时间戳Clock模块,我们只需要调用模块即可获取时间戳.
让我们来实战使用一下.
首先设计函数和引入Clock模块
use sui::clock::{Self, Clock};
...
...
public entry fun shownumber(clock: &Clock){
let des_number = clock::timestamp_ms(clock);
print(&des_number);
}
我们设计了一个显示时钟的函数,并引入了Clock模块.
编译没问题后
发布合约
sui client publish --skip-fetch-latest-git-deps --skip-dependency-verification --gas-budget 100000000
执行合约
sui client call --package 0x167e1f2c267fac00afe059fad54bfe49b211badcd945781cd506ed13251702df --module tbase --function shownumber --args 0x6 --gas-budget 100000000
简单介绍一下参数
--package 后面跟package id
--module 后面跟模块名
--function 后面跟函数名
--args 后面跟参数: clock的地址
--gas-budget 后面跟gas消耗
执行后发现控制台并没有打印出任何东西,说明movecall执行合约时控制台已经没有输出了。
为了方便观察,我们设计一个事件
struct TbaseExt has copy, drop {
tbase_ext: u64,
}
修改函数
public entry fun shownumber(clock: &Clock){
let des_number = clock::timestamp_ms(clock);
//can not see the number in client
print(&des_number);
event::emit(TbaseExt{
tbase_ext:des_number
});
}
增加了事件触发 emit方法
继续编译&发布合约并执行新的合约
获取事件
╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: 8bb71wGceqBhqnG4YDcEMjDzrqWuJTL5aTY9DA9YZUQA:0 │
│ │ PackageID: 0x167e1f2c267fac00afe059fad54bfe49b211badcd945781cd506ed13251702df │
│ │ Transaction Module: tbase │
│ │ Sender: 0xb32458b39bbf1d504cc2deadf51775b1bce2d32a8aa8145d7fcbbd7c0335e328 │
│ │ EventType: 0x167e1f2c267fac00afe059fad54bfe49b211badcd945781cd506ed13251702df::tbase::TbaseExt │
│ │ ParsedJSON: │
│ │ ┌───────────┬───────────────┐ │
│ │ │ tbase_ext │ 1713088930391 │ │
│ │ └───────────┴───────────────┘ │
│ └── │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯
在 Transaction Block Events 我们看到了事件信息 tbase_ext 1713088930391
这个 u64的数字 1713088930391 不太直观,需要转换成日期格式。这串数字是13位的,是毫秒级的时间戳。
10位的数字是秒级的时间戳。
我们需要实际验证一下,看看这个数字是否是毫秒级的时间戳。
可以利用python对数据进行验证(实际动手很重要)
import datetime
timestamp = 1713088930391 # 毫秒级的时间戳
# 将毫秒转换为秒
timestamp_seconds = timestamp / 1000
# 使用datetime将时间戳转换为日期格式
date = datetime.datetime.fromtimestamp(timestamp_seconds)
print(date)
运行后得到结果,说明clock 0x6 对象 获得的时间戳是毫秒级的时间戳
由此在sui move 获取时间戳试验以及基本成功了。同学们可以使用这个长度13位的时间戳做很多事情。
为了在链上实际测试随机数,我们接着设计一个事件
struct TrndExt has copy, drop {
trnd_ext: u8,
}
设计函数(仅测试用)
public entry fun showrandom(r: &Random, ctx: &mut TxContext){
let generator = new_generator(r, ctx);
let v = random::generate_u8_in_range(&mut generator, 1, 100);
event::emit(TrndExt{
trnd_ext:v
});
}
使用random的时候会得到的一个warning
Functions that accept 'sui::random::Random' as a parameter might be abused by attackers by inspecting the results of randomness
截止目前,sui move testnet 还没 0x8 这个Random对象
所以我们需要切换到 devnet 测试随机数 (当前sui的版本是 v 1.22 )
执行调用合约 注意参数 --args 0x8 ,刚才我们测时间戳是 0x6
sui client call --package 0x95638250c4c9616417eb2238f3326f6b91e9f6ce242062fcbbb4fb6afdeb12ef --module tbase --function showrandom --args 0x8 --gas-budget 100000000
结果
╭─────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Block Events │
├─────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ┌── │
│ │ EventID: 8dqHgqXkSFYtJEECBdBhPEiVFHbVwSUCm8kGmgsbb3c7:0 │
│ │ PackageID: 0x050818073dcc5d5758327de7b1a872a5c0b9dca4ba1cf2c58e8a26eb9ff13f6b │
│ │ Transaction Module: tbase │
│ │ Sender: 0xb32458b39bbf1d504cc2deadf51775b1bce2d32a8aa8145d7fcbbd7c0335e328 │
│ │ EventType: 0x50818073dcc5d5758327de7b1a872a5c0b9dca4ba1cf2c58e8a26eb9ff13f6b::tbase::TrndExt │
│ │ ParsedJSON: │
│ │ ┌──────────┬────┐ │
│ │ │ trnd_ext │ 85 │ │
│ │ └──────────┴────┘ │
│ └── │
╰─────────────────────────────────────────────────────────────────────────────────────────────────╯
在运行一下 获得
│ │ ┌──────────┬────┐ │
│ │ │ trnd_ext │ 22 │ │
│ │ └──────────┴────┘ │
说明随机数生成器 0x8 对象 已经存在并工作正常
最后,在实际使用的时候要去掉public
//#[allow(lint(public_random))]
entry fun showrandom(r: &Random, ctx: &mut TxContext){
let generator = new_generator(r, ctx);
let v = random::generate_u8_in_range(&mut generator, 1, 100);
event::emit(TrndExt{
trnd_ext:v
});
}
另 generator 最好也不要当成参数传递,而是直接使用,防止被攻击者利用。
在sui move 中,我们学习并实际尝试了如何使用时间戳和随机数。 本文通过细致的解读步骤,帮助同学们一步一步的理解。
不过最重要的还是需要同学们自己动手实践,才能真正掌握,走马观花看一遍不解决实际问题。
copy一下代码有何意义呢?
留个思考:
如何避免 快乐流程所消耗的gas要少于不快乐流程所消耗的gas?
(未完待续)
Let's Move 中文社区
telegram: https://t.me/move_cn
QQ群: 79489587
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!