Implementing the Witness Pattern for Confirming Type Ownership in Sui
In this tutorial, we will demonstrate how to implement the Witness pattern to confirm the ownership of a type in the Sui ecosystem. The Witness pattern is used for confirming ownership by passing a drop instance of a type. We will create a custom Guardian type that can only be instantiated with a witness and a PEACE type to demonstrate the pattern.
Follow these steps to implement the Witness pattern:
- Define the Guardian type: Create a module that defines a generic type
Guardian<T>which can only be instantiated with a witness. The phantom parameterTcan only be initialized in thecreate_guardianfunction, and the types passed must have thedropability.
module examples::guardian {
use sui::object::{Self, UID};
use sui::tx_context::TxContext;
struct Guardian<phantom T: drop> has key, store {
id: UID
}
}
- Create the create_guardian function: Define a public function
create_guardianthat takes an actual instance of typeTwithdropability as its first argument. This instance is dropped as soon as it is received.
public fun create_guardian<T: drop>(
_witness: T, ctx: &mut TxContext
): Guardian<T> {
Guardian { id: object::new(ctx) }
}
- Create the custom module: Define a custom module
examples::peace_guardianthat makes use of theguardiantype. Create a customPEACEtype with thedropability, which is intended to be used only once.
module examples::peace_guardian {
use sui::transfer;
use sui::tx_context::{Self, TxContext};
// Use the `guardian` as a dependency.
use 0x0::guardian;
struct PEACE has drop {}
}
- Initialize the module: Create a module initializer function that is called once on module publish. This is the best way to ensure that the code is called only once, which is often the best practice with the Witness pattern. Inside this function, transfer a newly created
Guardianinstance to the sender.
fun init(ctx: &mut TxContext) {
transfer::public_transfer(
guardian::create_guardian(PEACE {}, ctx),
tx_context::sender(ctx)
)
}
By following these steps, you can implement the Witness pattern for confirming the ownership of a type in the Sui ecosystem. In this example, we created a custom Guardian type that can only be instantiated with a witness and demonstrated the pattern using the PEACE type.