Skip to content

Instantly share code, notes, and snippets.

@damirka
Last active January 4, 2023 18:45
Show Gist options
  • Save damirka/4ea58a8326d32336321d195e2a4d0851 to your computer and use it in GitHub Desktop.
Save damirka/4ea58a8326d32336321d195e2a4d0851 to your computer and use it in GitHub Desktop.
module sui::publisher {
use std::type_name;
use sui::object::{Self, UID};
use sui::tx_context::TxContext;
use sui::types;
use sui::bcs;
/// This type can only be created in the transaction that
/// generates a module, by consuming its one-time witness, so it
/// can be used to identify the address that published the package
/// a type originated from.
///
/// It does not have `store`, to prevent it being transferred to
/// another address, but it can be burned.
struct Publisher has key, store {
id: UID,
package: address // TypeName
}
/// Tried to claim ownership using a type that isn't a one-time witness.
const ENotOneTimeWitness: u64 = 0;
public fun claim<OTW: drop>(otw: OTW, ctx: &mut TxContext): Publisher {
assert!(types::is_one_time_witness(&otw), ENotOneTimeWitness);
Publisher {
id: object::new(ctx),
package: addr<OTW>(),
}
}
public fun addr<T>(): address {
// we need to decode hex (40 bytes -> 20 here)
let bytes = bcs::new(bcs::to_bytes(&type_name::get<T>()));
bcs::peel_vec_lengh(&mut bytes);
bcs::peel_address(&mut bytes)
}
public fun burn(publisher: Publisher) {
let Publisher { id, package: _ } = publisher;
object::delete(id);
}
/// Check whether this Publisher owns the type `T`.
public fun owns<T>(publisher: &Publisher): bool {
addr<T>() == publisher.package
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment