Skip to main content

消费

由于 Token 类型没有 store 能力,因此无法将其“存储”在另一个对象中。因此,不可能采用类似于 Coin 的方式进行消费 - 接受 Token 作为支付的应用程序将无法将其添加到其余额中。为了解决这个问题,Token 有一个 "spend" 方法,允许在一个应用程序中 "消费" 它,然后将其作为 spent_balance 交付给 TokenPolicy 或者立即使用 TreasuryCap 进行销毁。

消费操作

通过调用 spend 方法,可以消费 Token。它接受以下参数:

// module sui::token
public fun spend<T>(token: Token<T>, ctx: &mut TxContext): ActionRequest<T>;

从签名中可以看出,Token 对象被消耗。其余额将成为 ActionRequest 中的 spent_balance

消费的 Token

“消费” 操作的 ActionRequest 包含被消费的 TokenBalance,可以通过 使用 TreasuryCap 确认 或者 交付给 TokenPolicy。在第一种情况下,余额将直接在 TreasuryCap 中 "销毁",在第二种情况下,它将被交付到 TokenPolicy 的 "spent_balance"。

已消费的余额无法以任何方式使用,也不可能 "提取" 它。唯一可用的操作是 "刷新" - 通过提供 TreasuryCap 来销毁 spent_balance

限制消费操作

通常,spend 操作应该至少有一个分配给它的 "Rule",以防止无谓的消费,并且在接受 Token 的应用程序中授权 spend 的推荐方式是在执行 spend 的函数中直接进行 "戳记"。例如:

/// Rule-like witness to stamp the ActionRequest
struct GiftShop has drop {}

/// Spend the token and return a Gift + ActionRequest
public fun buy_gift(
token: Token<CREDITS>,
ctx: &mut TxContext
): (Gift, ActionRequest<CREDITS>) {

// token is spent
let action_request = token::spend(token, ctx);

// stamp the ActionRequest as performed by GiftShop
token::add_approval(GiftShop {}, &mut action_request, ctx);

// return already "stamped" ActionRequest
(Gift { ... }, action_request)
}