“羊了个羊”这个微信小游戏真实让人欲罢不能,沉迷其中。每天打开朋友圈、微信群,大家都在问第二关过了吗?甚至于小编有个当医生的朋友,忙碌亿整天之后,晚上也在争分夺秒的玩“羊了个羊”。
如果我们希望能够区分这些小猫,我们需要赋予它们独特的属性!在上一步中,我们使用了尚未实际定义的KittyRandomness
。
我们将使用frame_support
中的Randomness trait执行此操作。它将能够生成一个随机的种子,我们将用它来创建独特的小猫,并培育新的小猫。
Randomness
特征约束的新类型。来自frame_support
中Randomness
trait 需要使用参数来指定Output
和BlockNumber
泛型。
将 ACTION #5 行替换为:
type KittyRandomness: Randomness<Self::Hash, Self::BlockNumber>;
鉴于我们在pallet的配置中添加了一个新类型,我们需要配置runtime以设置其具体类型。如果我们想更改正在使用的算法,而无需修改pallet内的使用位置,KittyRandomness
可能会派上用场。为了展示这一点,我们将设置 KittyRandomness 类型为 FRAME 的 RandomnessCollectiveFlip 的一个实例。 方便的是,node template已经有一个 RandomnessCollectiveFlip pallet的实例。
在runtime的runtime/src/lib.rs
中设置 KittyRandomness
类型:
impl pallet_kitties::Config for Runtime {
type Event = Event;
type Currency = Balances;
type KittyRandomness = RandomnessCollectiveFlip; // <-- ACTION: add this line.
}
在这里,我们从其接口(Randomness<Self::Hash, Self::BlockNumber>
)中抽象出随机性生成实现(RandomnessCollectiveFlip
)。
生成DNA类似于使用随机性随机分配性别类型。不同之处在于,我们将使用在上一部分中导入的blake2_128
。如果我们在同一块中多次调用此函数,我们还将使用extrinsic_index从frame_system
pallet中生成不同的哈希。将 ACTION #6 行替换为:
impl pallet_kitties::Config for Runtime {
type Event = Event;
type Currency = Balances;
type KittyRandomness = RandomnessCollectiveFlip; // <-- ACTION: add this line.
}
为了轻松跟踪我们所有的小猫咪,我们将标准化我们的逻辑,以使用唯一的 ID 作为存储项的全局KEY。这意味着单个唯一键将指向我们的Kitty对象(即我们之前声明的结构)。
为了使其正常工作,我们需要确保新Kitty的ID始终是唯一的。我们可以使用新的存储项Kitties
来执行此操作,该存储项将从ID(哈希)映射到Kitty对象。
使用此对象,我们只需检查此存储项是否已包含使用特定 ID 的映射,即可轻松检查冲突。例如,从可调度函数内部,我们可以使用以下命令进行检查:
ensure!(!<Kitties<T>>::exists(new_id), "This new id already exists");
我们的runtime需要注意:
Kitties
的存储map持有)。KittiesOwned
的新存储映射)。要为结构Kitty
创建存储实例,我们将使用StorageMap
— FRAME 提供给我们的。
存储项的外观如下:
#[pallet::storage]
#[pallet::getter(fn kitties)]
pub(super) type Kitties<T: Config> = StorageMap<
_,
Twox64Concat,
T::Hash,
Kitty<T>,
>;
KittiesOwned
存储项与此类似,只是我们将使用BoundedVec
来跟踪我们将在runtime/src/lib.s
中配置的 Kitties 的最大数量。
#[pallet::storage]
#[pallet::getter(fn kitties_owned)]
/// Keeps track of what accounts own what Kitty.
pub(super) type KittiesOwned<T: Config> = StorageMap<
_,
Twox64Concat,
T::AccountId,
BoundedVec<T::Hash, T::MaxKittyOwned>,
ValueQuery,
>;
复制上面的两个代码片段以替换操作 #7 行。
在检查pallet编译之前,我们需要在配置特征中添加一个新类型MaxKittyOwned
,这是一个pallet常量类型(类似于前面KittyRandomness
的步骤)。将操作 #9 替换为:
#[pallet::constant]
type MaxKittyOwned: Get<u32>;
最后,我们在runtime/src/lib.rs
中定义类型MaxKittyOwned
。这与我们对 Currency 和 KittyRandomness 遵循的模式相同,只是我们将使用 parameter_types ! 宏添加一个固定的 u32!
parameter_types! { // <- add this macro
// One can own at most 9,999 Kitties
pub const MaxKittyOwned: u32 = 9999;
}
/// Configure the pallet-kitties in pallets/kitties.
impl pallet_kitties::Config for Runtime {
type Event = Event;
type Currency = Balances;
type KittyRandomness = RandomnessCollectiveFlip;
type MaxKittyOwned = MaxKittyOwned; // <- add this line
}
检查Kitties 区块链编译
cargo build --release
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。