type_hash

这个宏为给定的结构体或枚举生成一个兼容 {SNIP-12} 的类型哈希。

注意:这个宏完全兼容 {SNIP-12} 标准的修订版本 1。

用法

/// name 和 debug 是可选参数
#[type_hash(name: "My Struct", debug: true)]
struct MyStruct {
    #[snip12(name: "My Field")]
    my_field: felt252,
}

这将为结构体生成一个类型哈希。

// 编码类型: "My Struct"("My Field":"felt")
pub const MY_STRUCT_TYPE_HASH: felt252 = 0x1735aa9819941b96c651b740b792a96c854565eaff089b7e293d996828b88a8;

并且由于 debug 参数,它将生成以下代码:

pub fn __MY_STRUCT_encoded_type() {
    println!("\"My Struct\"(\"My Field\":\"felt\")");
}

基本类型

{SNIP-12} 标准中定义的支持的基本类型有:

  • felt252

  • shortstring

  • ClassHash

  • ContractAddress

  • timestamp

  • selector

  • merkletree

  • u128

  • i128

示例

具有基本类型和自定义名称和类型的结构体:

#[type_hash(name: "My Struct", debug: true)]
pub struct MyStruct {
    #[snip12(name: "Simple Felt")] // 可选的自定义名称
    pub simple_felt: felt252,
    #[snip12(name: "Class Hash")]
    pub class_hash: ClassHash,
    #[snip12(name: "Target Token")]
    pub target: ContractAddress,
    #[snip12(name: "Timestamp", kind: "timestamp")]
    pub timestamp: u128,
    #[snip12(name: "Selector", kind: "selector")]
    pub selector: felt252,
}

// 编码类型: "My Struct"("Simple Felt":"felt","Class Hash":"ClassHash",
// "Target Token":"ContractAddress","Timestamp":"timestamp","Selector":"selector")
pub const MY_STRUCT_TYPE_HASH: felt252
    = 0x522e0c3dc5e13b0978f4645760a436b1e119fd335842523fee8fbae6057b8c;

具有基本类型和自定义名称和类型的枚举:

#[type_hash(name: "My Enum", debug: true)]
pub enum MyEnum {
    #[snip12(name: "Simple Felt")]
    SimpleFelt: felt252,
    #[snip12(name: "Class Hash")]
    ClassHash: ClassHash,
    #[snip12(name: "Target Token")]
    ContractAddress: ContractAddress,
    #[snip12(name: "Timestamp", kind: "timestamp")]
    Timestamp: u128,
    #[snip12(name: "Selector", kind: "selector")]
    Selector: felt252,
}

// 编码类型: "My Enum"("Simple Felt"("felt"),"Class Hash"("ClassHash"),
// "Target Token"("ContractAddress"),"Timestamp"("timestamp"),"Selector"("selector"))
pub const MY_ENUM_TYPE_HASH: felt252
    = 0x3f30aaa6cda9f699d4131940b10602b78b986feb88f28a19f3b48567cb4b566;

集合类型

{SNIP-12} 标准中定义的支持的集合类型有:

  • Array

  • Tuple (仅支持枚举)

  • Span (视为数组)

注意:虽然 Span 没有被 {SNIP-12} 标准直接支持,但为了本宏的目的,它被视为一个数组,因为 使用 Span<felt252> 而不是 Array<felt252> 有时有助于节省 Gas。

示例

具有集合类型的结构体:

#[type_hash(name: "My Struct", debug: true)]
pub struct MyStruct {
    #[snip12(name: "Member 1")]
    pub member1: Array<felt252>,
    #[snip12(name: "Member 2")]
    pub member2: Span<u128>,
    #[snip12(name: "Timestamps", kind: "Array<timestamp>")]
    pub timestamps: Array<u128>,
}

// 编码类型: "My Struct"("Member 1":"felt*","Member 2":"u128*",
// "Timestamps":"timestamp*")
pub const MY_STRUCT_TYPE_HASH: felt252
    = 0x369cdec45d8c55e70986aed44da0e330375171ba6e25b58e741c0ce02fa8ac;

具有集合类型的枚举:

#[type_hash(name: "My Enum", debug: true)]
pub enum MyEnum {
    #[snip12(name: "Member 1")]
    Member1: Array<felt252>,
    #[snip12(name: "Member 2")]
    Member2: Span<u128>,
    #[snip12(name: "Timestamps", kind: "Array<timestamp>")]
    Timestamps: Array<u128>,
    #[snip12(name: "Name and Last Name", kind: "(shortstring, shortstring)")]
    NameAndLastName: (felt252, felt252),
}

// 编码类型: "My Enum"("Member 1"("felt*"),"Member 2"("u128*"),
// "Timestamps"("timestamp*"),"Name and Last Name"("shortstring","shortstring"))
pub const MY_ENUM_TYPE_HASH: felt252
    = 0x9e3e1ebad4448a8344b3318f9cfda5df237588fd8328e1c2968635f09c735d;

预设类型

{SNIP-12} 标准中定义的支持的预设类型有:

  • TokenAmount

  • NftId

  • u256

示例

具有预设类型的结构体:

#[type_hash(name: "My Struct", debug: true)]
pub struct MyStruct {
    #[snip12(name: "Token Amount")]
    pub token_amount: TokenAmount,
    #[snip12(name: "NFT ID")]
    pub nft_id: NftId,
    #[snip12(name: "Number")]
    pub number: u256,
}

// 编码类型: "My Struct"("Token Amount":"TokenAmount","NFT ID":"NftId","Number":"u256")"NftId"
// ("collection_address":"ContractAddress","token_id":"u256")"TokenAmount"
// ("token_address":"ContractAddress","amount":"u256")
// "u256"("low":"u128","high":"u128")
pub const MY_STRUCT_TYPE_HASH: felt252
    = 0x19f63528d68c4f44b7d9003a5a6b7793f5bb6ffc8a22bdec82b413ddf4f9412;

具有预设类型的枚举:

#[type_hash(name: "My Enum", debug: true)]
pub enum MyEnum {
    #[snip12(name: "Token Amount")]
    TokenAmount: TokenAmount,
    #[snip12(name: "NFT ID")]
    NftId: NftId,
    #[snip12(name: "Number")]
    Number: u256,
}

// 编码类型: "My Enum"("Token Amount"("TokenAmount"),"NFT ID"("NftId"),"Number"("u256"))"NftId"
// ("collection_address":"ContractAddress","token_id":"u256")"TokenAmount"
// ("token_address":"ContractAddress","amount":"u256")
// "u256"("low":"u128","high":"u128")
pub const MY_ENUM_TYPE_HASH: felt252
    = 0x39dd19c7e5c5f89e084b78a26200b712c6ae3265f2bae774471c588858421b7;

用户自定义类型

目前不支持用户自定义类型,因为宏无法访问目标结构体/枚举之外的作用域。 未来可能会通过扩展语法来显式声明自定义类型定义来支持。