Events
Events are the main way to track actions on chain. The following example includes comments to document the logic of the code. The example extends the donut example used elsewhere in the documentation to include events that are emitted when someone purchases a donut and when the DonutShop
collects coins from that sale. You could then set up subscriptions to listen for these events, then trigger logic when those events fire.
/// Extended example of a shared object. Now with addition of events!
module examples::donuts_with_events {
use iota::iota::IOTA;
use iota::coin::{Self, Coin};
use iota::balance::{Self, Balance};
// This is the only dependency you need for events.
use iota::event;
/// For when Coin balance is too low.
const ENotEnough: u64 = 0;
/// Capability that grants an owner the right to collect profits.
public struct ShopOwnerCap has key { id: UID }
/// A purchasable Donut. For simplicity's sake we ignore implementation.
public struct Donut has key { id: UID }
public struct DonutShop has key {
id: UID,
price: u64,
balance: Balance<IOTA>
}
// ====== Events ======
/// For when someone has purchased a donut.
public struct DonutBought has copy, drop {
id: ID
}
/// For when DonutShop owner has collected profits.
public struct ProfitsCollected has copy, drop {
amount: u64
}
// ====== Functions ======
fun init(ctx: &mut TxContext) {
transfer::transfer(ShopOwnerCap {
id: object::new(ctx)
}, tx_context::sender(ctx));
transfer::share_object(DonutShop {
id: object::new(ctx),
price: 1000,
balance: balance::zero()
})
}
/// Buy a donut.
public fun buy_donut(
shop: &mut DonutShop,
payment: &mut Coin<IOTA>,
ctx: &mut TxContext,
): Donut {
assert!(coin::value(payment) >= shop.price, ENotEnough);
let coin_balance = coin::balance_mut(payment);
let paid = balance::split(coin_balance, shop.price);
let id = object::new(ctx);
balance::join(&mut shop.balance, paid);
// Emit the event using future object's ID.
event::emit(DonutBought { id: object::uid_to_inner(&id) });
Donut { id }
}
/// Consume donut and get nothing...
public fun eat_donut(d: Donut) {
let Donut { id } = d;
object::delete(id);
}
/// Take coin from `DonutShop` and transfer it to tx sender.
/// Requires authorization with `ShopOwnerCap`.
public fun collect_profits(
_: &ShopOwnerCap,
shop: &mut DonutShop,
ctx: &mut TxContext,
): Coin<IOTA> {
let amount = balance::value(&shop.balance);
let profits = coin::take(&mut shop.balance, amount, ctx);
// simply create new type instance and emit it
event::emit(ProfitsCollected { amount });
profits
}
}
Related links
- Using Events: A guide to leveraging IOTA events in your smart contracts.
Question 1/3
What is the main purpose of events in IOTA Move smart contracts?
Feedback Form