From fde4f4fb030fd7a412af364964b3c6019988cf4c Mon Sep 17 00:00:00 2001 From: str-mv Date: Fri, 26 Jun 2020 10:09:50 +0000 Subject: [PATCH] Safe transfer added --- --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -59,18 +59,20 @@ /// Next available collection ID pub NextCollectionID get(fn next_collection_id): u64; - /// Collection map pub Collection get(collection): map hasher(identity) u64 => CollectionType; + //pub Collection get(collection): map hasher(identity) u64 => CollectionType; - /// Admins map (collection) pub AdminList get(admin_list_collection): map hasher(identity) u64 => Vec; /// Balance owner per collection map pub Balance get(balance_count): map hasher(blake2_128_concat) (u64, T::AccountId) => u64; + pub ApprovedList get(approved): map hasher(blake2_128_concat) (u64, u64) => Vec; - pub ApprovedList get(approved): map hasher(blake2_128_concat) (u64, u64) => Vec; pub ItemList get(item_id): map hasher(blake2_128_concat) (u64, u64) => NftItemType; + // pub ItemList get(item_id): map hasher(blake2_128_concat) (u64, u64) => NftItemType; + pub ItemListIndex get(item_index): map hasher(blake2_128_concat) u64 => u64; + // pub ItemListIndex get(item_index): map hasher(blake2_128_concat) u64 => u64; } } @@ -114,7 +116,7 @@ // Generate next collection ID let next_id = NextCollectionID::get() .checked_add(1) - .expect("collection id error"); + .expect("collection id error") - 1; NextCollectionID::put(next_id); @@ -384,5 +386,18 @@ Ok(()) } + + #[weight = frame_support::weights::SimpleDispatchInfo::default()] + pub fn safe_transfer_from(origin, collection_id: u64, item_id: u64, new_owner: T::AccountId) -> DispatchResult { + + let no_perm_mes = "You do not have permissions to modify this collection"; + ensure!(>::contains_key((collection_id, item_id)), no_perm_mes); + let list_itm = >::get((collection_id, item_id)); + ensure!(list_itm.contains(&new_owner.clone()), no_perm_mes); + + Self::transfer(origin, collection_id, item_id, new_owner)?; + + Ok(()) + } } } --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -2,40 +2,39 @@ #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. -#![recursion_limit="256"] +#![recursion_limit = "256"] // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use sp_std::prelude::*; +use grandpa::fg_primitives; +use grandpa::AuthorityList as GrandpaAuthorityList; +use sp_api::impl_runtime_apis; +use sp_consensus_aura::sr25519::AuthorityId as AuraId; use sp_core::OpaqueMetadata; -use sp_runtime::{ - ApplyExtrinsicResult, generic, create_runtime_str, impl_opaque_keys, MultiSignature, - transaction_validity::{TransactionValidity, TransactionSource}, -}; use sp_runtime::traits::{ - BlakeTwo256, Block as BlockT, IdentityLookup, Verify, ConvertInto, IdentifyAccount + BlakeTwo256, Block as BlockT, ConvertInto, IdentifyAccount, IdentityLookup, Verify, }; -use sp_api::impl_runtime_apis; -use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use grandpa::AuthorityList as GrandpaAuthorityList; -use grandpa::fg_primitives; -use sp_version::RuntimeVersion; +use sp_runtime::{ + create_runtime_str, generic, impl_opaque_keys, + transaction_validity::{TransactionSource, TransactionValidity}, + ApplyExtrinsicResult, MultiSignature, +}; +use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; +use sp_version::RuntimeVersion; // A few exports that help ease life for downstream crates. -#[cfg(any(feature = "std", test))] -pub use sp_runtime::BuildStorage; -pub use timestamp::Call as TimestampCall; pub use balances::Call as BalancesCall; -pub use sp_runtime::{Permill, Perbill}; pub use frame_support::{ - StorageValue, construct_runtime, parameter_types, - traits::Randomness, - weights::Weight, + construct_runtime, parameter_types, traits::Randomness, weights::Weight, StorageValue, }; +#[cfg(any(feature = "std", test))] +pub use sp_runtime::BuildStorage; +pub use sp_runtime::{Perbill, Permill}; +pub use timestamp::Call as TimestampCall; /// Importing a template pallet pub use nft; @@ -71,33 +70,33 @@ /// of data like extrinsics, allowing for them to continue syncing the network through upgrades /// to even the core data structures. pub mod opaque { - use super::*; + use super::*; - pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; + pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic; - /// Opaque block header type. - pub type Header = generic::Header; - /// Opaque block type. - pub type Block = generic::Block; - /// Opaque block identifier type. - pub type BlockId = generic::BlockId; + /// Opaque block header type. + pub type Header = generic::Header; + /// Opaque block type. + pub type Block = generic::Block; + /// Opaque block identifier type. + pub type BlockId = generic::BlockId; - impl_opaque_keys! { - pub struct SessionKeys { - pub aura: Aura, - pub grandpa: Grandpa, - } - } + impl_opaque_keys! { + pub struct SessionKeys { + pub aura: Aura, + pub grandpa: Grandpa, + } + } } /// This runtime version. pub const VERSION: RuntimeVersion = RuntimeVersion { - spec_name: create_runtime_str!("nft"), - impl_name: create_runtime_str!("nft"), - authoring_version: 1, - spec_version: 1, - impl_version: 1, - apis: RUNTIME_API_VERSIONS, + spec_name: create_runtime_str!("nft"), + impl_name: create_runtime_str!("nft"), + authoring_version: 1, + spec_version: 1, + impl_version: 1, + apis: RUNTIME_API_VERSIONS, }; pub const MILLISECS_PER_BLOCK: u64 = 6000; @@ -112,137 +111,137 @@ /// The version information used to identify this runtime when compiled natively. #[cfg(feature = "std")] pub fn native_version() -> NativeVersion { - NativeVersion { - runtime_version: VERSION, - can_author_with: Default::default(), - } + NativeVersion { + runtime_version: VERSION, + can_author_with: Default::default(), + } } parameter_types! { - pub const BlockHashCount: BlockNumber = 250; - pub const MaximumBlockWeight: Weight = 1_000_000_000; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); - pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; - pub const Version: RuntimeVersion = VERSION; + pub const BlockHashCount: BlockNumber = 250; + pub const MaximumBlockWeight: Weight = 1_000_000_000; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); + pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; + pub const Version: RuntimeVersion = VERSION; } impl system::Trait for Runtime { - /// The identifier used to distinguish between accounts. - type AccountId = AccountId; - /// The aggregated dispatch type that is available for extrinsics. - type Call = Call; - /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = IdentityLookup; - /// The index type for storing how many extrinsics an account has signed. - type Index = Index; - /// The index type for blocks. - type BlockNumber = BlockNumber; - /// The type for hashing blocks and tries. - type Hash = Hash; - /// The hashing algorithm used. - type Hashing = BlakeTwo256; - /// The header type. - type Header = generic::Header; - /// The ubiquitous event type. - type Event = Event; - /// The ubiquitous origin type. - type Origin = Origin; - /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = BlockHashCount; - /// Maximum weight of each block. - type MaximumBlockWeight = MaximumBlockWeight; - /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. - type MaximumBlockLength = MaximumBlockLength; - /// Portion of the block weight that is available to all normal transactions. - type AvailableBlockRatio = AvailableBlockRatio; - /// Version of the runtime. - type Version = Version; - /// Converts a module to the index of the module in `construct_runtime!`. - /// - /// This type is being generated by `construct_runtime!`. - type ModuleToIndex = ModuleToIndex; - /// What to do if a new account is created. - type OnNewAccount = (); - /// What to do if an account is fully reaped from the system. - type OnKilledAccount = (); - /// The data to be stored in an account. - type AccountData = balances::AccountData; + /// The identifier used to distinguish between accounts. + type AccountId = AccountId; + /// The aggregated dispatch type that is available for extrinsics. + type Call = Call; + /// The lookup mechanism to get account ID from whatever is passed in dispatchers. + type Lookup = IdentityLookup; + /// The index type for storing how many extrinsics an account has signed. + type Index = Index; + /// The index type for blocks. + type BlockNumber = BlockNumber; + /// The type for hashing blocks and tries. + type Hash = Hash; + /// The hashing algorithm used. + type Hashing = BlakeTwo256; + /// The header type. + type Header = generic::Header; + /// The ubiquitous event type. + type Event = Event; + /// The ubiquitous origin type. + type Origin = Origin; + /// Maximum number of block number to block hash mappings to keep (oldest pruned first). + type BlockHashCount = BlockHashCount; + /// Maximum weight of each block. + type MaximumBlockWeight = MaximumBlockWeight; + /// Maximum size of all encoded transactions (in bytes) that are allowed in one block. + type MaximumBlockLength = MaximumBlockLength; + /// Portion of the block weight that is available to all normal transactions. + type AvailableBlockRatio = AvailableBlockRatio; + /// Version of the runtime. + type Version = Version; + /// Converts a module to the index of the module in `construct_runtime!`. + /// + /// This type is being generated by `construct_runtime!`. + type ModuleToIndex = ModuleToIndex; + /// What to do if a new account is created. + type OnNewAccount = (); + /// What to do if an account is fully reaped from the system. + type OnKilledAccount = (); + /// The data to be stored in an account. + type AccountData = balances::AccountData; } impl aura::Trait for Runtime { - type AuthorityId = AuraId; + type AuthorityId = AuraId; } impl grandpa::Trait for Runtime { - type Event = Event; + type Event = Event; } parameter_types! { - pub const MinimumPeriod: u64 = SLOT_DURATION / 2; + pub const MinimumPeriod: u64 = SLOT_DURATION / 2; } impl timestamp::Trait for Runtime { - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = Aura; - type MinimumPeriod = MinimumPeriod; + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = Aura; + type MinimumPeriod = MinimumPeriod; } parameter_types! { - pub const ExistentialDeposit: u128 = 500; + pub const ExistentialDeposit: u128 = 500; } impl balances::Trait for Runtime { - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; } parameter_types! { - pub const TransactionBaseFee: Balance = 0; - pub const TransactionByteFee: Balance = 1; + pub const TransactionBaseFee: Balance = 0; + pub const TransactionByteFee: Balance = 1; } impl transaction_payment::Trait for Runtime { - type Currency = balances::Module; - type OnTransactionPayment = (); - type TransactionBaseFee = TransactionBaseFee; - type TransactionByteFee = TransactionByteFee; - type WeightToFee = ConvertInto; - type FeeMultiplierUpdate = (); + type Currency = balances::Module; + type OnTransactionPayment = (); + type TransactionBaseFee = TransactionBaseFee; + type TransactionByteFee = TransactionByteFee; + type WeightToFee = ConvertInto; + type FeeMultiplierUpdate = (); } impl sudo::Trait for Runtime { - type Event = Event; - type Call = Call; + type Event = Event; + type Call = Call; } /// Used for the module template in `./template.rs` impl nft::Trait for Runtime { - type Event = Event; + type Event = Event; } construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = opaque::Block, - UncheckedExtrinsic = UncheckedExtrinsic - { - System: system::{Module, Call, Config, Storage, Event}, - RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, - Timestamp: timestamp::{Module, Call, Storage, Inherent}, - Aura: aura::{Module, Config, Inherent(Timestamp)}, - Grandpa: grandpa::{Module, Call, Storage, Config, Event}, - Balances: balances::{Module, Call, Storage, Config, Event}, - TransactionPayment: transaction_payment::{Module, Storage}, - Sudo: sudo::{Module, Call, Config, Storage, Event}, - // Used for the module template in `./template.rs` - Nft: nft::{Module, Call, Storage, Event}, - } + pub enum Runtime where + Block = Block, + NodeBlock = opaque::Block, + UncheckedExtrinsic = UncheckedExtrinsic + { + System: system::{Module, Call, Config, Storage, Event}, + RandomnessCollectiveFlip: randomness_collective_flip::{Module, Call, Storage}, + Timestamp: timestamp::{Module, Call, Storage, Inherent}, + Aura: aura::{Module, Config, Inherent(Timestamp)}, + Grandpa: grandpa::{Module, Call, Storage, Config, Event}, + Balances: balances::{Module, Call, Storage, Config, Event}, + TransactionPayment: transaction_payment::{Module, Storage}, + Sudo: sudo::{Module, Call, Config, Storage, Event}, + // Used for the module template in `./template.rs` + Nft: nft::{Module, Call, Storage, Event}, + } ); /// The address format for describing accounts. @@ -257,106 +256,107 @@ pub type BlockId = generic::BlockId; /// The SignedExtension to the basic transaction logic. pub type SignedExtra = ( - system::CheckVersion, - system::CheckGenesis, - system::CheckEra, - system::CheckNonce, - system::CheckWeight, - transaction_payment::ChargeTransactionPayment + system::CheckVersion, + system::CheckGenesis, + system::CheckEra, + system::CheckNonce, + system::CheckWeight, + transaction_payment::ChargeTransactionPayment, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; /// Extrinsic type that has already been checked. pub type CheckedExtrinsic = generic::CheckedExtrinsic; /// Executive: handles dispatch to the various modules. -pub type Executive = frame_executive::Executive, Runtime, AllModules>; +pub type Executive = + frame_executive::Executive, Runtime, AllModules>; impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } + impl sp_api::Core for Runtime { + fn version() -> RuntimeVersion { + VERSION + } - fn execute_block(block: Block) { - Executive::execute_block(block) - } + fn execute_block(block: Block) { + Executive::execute_block(block) + } - fn initialize_block(header: &::Header) { - Executive::initialize_block(header) - } - } + fn initialize_block(header: &::Header) { + Executive::initialize_block(header) + } + } - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - Runtime::metadata().into() - } - } + impl sp_api::Metadata for Runtime { + fn metadata() -> OpaqueMetadata { + Runtime::metadata().into() + } + } - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } + impl sp_block_builder::BlockBuilder for Runtime { + fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { + Executive::apply_extrinsic(extrinsic) + } - fn finalize_block() -> ::Header { - Executive::finalize_block() - } + fn finalize_block() -> ::Header { + Executive::finalize_block() + } - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } + fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { + data.create_extrinsics() + } - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } + fn check_inherents( + block: Block, + data: sp_inherents::InherentData, + ) -> sp_inherents::CheckInherentsResult { + data.check_extrinsics(&block) + } - fn random_seed() -> ::Hash { - RandomnessCollectiveFlip::random_seed() - } - } + fn random_seed() -> ::Hash { + RandomnessCollectiveFlip::random_seed() + } + } - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx) - } - } + impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { + fn validate_transaction( + source: TransactionSource, + tx: ::Extrinsic, + ) -> TransactionValidity { + Executive::validate_transaction(source, tx) + } + } - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } + impl sp_offchain::OffchainWorkerApi for Runtime { + fn offchain_worker(header: &::Header) { + Executive::offchain_worker(header) + } + } - impl sp_consensus_aura::AuraApi for Runtime { - fn slot_duration() -> u64 { - Aura::slot_duration() - } + impl sp_consensus_aura::AuraApi for Runtime { + fn slot_duration() -> u64 { + Aura::slot_duration() + } - fn authorities() -> Vec { - Aura::authorities() - } - } + fn authorities() -> Vec { + Aura::authorities() + } + } - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - opaque::SessionKeys::generate(seed) - } + impl sp_session::SessionKeys for Runtime { + fn generate_session_keys(seed: Option>) -> Vec { + opaque::SessionKeys::generate(seed) + } - fn decode_session_keys( - encoded: Vec, - ) -> Option, sp_core::crypto::KeyTypeId)>> { - opaque::SessionKeys::decode_into_raw_public_keys(&encoded) - } - } + fn decode_session_keys( + encoded: Vec, + ) -> Option, sp_core::crypto::KeyTypeId)>> { + opaque::SessionKeys::decode_into_raw_public_keys(&encoded) + } + } - impl fg_primitives::GrandpaApi for Runtime { - fn grandpa_authorities() -> GrandpaAuthorityList { - Grandpa::grandpa_authorities() - } - } + impl fg_primitives::GrandpaApi for Runtime { + fn grandpa_authorities() -> GrandpaAuthorityList { + Grandpa::grandpa_authorities() + } + } } -- gitstuff