Implementing Transferable Witness Pattern in Sui
In this tutorial, we will demonstrate how to implement the Transferable Witness pattern in the Sui ecosystem. This pattern is based on a combination of two other patterns: Capability and Witness. Transferable Witness pattern can be useful when type authorization by one module is needed to be used in another module or when authorization should be performed after some time.
Here are the steps to implement the Transferable Witness pattern:
- Create the transferable_witness module: Define a new module
examples::transferable_witnessthat will implement the Transferable Witness pattern.
module examples::transferable_witness {
use sui::transfer;
use sui::object::{Self, UID};
use sui::tx_context::{Self, TxContext};
}
- Define the WITNESS type: Create a
WITNESStype that hasstoreanddropabilities. Thestoreability allows storing the witness inside a wrapper.
struct WITNESS has store, drop {}
- Define the WitnessCarrier type: Create a
WitnessCarriertype that has thekeyability and carries theWITNESStype. TheWitnessCarriercan be used only once to get aWITNESS.
struct WitnessCarrier has key { id: UID, witness: WITNESS }
- Initialize the module: Create an
initfunction that sends aWitnessCarrierto the module publisher. This function will be called once on module publish.
fun init(ctx: &mut TxContext) {
transfer::transfer(
WitnessCarrier { id: object::new(ctx), witness: WITNESS {} },
tx_context::sender(ctx)
)
}
- Create the get_witness function: Define a public function
get_witnessthat takes aWitnessCarrieras an argument and returns the innerWITNESStype. The function unwraps the carrier and deletes the carrier'sidbefore returning thewitness.
public fun get_witness(carrier: WitnessCarrier): WITNESS {
let WitnessCarrier { id, witness } = carrier;
object::delete(id);
witness
}
By following these steps, you can implement the Transferable Witness pattern in the Sui ecosystem. This pattern combines the Capability and Witness patterns to allow type authorization by one module to be used in another module or to perform authorization after some time.