diff --git a/pallets/governance/src/lib.rs b/pallets/governance/src/lib.rs index 77d9130ad..84fcbd426 100644 --- a/pallets/governance/src/lib.rs +++ b/pallets/governance/src/lib.rs @@ -166,6 +166,9 @@ pub mod pallet { #[pallet::storage] pub type Curator = StorageValue<_, T::AccountId, ValueQuery, DefaultKey>; + /// Determines whether smart contract can be deployed by everyone or only by the curator + #[pallet::storage] + pub type RestrictContractDeploy = StorageValue<_, bool, ValueQuery>; // --------------------------------- // Extrinsics // --------------------------------- diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index ec021e081..ef615c021 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -118,6 +118,10 @@ pub use pallet_subspace; mod precompiles; use precompiles::FrontierPrecompiles; +use frame_system::RawOrigin; +use pallet_evm::EnsureAddressOrigin; +use sp_runtime::AccountId32; + /// An index to a block. pub type BlockNumber = u64; @@ -184,7 +188,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 424, + spec_version: 429, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -524,8 +528,8 @@ impl pallet_evm::Config for Runtime { type BalanceConverter = EvmBalanceConverter; type WeightPerGas = WeightPerGas; type BlockHashMapping = pallet_ethereum::EthereumBlockHashMapping; - type CallOrigin = pallet_evm::EnsureAddressTruncated; - type WithdrawOrigin = pallet_evm::EnsureAddressTruncated; + type CallOrigin = EnsureCuratorAddressTruncated; + type WithdrawOrigin = EnsureCuratorAddressTruncated; type AddressMapping = HashedAddressMapping; type Currency = Balances; type RuntimeEvent = RuntimeEvent; @@ -656,6 +660,36 @@ impl BalanceConverter for EvmBalanceConverter { } } +pub struct EnsureCuratorAddressTruncated; + +impl EnsureAddressOrigin for EnsureCuratorAddressTruncated { + type Success = AccountId32; + + fn try_address_origin( + address: &H160, + origin: RuntimeOrigin, + ) -> Result { + , RuntimeOrigin>>>::into(origin) + .and_then(|o| match o { + RawOrigin::Signed(who) => { + let address_matches = AsRef::<[u8; 32]>::as_ref(&who)[0..20] == address[0..20]; + + if !address_matches { + return Err(RuntimeOrigin::from(RawOrigin::Signed(who))); + } + + if pallet_governance::RestrictContractDeploy::::get() + && Some(who.clone()) != Some(pallet_governance::Curator::::get()) { + return Err(RuntimeOrigin::from(RawOrigin::Signed(who))); + } + + Ok(who) + } + r => Err(RuntimeOrigin::from(r)), + }) + } +} + // The address format for describing accounts. pub type Address = sp_runtime::MultiAddress; // Block header type as expected by this runtime.