Допис
Діліться своїми знаннями.
Розуміння модуля годинника Sui та використання часових міток
Я будую чутливу до часу логіку вSui Move(наприклад, заслуга токенів, терміни аукціону), але борюся з надійною обробкою часових міток. Ключові питання:
- Об'єкт годинника: Навіщо Sui потрібен спільний годинник замість блокових часових міток?
- Точність: Наскільки точні ці часові мітки порівняно з часом блоку?
- Шаблони використання: найкращі практики щодо блокування часу, термінів та планування?
- Тестування: Як знущати час у одиничних тестах?
Поточні питання:
- Базове використання sui:: clock працює, але відчувається обмежувальним
- Не впевнений, як обробляти час на різних ділянках/валідаторах
- Тестування логіки, залежної від часу, є невдалим
- Sui
Відповіді
2####1. Фундаменти годинника Sui
Чому спільний годинник? Модель паралельного виконання Суй означає:
- Немає гарантованого порядку блоків → не можна використовувати номери блоків/мітки часу
- це**
Clock
спільний об'єкт**, що забезпечує час, підтримуваний консенсусом
Основна структура:
module sui::clock {
struct Clock has key {
id: UID,
timestamp_ms: u64,
}
}
Ключові властивості:
- Оновлюється кожні2 секунди(налаштовується валідаторами)
- Точність мілісекунд (проти блоків ~ 12s Ethereum)
- Незмінний - не може бути змінений договорами
####2. Практичні схеми використання
#####Базова перевірка часу
use sui::clock;
public entry fn execute_if_ready(
clock: &Clock,
lock: &mut LockedAsset
) {
assert!(clock.timestamp_ms >= lock.unlock_time, ELocked);
// Release assets
}
#####Термін виконання термінів
struct Auction has key {
id: UID,
end_time: u64, // Stored as Clock timestamp
highest_bid: u64
}
public entry fn bid(
auction: &mut Auction,
clock: &Clock,
bid_amount: u64
) {
assert!(clock.timestamp_ms < auction.end_time, EAuctionEnded);
// Process bid
}
#####Дії, заблоковані час
struct VestingSchedule has key {
id: UID,
start_time: u64,
cliff_duration: u64 // In milliseconds
}
public fun claimable_amount(
vesting: &VestingSchedule,
clock: &Clock
): u64 {
let elapsed = clock.timestamp_ms - vesting.start_time;
// Linear vesting math
}
####3. Розширені міркування
#####Консистенція осколку
- Усі осколки бачатьту саму часову мітку годинникав межах транзакції
- Для крос-осколкових операцій передайте
&Clock
як посилання на спільний об'єкт
#####Оптимізація газу
- Зберігайтевідносний час(наприклад,
duration_ms: u64
) замість абсолютного, де це можливо - Повторне використання одного і того ж
Clock
посилання між функціями
#####**Обробка помилок
const MAX_CLOCK_DRIFT_MS: u64 = 3000; // 3s tolerance
public fun validate_clock(clock: &Clock) {
assert!(tx_context::epoch(ctx) == clock.epoch(), EStaleClock);
assert!(clock.timestamp_ms <= tx_context::now_ms(ctx) + MAX_CLOCK_DRIFT_MS, EInvalidTime);
}
####4. Стратегії тестування
#####Насмішливий годинник у тестах
#[test_only]
fun mock_clock(timestamp_ms: u64): Clock {
Clock { id: test_scenario::new_object(ctx), timestamp_ms }
}
#[test]
fun test_vesting() {
let clock = mock_clock(1000);
let vesting = VestingSchedule { start_time: 0, ... };
// Test claimable amount at t=1000
}
#####Тести переходу епохи
#[test]
fun test_clock_epoch_change() {
let mut scenario = test_scenario::begin(...);
// Advance epoch
test_scenario::next_epoch(&mut scenario);
let clock = test_scenario::take_shared<Clock>(scenario);
assert!(clock.epoch() == 1, EEpochError);
}
Якщо ви працюєте над логікою, чутливою до часу, як-от аукціони або графіки накладення в Sui Move, sui::clock
модуль є вашим найкращим способом відстеження часу. Sui не покладається на блокові часові мітки, такі як Ethereum або Solana, оскільки він спрямований на детерміноване виконання та паралелізм. Ось чому він використовуєспільний об'єкт годинника, який оновлюється один раз на контрольну точку та дає вам канонічне джерело часу.
Ви взаємодієте з часом, читаючи з цього спільного об'єкта годинника (зазвичай передається у функції введення) за допомогоюclock.timestamp
. Це значення оновлюється приблизно кожну секунду і дає вам поточну мітку часу UNIX у секундах. Хоча він не прив'язаний до кожного блоку, як у EVM, він досить точний для практичних випадків використання, таких як розблокування токенів або термін дії ставок - просто не точність рівня мікросекунди.
Під час створення логіки, заснованої на часі, завжди чітко передавайте об'єкт Clock, щоб функція «Переміщення» могла прочитати його та порівнювати часові мітки із збереженими термінами. Щоб уникнути жорсткої поведінки, використовуйте пільгові періоди або свободу у своїх порівняннях (if current_time > unlock_time + buffer
) та уникайте покладатися на точні секунди.
Для тестування Sui дозволяємакетувати годинник у тестах одиниця, створивши власний екземпляр спільного об'єкта з власною міткою часу. Таким чином, ви можете імітувати майбутні умови, не потребуючи реального часу. Просто побудуйте Годинник вручну із встановленим значенням у ваших #[test]
функціях.
Якщо ви відчуваєте себе обмеженим, це, ймовірно, пов'язано з тим, як Суй захищає Годинник від мутації поза контрольними пунктами. Вам потрібно буде спроектувати свої модулі, щоб очікувати часових міток як вхідних даних, і читати їх з офіційного спільного об'єкта. Уникайте створення власного джерела часу, оскільки це порушує детермінізм.
Ви знаєте відповідь?
Будь ласка, увійдіть та поділіться нею.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Зароби свою частку з 1000 Sui
Заробляй бали репутації та отримуй винагороди за допомогу в розвитку спільноти Sui.
- Чому BCS вимагає точного порядку полів для десеріалізації, коли структури Move мають названі поля?53
- Помилки перевірки кількох джерел» у публікаціях модуля Sui Move - автоматичне вирішення помилок43
- Невдала операція Sui: об'єкти, зарезервовані для іншої транзакції25
- Як обмеження здібностей взаємодіють з динамічними полями в гетерогенних колекціях?05