代码之家  ›  专栏  ›  技术社区  ›  Petr Mensik

为什么使用<T::Lookup作为StaticLookup>::Source而不是普通的T::AccountId?

  •  0
  • Petr Mensik  · 技术社区  · 3 年前

    根据这个 PR ,所有可调度呼叫都应使用 <T::Lookup as StaticLookup>::Source 而不是 T::AccountId 。为什么用查找来处理转账比用用户的帐户来处理转账更好?Substrate中的查找是如何工作的,是否有替代方法 StaticLookup ?

    最后,除了 IdentityLookup 你会如何使用它们?

    type Lookup = IdentityLookup<AccountId>;
    
    0 回复  |  直到 3 年前
        1
  •  8
  •   Shawn Tabrizi    3 年前

    StaticLookup是对地址的抽象,可以将多种不同的地址类型转换为底层AccountId。

    想象一个只使用AccountId的外部。与该函数交互的唯一方法是为链上的帐户提供原始AccountId。

    相反,使用StaticLookup,您可以提供任何兼容的地址格式,并且将使用额外的逻辑将该地址转换为基础帐户。

    想象一下:

    enum Address {
        AccountId([u8; 32]),  // 32 byte account id
        String(Vec<u8>),      // arbitrary string
    }
    

    这是一个实际的例子,说明你将如何允许人们在你的链上使用名称服务。例如,您可以执行以下操作:

    transfer(b"shawntabrizi", 100 UNIT)
    

    除了:

    transfer(5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY, 100 UNIT)
    

    StaticLookup将包含任何适当的代码,用于将已知格式转换为所需的最终AccountId。

    想象一下以下代码:

    struct NameServiceLookup;
    impl StaticLookup for NameServiceLookup {
        type Source = Address;
        type Target = AccountId;
    
        fn lookup(a: Address) -> Result<AccountId, LookupError> {
            match a {
                Address::AccountId(id) => Ok(id),
                Address::String(string) => {
                    string_to_account_id(string).ok_or(LookupError)
                },
            }
        }
    
        fn unlookup(a: [u8; 32]) -> Address {
            Address::AccountId(a)
        }
    }
    

    在这里,您可以看到我们有特殊的逻辑来处理地址,如果它是AccountId或String StaticLookup 将提供。

    实施 IdentityLookup 是一个简单的直通,它精确地返回输出的输入。所以,当你没有这样花哨的逻辑,想把所有东西都做出来时,这就是你想要使用的 静态查找 完全相同 AccountId 直接:

    pub struct IdentityLookup<T>(PhantomData<T>);
    impl<T: Codec + Clone + PartialEq + Debug> StaticLookup for IdentityLookup<T> {
        type Source = T;
        type Target = T;
        fn lookup(x: T) -> Result<T, LookupError> { Ok(x) }
        fn unlookup(x: T) -> T { x }
    }
    
    推荐文章