rust - Substrate 的 `<T>` 中的 `fn deposit_event<T>() = default` 有什么作用?

标签 rust blockchain substrate

引用Substrate Collectables Workshop , <T> 是什么意思在fn deposit_event<T>() = default;中实际做和引用?当我的 Event 时,我可以省略它吗?不包括例如 AccountId

最佳答案

在 Substrate 的背景下,这里有几件事需要回答。

泛型

每个 Substrate 模块都能够定义模块所需的自定义类型,所有这些都是实现某些特征所必需的。与强定义这些类型不同,使用 traits 可以让我们确保类型具有某些属性,但不限于类型可以是什么。这些 generic 类型定义位于 trait Trait 中, 必须在每个模块中定义。

这是在 system 中定义的自定义类型的示例模块,几乎在所有其他模块中使用:

pub trait Trait: 'static + Eq + Clone {
    /// The aggregated `Origin` type used by dispatchable calls.
    type Origin: ...

    /// Account index (aka nonce) type. This stores the number of previous transactions associated with a sender
    /// account.
    type Index: ...

    /// The block number type used by the runtime.
    type BlockNumber: ...

    /// The output of the `Hashing` function.
    type Hash: ...

    /// The hashing system (algorithm) being used in the runtime (e.g. Blake2).
    type Hashing: Hash<Output = Self::Hash>;

    /// Collection of (light-client-relevant) logs for a block to be included verbatim in the block header.
    type Digest: ...

    /// The user account identifier type for the runtime.
    type AccountId: ...

    /// Converting trait to take a source type and convert to `AccountId`.
    ///
    /// Used to define the type and conversion mechanism for referencing accounts in transactions. It's perfectly
    /// reasonable for this to be an identity conversion (with the source type being `AccountId`), but other modules
    /// (e.g. Indices module) may provide more functional/efficient alternatives.
    type Lookup: StaticLookup<Target = Self::AccountId>;

    /// The block header.
    type Header: ...

    /// The aggregated event type of the runtime.
    type Event: Parameter + Member + From<Event>;

    /// A piece of information that can be part of the digest (as a digest item).
    type Log: From<Log<Self>> + Into<DigestItemOf<Self>>;
}

在您的自定义模块中,您将定义如下内容:

/// The module's configuration trait.
pub trait Trait: system::Trait {
    /// The overarching event type.
    type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}

注意这里我们定义了自己的Event类型,我们的模块现在可以使用,而且我们继承 system 的特征模块 ( system::Trait ),所以我们也可以使用所有这些类型!

使用泛型

现在我们已经在运行时模块中定义了一些自定义类型,我们可以开始在整个模块逻辑中使用它们。

在这段代码中你总是会看到像第二行这样的一行:

decl_storage! {
    trait Store for Module<T: Trait> as Sudo {
        /// The `AccountId` of the sudo key.
        Key get(key) config(): T::AccountId;
    }
}

这一行有些是宏魔法,但重要的是你看到我们定义了 Module<T: Trait> .这意味着我们已经分配了模块的 trait Trait作为 Module 的通用参数在 T 的别名下.

因此,我们可以使用 T像我们上面那样引用这些特殊类型:

T::AccountId

绕一圈,我们可以访问这个类型,因为我们从 system::Trait 继承了它定义!

存款事件宏生成

为了最终回答您的问题,decl_module!函数生成 deposit_event 的函数体避免您一遍又一遍地编写相同的代码。

我们检测预定义的函数名称 deposit_event , 并检查 = default; ,然后将其替换为可用的 deposit_event功能。

但是,当生成这个函数时,宏不知道它是否应该使用输入事件是泛型的函数,或者输入事件不使用泛型。因此,您需要通过说 deposit_event<T>() 来“给它一个提示”或者只是 deposit_event() .

然后它将生成适用于模块中类型的函数的正确版本。如果您的模块事件使用任何通用类型,例如 T::AccountIdT::Balance ,您还需要定义 deposit_event 的通用版本.

关于rust - Substrate 的 `<T>` 中的 `fn deposit_event<T>() = default` 有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56062757/

相关文章:

rust - 如何使用滑动窗口对生成迭代器?

rust - 如何通过泛型获取数组结构 (SOA) 中的值?

rust - 为什么 query_map 的结果不打印任何东西?

go - 如何在 hyperledger fabric v0.6 链代码实现中查询一段时间的状态

blockchain - 以去中心化方式从 Chainlink 获取代币历史价格数据的最佳方式是什么?

rust - 当两个条件变量之一通知时,是否可以等待并返回?

blockchain - Hyperledger-Fabric-Java-SDK 入门

rust - 为自定义托盘 Substrate 添加自定义 RPC 时出错

rust - 卡在编译中(substrate-node-template :make build )

javascript - 添加自定义 @polkadot/types 时 Polkadot-js Babel 错误