ckb_ssri_std/public_module_traits/
udt.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use ckb_std::ckb_types::{
    bytes::Bytes,
    packed::{Byte32Vec, Script, Transaction},
};
extern crate alloc;

use alloc::vec::Vec;
use serde::{Deserialize, Serialize};

/// User-Defined Token (UDT) trait for implementing custom tokens on CKB
///
/// This trait defines the standard interface for implementing fungible tokens
/// on the CKB blockchain following the SSRI protocol. 
///
/// # Implementation Notes
///
/// - All amounts are represented as u128 in convention
/// - Methods that modify state return a Transaction that must be committed
/// - Verification methods are separate from state-changing methods
///
/// # Example
///
/// ```rust,no_run
/// use ckb_ssri_std::public_module_traits::udt::UDT;
///
/// struct MyToken;
///
/// impl UDT for MyToken {
///     type Error = ();
///     
///     fn balance() -> Result<u128, Self::Error> {
///         // Implementation
///         Ok(0)
///     }
///     // ... implement other required methods
/// }
/// ```
pub trait UDT {
    type Error;
    fn transfer(
        tx: Option<Transaction>,
        to_lock_vec: Vec<Script>,
        to_amount_vec: Vec<u128>,
    ) -> Result<Transaction, Self::Error>;
    fn verify_transfer() -> Result<(), Self::Error>;
    fn name() -> Result<Bytes, Self::Error>;
    fn symbol() -> Result<Bytes, Self::Error>;
    fn decimals() -> Result<u8, Self::Error>;
    fn icon() -> Result<Bytes, Self::Error>;
    fn mint(
        tx: Option<Transaction>,
        to_lock_vec: Vec<Script>,
        to_amount_vec: Vec<u128>,
    ) -> Result<Transaction, Self::Error>;
    fn verify_mint() -> Result<(), Self::Error>;
}
pub const UDT_LEN: usize = 16;
pub enum UDTError {
    InsufficientBalance,
    NoMintPermission,
    NoBurnPermission,
}

pub trait UDTPausable: UDT {
    /* NOTE: Pausing/Unpause without lock hashes should take effect on the global level */
    fn pause(
        tx: Option<Transaction>,
        lock_hashes: &Vec<[u8; 32]>,
    ) -> Result<Transaction, Self::Error>;
    fn unpause(
        tx: Option<Transaction>,
        lock_hashes: &Vec<[u8; 32]>,
    ) -> Result<Transaction, Self::Error>;
    fn is_paused(lock_hashes: &Vec<[u8; 32]>) -> Result<Vec<bool>, Self::Error>;
    fn enumerate_paused(offset: u64, limit: u64) -> Result<Byte32Vec, Self::Error>;
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct UDTPausableData {
    pub pause_list: Vec<[u8; 32]>,
    pub next_type_script: Option<ScriptLike>
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ScriptLike {
    pub code_hash: [u8; 32],
    pub hash_type: u8,
    pub args: Vec<u8>,
}
pub enum UDTPausableError {
    NoPausePermission,
    NoUnpausePermission,
    AbortedFromPause,
    IncompletePauseList,
    CyclicPauseList,
}