-
Notifications
You must be signed in to change notification settings - Fork 36
The account abstraction pallet #130
base: polkadot-v0.9.39
Are you sure you want to change the base?
Changes from 6 commits
9856d9e
8e049e6
a909f8e
3619ac4
2cec263
d810947
6e71c60
c1a740e
6f5aa27
ee7e727
0973c5a
98700fa
f8149af
b0c4bb0
11ec601
eb56aa2
b494247
0307dcd
34b2d24
c829786
564a2e9
83fa23b
ca3bddc
3a1ae8b
7aca6a1
81f533d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| [package] | ||
| name = "pallet-account" | ||
| authors = ["Stake Technologies"] | ||
| edition = "2021" | ||
| version = "0.1.0" | ||
|
|
||
| [dependencies] | ||
| log = { workspace = true } | ||
| serde = { workspace = true, optional = true } | ||
|
|
||
| # Substrate | ||
| parity-scale-codec = { workspace = true } | ||
| frame-support = { workspace = true } | ||
| frame-system = { workspace = true } | ||
| scale-info = { workspace = true } | ||
| sp-core = { workspace = true } | ||
| sp-runtime = { workspace = true } | ||
| sp-std = { workspace = true } | ||
|
|
||
| # Benchmarks | ||
| frame-benchmarking = { workspace = true, optional = true } | ||
|
|
||
| [dev-dependencies] | ||
| pallet-balances = { workspace = true, features = ["std"] } | ||
| assert_matches = { workspace = true } | ||
| hex-literal = { workspace = true } | ||
|
|
||
| [features] | ||
| default = ["std"] | ||
| std = [ | ||
| "parity-scale-codec/std", | ||
| "frame-support/std", | ||
| "frame-system/std", | ||
| "scale-info/std", | ||
| "serde", | ||
| "sp-core/std", | ||
| "sp-runtime/std", | ||
| "sp-std/std", | ||
| ] | ||
|
|
||
| runtime-benchmarks = [ | ||
| "frame-benchmarking", | ||
| ] | ||
| try-runtime = ["frame-support/try-runtime"] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| // This file is part of Astar. | ||
|
|
||
| // Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
|
|
||
| // Astar is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
|
|
||
| // Astar is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU General Public License for more details. | ||
|
|
||
| // You should have received a copy of the GNU General Public License | ||
| // along with Astar. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| //! # Account abstraction pallet | ||
| //! | ||
| //! ## Overview | ||
| //! | ||
| //! An accout abstraction pallet make possible to derive new blockchain based | ||
|
akru marked this conversation as resolved.
Outdated
|
||
| //! account for your existed external owned account (seed phrase based). The onchain | ||
|
akru marked this conversation as resolved.
Outdated
|
||
| //! account could be drived to multiple address spaces: H160 and SS58. For example, | ||
|
akru marked this conversation as resolved.
Outdated
|
||
| //! it makes possible predictable interaction between substrate native account and | ||
| //! EVM smart contracts. | ||
|
akru marked this conversation as resolved.
Outdated
|
||
| //! | ||
| //! ## Interface | ||
| //! | ||
| //! ### Dispatchable Function | ||
| //! | ||
| //! * new_origin() - create new origin for account | ||
| //! * proxy_call() - make proxy call with derived account as origin | ||
| //! * meta_call() - make meta call with dedicated payer account | ||
| //! | ||
|
|
||
| #![cfg_attr(not(feature = "std"), no_std)] | ||
|
|
||
| pub mod origins; | ||
| pub use origins::*; | ||
|
|
||
| pub mod pallet; | ||
| pub use pallet::pallet::*; | ||
|
|
||
| pub mod weights; | ||
| pub use weights::*; | ||
|
|
||
| #[cfg(test)] | ||
| mod mock; | ||
| #[cfg(test)] | ||
| mod tests; | ||
|
akru marked this conversation as resolved.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| // This file is part of Astar. | ||
|
|
||
| // Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
|
|
||
| // Astar is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
|
|
||
| // Astar is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU General Public License for more details. | ||
|
|
||
| // You should have received a copy of the GNU General Public License | ||
| // along with Astar. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| use crate as pallet_account; | ||
|
|
||
| use frame_support::{ | ||
| construct_runtime, parameter_types, sp_io::TestExternalities, weights::Weight, | ||
| }; | ||
| use hex_literal::hex; | ||
| use sp_core::H256; | ||
| use sp_runtime::{ | ||
| testing::Header, | ||
| traits::{BlakeTwo256, IdentityLookup}, | ||
| AccountId32, | ||
| }; | ||
|
|
||
| pub(crate) type AccountId = AccountId32; | ||
| pub(crate) type BlockNumber = u64; | ||
| pub(crate) type Balance = u128; | ||
|
|
||
| pub(crate) const ALICE: AccountId = AccountId::new([0u8; 32]); | ||
| pub(crate) const BOB: AccountId = AccountId::new([1u8; 32]); | ||
|
|
||
| pub(crate) const ALICE_ED25519: [u8; 32] = | ||
| hex!["88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee"]; | ||
|
|
||
| pub(crate) const ALICE_D1_NATIVE: [u8; 32] = | ||
| hex!["9f0e444c69f77a49bd0be89db92c38fe713e0963165cca12faf5712d7657120f"]; | ||
| pub(crate) const ALICE_D2_H160: [u8; 20] = hex!["5d2532e641a22a8f5e0a42652fe82dc231fd27f8"]; | ||
|
|
||
| type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<TestRuntime>; | ||
| type Block = frame_system::mocking::MockBlock<TestRuntime>; | ||
|
|
||
| /// Value shouldn't be less than 2 for testing purposes, otherwise we cannot test certain corner cases. | ||
| pub(crate) const EXISTENTIAL_DEPOSIT: Balance = 2; | ||
|
|
||
| construct_runtime!( | ||
| pub struct TestRuntime | ||
| where | ||
| Block = Block, | ||
| NodeBlock = Block, | ||
| UncheckedExtrinsic = UncheckedExtrinsic, | ||
| { | ||
| System: frame_system, | ||
| Balances: pallet_balances, | ||
| Account: pallet_account, | ||
| } | ||
| ); | ||
|
|
||
| parameter_types! { | ||
| pub const BlockHashCount: u64 = 250; | ||
| pub BlockWeights: frame_system::limits::BlockWeights = | ||
| frame_system::limits::BlockWeights::simple_max(Weight::from_ref_time(1024)); | ||
| } | ||
|
|
||
| impl frame_system::Config for TestRuntime { | ||
| type BaseCallFilter = frame_support::traits::Everything; | ||
| type BlockWeights = (); | ||
| type BlockLength = (); | ||
| type RuntimeOrigin = RuntimeOrigin; | ||
| type Index = u64; | ||
| type RuntimeCall = RuntimeCall; | ||
| type BlockNumber = BlockNumber; | ||
| type Hash = H256; | ||
| type Hashing = BlakeTwo256; | ||
| type AccountId = AccountId; | ||
| type Lookup = IdentityLookup<Self::AccountId>; | ||
| type Header = Header; | ||
| type RuntimeEvent = RuntimeEvent; | ||
| type BlockHashCount = BlockHashCount; | ||
| type DbWeight = (); | ||
| type Version = (); | ||
| type PalletInfo = PalletInfo; | ||
| type AccountData = pallet_balances::AccountData<Balance>; | ||
| type OnNewAccount = (); | ||
| type OnKilledAccount = (); | ||
| type SystemWeightInfo = (); | ||
| type SS58Prefix = (); | ||
| type OnSetCode = (); | ||
| type MaxConsumers = frame_support::traits::ConstU32<16>; | ||
| } | ||
|
|
||
| parameter_types! { | ||
| pub const MaxLocks: u32 = 4; | ||
| pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT; | ||
| } | ||
|
|
||
| impl pallet_balances::Config for TestRuntime { | ||
| type MaxLocks = MaxLocks; | ||
| type MaxReserves = (); | ||
| type ReserveIdentifier = [u8; 8]; | ||
| type Balance = Balance; | ||
| type RuntimeEvent = RuntimeEvent; | ||
| type DustRemoval = (); | ||
| type ExistentialDeposit = ExistentialDeposit; | ||
| type AccountStore = System; | ||
| type WeightInfo = (); | ||
| } | ||
|
|
||
| parameter_types! { | ||
| pub const ChainMagic: u16 = 0x4200; | ||
| } | ||
|
|
||
| impl pallet_account::Config for TestRuntime { | ||
| type CustomOrigin = super::NativeAndEVM; | ||
| type CustomOriginKind = super::NativeAndEVMKind; | ||
| type RuntimeOrigin = RuntimeOrigin; | ||
| type RuntimeCall = RuntimeCall; | ||
| type ChainMagic = ChainMagic; | ||
| type Signer = sp_runtime::MultiSigner; | ||
| type Signature = sp_runtime::MultiSignature; | ||
| type RuntimeEvent = RuntimeEvent; | ||
| type WeightInfo = (); | ||
| } | ||
|
|
||
| pub struct ExternalityBuilder; | ||
|
|
||
| impl ExternalityBuilder { | ||
| pub fn build() -> TestExternalities { | ||
| let mut storage = frame_system::GenesisConfig::default() | ||
| .build_storage::<TestRuntime>() | ||
| .unwrap(); | ||
|
|
||
| // This will cause some initial issuance | ||
| pallet_balances::GenesisConfig::<TestRuntime> { | ||
| balances: vec![ | ||
| (ALICE, 9000), | ||
| (ALICE_ED25519.into(), 1000), | ||
| (ALICE_D1_NATIVE.into(), 1000), | ||
| (BOB, 800), | ||
| ], | ||
| } | ||
| .assimilate_storage(&mut storage) | ||
| .ok(); | ||
|
|
||
| let mut ext = TestExternalities::from(storage); | ||
| ext.execute_with(|| System::set_block_number(1)); | ||
| ext | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| // This file is part of Astar. | ||
|
|
||
| // Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
|
|
||
| // Astar is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
|
|
||
| // Astar is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU General Public License for more details. | ||
|
|
||
| // You should have received a copy of the GNU General Public License | ||
| // along with Astar. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; | ||
| use scale_info::TypeInfo; | ||
| use sp_runtime::{AccountId32, RuntimeDebug}; | ||
|
|
||
| /// Derive new origin. | ||
| pub trait OriginDeriving<AccountId, Origin> { | ||
| /// Derive new origin depend of account and index | ||
| fn derive(&self, source: &AccountId, index: u32) -> Origin; | ||
| } | ||
|
|
||
| /// Origin that support native and EVM compatible options. | ||
| #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] | ||
| pub enum NativeAndEVM { | ||
|
akru marked this conversation as resolved.
|
||
| /// Substrate native origin. | ||
| Native(AccountId32), | ||
| /// The 20-byte length Ethereum like origin. | ||
| H160(sp_core::H160), | ||
| } | ||
|
|
||
| impl TryInto<AccountId32> for NativeAndEVM { | ||
| type Error = (); | ||
| fn try_into(self) -> Result<AccountId32, Self::Error> { | ||
| match self { | ||
| NativeAndEVM::Native(a) => Ok(a), | ||
| _ => Err(()), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Kind for NativeAndEVM origin. | ||
| #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] | ||
| pub enum NativeAndEVMKind { | ||
| Native, | ||
| H160, | ||
| } | ||
|
Comment on lines
+60
to
+63
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps adding
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably yes, but may be we can generate *Kind structure from custom origin somehow. I'll investigate later. |
||
|
|
||
| impl OriginDeriving<AccountId32, NativeAndEVM> for NativeAndEVMKind { | ||
| fn derive(&self, source: &AccountId32, index: u32) -> NativeAndEVM { | ||
| let salted_source = [source.as_ref(), &index.encode()[..]].concat(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
EDIT: probably not a good idea to be compatible with pallet-utilities. Compatibility with main stream derivation standard is more important
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly, at first stage I prefer to give some sample of usage and no more. What’s about derivation standard, it could be easily implemented outside of the pallet. |
||
| let derived = sp_core::blake2_256(&salted_source); | ||
| match self { | ||
| NativeAndEVMKind::Native => NativeAndEVM::Native(derived.into()), | ||
| NativeAndEVMKind::H160 => NativeAndEVM::H160(sp_core::H160::from_slice(&derived[..20])), | ||
| } | ||
| } | ||
|
Comment on lines
+66
to
+73
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dumb question: is our custom origin deriving meant to derive between H160 and Native? The impl here seems only to derive sub-accounts from their own type.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, to create new origin the call origin must be substrate-compatible. |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use workspace inheritance for relevant package info values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added