diff --git "a/PPT/\347\254\254\351\233\266\350\257\276.pdf" "b/PPT/\347\254\254\351\233\266\350\257\276.pdf" deleted file mode 100644 index ede6466..0000000 Binary files "a/PPT/\347\254\254\351\233\266\350\257\276.pdf" and /dev/null differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.28.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.28.png" new file mode 100644 index 0000000..df3a433 Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.28.png" differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.32.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.32.png" new file mode 100644 index 0000000..e4768fe Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.32.png" differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.43.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.43.png" new file mode 100644 index 0000000..e8c8cfe Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.47.43.png" differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.03.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.03.png" new file mode 100644 index 0000000..8a0cbf9 Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.03.png" differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.14.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.14.png" new file mode 100644 index 0000000..ee44ba1 Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.14.png" differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.19.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.19.png" new file mode 100644 index 0000000..26778f7 Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.19.png" differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.32.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.32.png" new file mode 100644 index 0000000..e1d2087 Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.48.32.png" differ diff --git "a/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.49.10.png" "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.49.10.png" new file mode 100644 index 0000000..d9bf33c Binary files /dev/null and "b/projects/lesson-1/\345\261\217\345\271\225\345\277\253\347\205\247 2019-09-12 \344\270\213\345\215\2106.49.10.png" differ diff --git a/projects/lesson-3/runtime/src/kitties.rs b/projects/lesson-3/runtime/src/kitties.rs index 93e49eb..f14b66f 100644 --- a/projects/lesson-3/runtime/src/kitties.rs +++ b/projects/lesson-3/runtime/src/kitties.rs @@ -31,7 +31,42 @@ decl_module! { let dna = payload.using_encoded(blake2_128); let kitty = Kitty(dna); Kitties::insert(count, kitty); - KittiesCount::put(count + 1); +// KittiesCount::put(count + 1); + let new_kitties_count = Self::kitties_count().checked_add(1) + .ok_or("Kitties count overflow")?; + KittiesCount::put(new_kitties_count); + } + /// Breed kitties + pub fn breed(origin, kitty_id_one: u32, kitty_id_two: u32) { + let sender = ensure_signed(origin)?; + + let kitty1 = Self::kitty(kitty_id_one); + let kitty2 = Self::kitty(kitty_id_two); +// ensure!(kitty1.is_some(), "非法的id"); +// ensure!(kitty2.is_some(), "非法的id"); + ensure!(kitty_id_one != kitty_id_two, "需要一个父代和一个母代"); + let kitty_id = Self::kitties_count(); + let kitty1_dna = kitty1.0; + let kitty2_dna = kitty2.0; + // + let random = (>::random_seed(), &sender, + >::extrinsic_index()); + let hashed = random.using_encoded(blake2_128); + let mut new_dna = [0u8; 16]; + for i in 0..kitty1_dna.len() { + if i%3 == 0 { + new_dna[i] = kitty1_dna[i]; + } else if i%3 == 1{ + new_dna[i] = kitty2_dna[i]; + } else { + new_dna[i] = hashed[i]; + } + } + Kitties::insert(kitty_id, Kitty(new_dna)); +// KittiesCount::put(count + 1); + let new_kitties_count = Self::kitties_count().checked_add(1) + .ok_or("Kitties count overflow")?; + KittiesCount::put(new_kitties_count); } } } diff --git a/projects/lesson-4/runtime/src/kitties.rs b/projects/lesson-4/runtime/src/kitties.rs index 6f97fd1..aede459 100644 --- a/projects/lesson-4/runtime/src/kitties.rs +++ b/projects/lesson-4/runtime/src/kitties.rs @@ -34,24 +34,27 @@ decl_module! { // 作业:重构create方法,避免重复代码 - let kitty_id = Self::kitties_count(); - if kitty_id == T::KittyIndex::max_value() { - return Err("Kitties count overflow"); - } +// let kitty_id = Self::kitties_count(); +// if kitty_id == T::KittyIndex::max_value() { +// return Err("Kitties count overflow"); +// } + let kitty_id = Self::next_kitty_id()?; // Generate a random 128bit value - let payload = (>::random_seed(), &sender, >::extrinsic_index(), >::block_number()); - let dna = payload.using_encoded(blake2_128); +// let payload = (>::random_seed(), &sender, >::extrinsic_index(), >::block_number()); +// let dna = payload.using_encoded(blake2_128); + let dna = Self::random_value(&sender); // Create and store kitty let kitty = Kitty(dna); - >::insert(kitty_id, kitty); - >::put(kitty_id + 1.into()); - - // Store the ownership information - let user_kitties_id = Self::owned_kitties_count(&sender); - >::insert((sender.clone(), user_kitties_id), kitty_id); - >::insert(sender, user_kitties_id + 1.into()); +// >::insert(kitty_id, kitty); +// >::put(kitty_id + 1.into()); + +// // Store the ownership information +// let user_kitties_id = Self::owned_kitties_count(&sender); +// >::insert((sender.clone(), user_kitties_id), kitty_id); +// >::insert(sender, user_kitties_id + 1.into()); + Self::insert_kitty(sender, kitty_id, kitty); } /// Breed kitties @@ -60,6 +63,20 @@ decl_module! { Self::do_breed(sender, kitty_id_1, kitty_id_2)?; } + /// Transfer a kitty to other owner + pub fn transfer(origin, to_account: T::AccountId, kitty_id: T::KittyIndex) { + let sender = ensure_signed(origin)?; + + ensure!(>::exists(&(sender.clone(),kitty_id)), "Only owner can transfer kitty"); + + let to_account_kitties_id = Self::owned_kitties_count(to_account.clone()); + >::insert((to_account.clone(), to_account_kitties_id), kitty_id); + >::insert(to_account.clone(),to_account_kitties_id + 1.into()); + + let sender_kitties_id = Self::owned_kitties_count(sender.clone()); +// >::kill((sender.clone(), sender_kitties_id),kitty_id); + >::insert(sender.clone(),sender_kitties_id - 1.into()); + } } } @@ -69,7 +86,8 @@ fn combine_dna(dna1: u8, dna2: u8, selector: u8) -> u8 { // selector.map_bits(|bit, index| if (bit == 1) { dna1 & (1 << index) } else { dna2 & (1 << index) }) // 注意 map_bits这个方法不存在。只要能达到同样效果,不局限算法 // 测试数据:dna1 = 0b11110000, dna2 = 0b11001100, selector = 0b10101010, 返回值 0b11100100 - return dna1; +// return dna1; + return ((dna1 & selector) | (dna2 & !selector)); } impl Module { diff --git a/projects/lesson-5/runtime/src/kitties.rs b/projects/lesson-5/runtime/src/kitties.rs index 6a7eb3c..be6f4f9 100644 --- a/projects/lesson-5/runtime/src/kitties.rs +++ b/projects/lesson-5/runtime/src/kitties.rs @@ -1,4 +1,4 @@ -use support::{decl_module, decl_storage, ensure, StorageValue, StorageMap, dispatch::Result, Parameter}; +use support::{decl_module, decl_storage, ensure, StorageValue, StorageMap, dispatch::Result, Parameter,traits::Currency}; use sr_primitives::traits::{SimpleArithmetic, Bounded, Member}; use codec::{Encode, Decode}; use runtime_io::blake2_128; @@ -7,6 +7,7 @@ use rstd::result; pub trait Trait: system::Trait { type KittyIndex: Parameter + Member + SimpleArithmetic + Bounded + Default + Copy; + type Currency: Currency; } #[derive(Encode, Decode)] @@ -27,6 +28,8 @@ decl_storage! { pub KittiesCount get(kitties_count): T::KittyIndex; pub OwnedKitties get(owned_kitties): map (T::AccountId, Option) => Option>; + + pub KittyPrices get(kitty_price): map T::KittyIndex => Option; } } @@ -55,6 +58,23 @@ decl_module! { // 作业:实现 transfer(origin, to: T::AccountId, kitty_id: T::KittyIndex) // 使用 ensure! 来保证只有主人才有权限调用 transfer // 使用 OwnedKitties::append 和 OwnedKitties::remove 来修改小猫的主人 + ///Transfer a kitty to other owner + pub fn transfer(origin, to: T::AccountId, kitty_id: T::KittyIndex) { + let sender = ensure_signed(origin)?; + + ensure!(>::exists(&(sender.clone(), Some(kitty_id))), "Only kitty can be transfered by owner"); + + >::remove(&sender, kitty_id); + >::append(&to, kitty_id); + } + // + pub fn sell(origin, kitty_id: T::KittyIndex, price: u64) { + let sender = ensure_signed(origin)?; + + ensure!(>::exists(&(sender.clone(), Some(kitty_id))), "Only kitty can be set price by owner"); + + >::insert(kitty_id, price); + } } } @@ -142,6 +162,7 @@ impl Module { fn insert_owned_kitty(owner: &T::AccountId, kitty_id: T::KittyIndex) { // 作业:调用 OwnedKitties::append 完成实现 + >::append(owner, kitty_id); } fn insert_kitty(owner: &T::AccountId, kitty_id: T::KittyIndex, kitty: Kitty) { diff --git a/projects/lesson-5/runtime/src/lib.rs b/projects/lesson-5/runtime/src/lib.rs index 706abae..77460ff 100644 --- a/projects/lesson-5/runtime/src/lib.rs +++ b/projects/lesson-5/runtime/src/lib.rs @@ -261,6 +261,7 @@ impl template::Trait for Runtime { impl kitties::Trait for Runtime { type KittyIndex = u32; + type Currency: Currency; } construct_runtime!( diff --git a/projects/lesson-6/runtime/src/kitties.rs b/projects/lesson-6/runtime/src/kitties.rs index f7b42eb..30afa7e 100644 --- a/projects/lesson-6/runtime/src/kitties.rs +++ b/projects/lesson-6/runtime/src/kitties.rs @@ -213,6 +213,7 @@ mod tests { use sr_primitives::{traits::{BlakeTwo256, IdentityLookup}, testing::Header}; use sr_primitives::weights::Weight; use sr_primitives::Perbill; + use crate::{ExistentialDeposit,TransferFee,CreationFee,TransactionBaseFee,TransactionByteFee}; impl_outer_origin! { pub enum Origin for Test {} @@ -247,8 +248,26 @@ mod tests { type AvailableBlockRatio = AvailableBlockRatio; type Version = (); } + impl balances::Trait for Test { + type Balance = u128; + type OnFreeBalanceZero = (); + type OnNewAccount = (); + type Event = (); + + type TransactionPayment = (); + type DustRemoval = (); + type TransferPayment = (); + type ExistentialDeposit = ExistentialDeposit; + type TransferFee = TransferFee; + type CreationFee = CreationFee; + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = (); + } impl Trait for Test { type KittyIndex = u32; + type Currency = balances::Module; + type Event = (); } type OwnedKittiesTest = OwnedKitties; @@ -261,53 +280,56 @@ mod tests { #[test] fn owned_kitties_can_append_values() { with_externalities(&mut new_test_ext(), || { - OwnedKittiesTest::append(&0, 1); +// OwnedKittiesTest::append(&0, 1); + OwnedKittiesList::::append(&0, 1); - assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem:: { prev: Some(1), next: Some(1), })); - assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem:: { prev: None, next: None, })); - OwnedKittiesTest::append(&0, 2); +// OwnedKittiesTest::append(&0, 2); + OwnedKittiesList::::append(&0, 2); - assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem:: { prev: Some(2), next: Some(1), })); - assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem:: { prev: None, next: Some(2), })); - assert_eq!(OwnedKittiesTest::get(&(0, Some(2))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(2))), Some(KittyLinkedItem:: { prev: Some(1), next: None, })); - OwnedKittiesTest::append(&0, 3); +// OwnedKittiesTest::append(&0, 3); + OwnedKittiesList::::append(&0, 3); - assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem:: { prev: Some(3), next: Some(1), })); - assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem:: { prev: None, next: Some(2), })); - assert_eq!(OwnedKittiesTest::get(&(0, Some(2))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(2))), Some(KittyLinkedItem:: { prev: Some(1), next: Some(3), })); - assert_eq!(OwnedKittiesTest::get(&(0, Some(3))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(3))), Some(KittyLinkedItem:: { prev: Some(2), next: None, })); @@ -317,32 +339,38 @@ mod tests { #[test] fn owned_kitties_can_remove_values() { with_externalities(&mut new_test_ext(), || { - OwnedKittiesTest::append(&0, 1); - OwnedKittiesTest::append(&0, 2); - OwnedKittiesTest::append(&0, 3); +// OwnedKittiesTest::append(&0, 1); +// OwnedKittiesTest::append(&0, 2); +// OwnedKittiesTest::append(&0, 3); + +// OwnedKittiesTest::remove(&0, 2); + OwnedKittiesList::::append(&0, 1); + OwnedKittiesList::::append(&0, 2); + OwnedKittiesList::::append(&0, 3); - OwnedKittiesTest::remove(&0, 2); + OwnedKittiesList::::remove(&0, 2); - assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem:: { prev: Some(3), next: Some(1), })); - assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(1))), Some(KittyLinkedItem:: { prev: None, next: Some(3), })); assert_eq!(OwnedKittiesTest::get(&(0, Some(2))), None); - assert_eq!(OwnedKittiesTest::get(&(0, Some(3))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(3))), Some(KittyLinkedItem:: { prev: Some(1), next: None, })); - OwnedKittiesTest::remove(&0, 1); +// OwnedKittiesTest::remove(&0, 1); + OwnedKittiesList::::remove(&0, 1); - assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem:: { prev: Some(3), next: Some(3), })); @@ -351,14 +379,15 @@ mod tests { assert_eq!(OwnedKittiesTest::get(&(0, Some(2))), None); - assert_eq!(OwnedKittiesTest::get(&(0, Some(3))), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, Some(3))), Some(KittyLinkedItem:: { prev: None, next: None, })); - OwnedKittiesTest::remove(&0, 3); +// OwnedKittiesTest::remove(&0, 3); + OwnedKittiesList::::remove(&0, 3); - assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem { + assert_eq!(OwnedKittiesTest::get(&(0, None)), Some(KittyLinkedItem:: { prev: None, next: None, })); diff --git a/projects/lesson-6/runtime/src/linked_item.rs b/projects/lesson-6/runtime/src/linked_item.rs index 2a51676..e970a87 100644 --- a/projects/lesson-6/runtime/src/linked_item.rs +++ b/projects/lesson-6/runtime/src/linked_item.rs @@ -37,9 +37,45 @@ impl LinkedList where pub fn append(key: &Key, value: Value) { // 作业:实现 append + let head = Self::read_head(key); + let new_head = LinkedItem { + prev: Some(value), + next: head.next, + }; + + Self::write_head(key, new_head); + let prev = Self::read(key, head.prev); + let new_prev = LinkedItem { + prev: prev.prev, + next: Some(value), + }; + Self::write(key, head.prev, new_prev); + + let item = LinkedItem { + prev: head.prev, + next: None, + }; + Self::write(key, Some(value), item); } pub fn remove(key: &Key, value: Value) { // 作业:实现 remove + if let Some(item) = Storage::take(&(key.clone(), Some(value))) { + let prev = Self::read(key, item.prev); + let new_prev = LinkedItem { + prev: prev.prev, + next: item.next, + }; + + Self::write(key, item.prev, new_prev); + + let next = Self::read(key, item.next); + let new_next = LinkedItem { + prev: item.prev, + next: next.next, + }; + + Self::write(key, item.next, new_next); + } } -} \ No newline at end of file +} diff --git a/projects/lesson-7/runtime/src/kitties.rs b/projects/lesson-7/runtime/src/kitties.rs index 05681a3..d4a9eeb 100644 --- a/projects/lesson-7/runtime/src/kitties.rs +++ b/projects/lesson-7/runtime/src/kitties.rs @@ -17,8 +17,33 @@ pub trait Trait: system::Trait { type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; -#[derive(Encode, Decode)] +// #[derive(Encode, Decode)] pub struct Kitty(pub [u8; 16]); +impl codec::Encode for Kitty { + fn encode_to(&self, dest: &mut EncOut) { + codec::Encode::encode_to(&&self.0, dest) + } + fn encode(&self) -> codec::alloc::vec::Vec { + codec::Encode::encode(&&self.0) + } + fn using_encoded R>(&self, f: F) -> R { + codec::Encode::using_encoded(&&self.0, f) + } +} +impl codec::Decode for Kitty { + fn decode(input:&mut DecIn) + -> core::result::Result { + Ok(Kitty({ + let res = + codec::Decode::decode(input); + match res { + Err(_) => + return Err("Error decoding field Kitty.0".into()), + Ok(a) => a, + } + })) + } +} type KittyLinkedItem = LinkedItem<::KittyIndex>; type OwnedKittiesList = LinkedList, ::AccountId, ::KittyIndex>; diff --git a/projects/lesson-7/runtime/src/linked_item.rs b/projects/lesson-7/runtime/src/linked_item.rs index eeeea0a..e9eee8e 100644 --- a/projects/lesson-7/runtime/src/linked_item.rs +++ b/projects/lesson-7/runtime/src/linked_item.rs @@ -10,7 +10,17 @@ pub struct LinkedItem { } pub struct LinkedList(rstd::marker::PhantomData<(Storage, Key, Value)>); - +impl codec::Encode for LinkedList { + fn encode_to(&self, dest: &mut EncOut) { + codec::Encode::encode_to(&&self.0, dest) + } + fn encode(&self) -> codec::alloc::vec::Vec { + codec::Encode::encode(&&self.0) + } + fn using_encoded R>(&self, f: F) -> R { + codec::Encode::using_encoded(&&self.0, f) + } +} impl LinkedList where Value: Parameter + Member + Copy, Key: Parameter, @@ -77,4 +87,4 @@ impl LinkedList where Self::write(key, item.next, new_next); } } -} \ No newline at end of file +}