From 3f3753b8e4d214d9bb72a3300d8e8d6ff01e266a Mon Sep 17 00:00:00 2001
From: Wei Tang <hi@that.world>
Date: Wed, 20 May 2020 21:33:16 +0200
Subject: [PATCH] evm: allow setting pre-defined accounts in genesis (#6086)

* evm: allow setting pre-defined accounts in genesis

* Only build GenesisAccount in std
---
 substrate/bin/node/runtime/src/lib.rs |  2 +-
 substrate/frame/evm/src/lib.rs        | 37 ++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index 834aabbef8b..eb8344d3e95 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -93,7 +93,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	// and set impl_version to 0. If only runtime
 	// implementation changes and behavior does not, then leave spec_version as
 	// is and increment impl_version.
-	spec_version: 249,
+	spec_version: 250,
 	impl_version: 0,
 	apis: RUNTIME_API_VERSIONS,
 	transaction_version: 1,
diff --git a/substrate/frame/evm/src/lib.rs b/substrate/frame/evm/src/lib.rs
index a2354c7761b..eab3c80a93e 100644
--- a/substrate/frame/evm/src/lib.rs
+++ b/substrate/frame/evm/src/lib.rs
@@ -25,6 +25,10 @@ mod backend;
 pub use crate::backend::{Account, Log, Vicinity, Backend};
 
 use sp_std::{vec::Vec, marker::PhantomData};
+#[cfg(feature = "std")]
+use codec::{Encode, Decode};
+#[cfg(feature = "std")]
+use serde::{Serialize, Deserialize};
 use frame_support::{ensure, decl_module, decl_storage, decl_event, decl_error};
 use frame_support::weights::{Weight, DispatchClass, FunctionOf, Pays};
 use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement, Get};
@@ -137,12 +141,43 @@ pub trait Trait: frame_system::Trait + pallet_timestamp::Trait {
 	}
 }
 
+#[cfg(feature = "std")]
+#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, Serialize, Deserialize)]
+/// Account definition used for genesis block construction.
+pub struct GenesisAccount {
+	/// Account nonce.
+	pub nonce: U256,
+	/// Account balance.
+	pub balance: U256,
+	/// Full account storage.
+	pub storage: std::collections::BTreeMap<H256, H256>,
+	/// Account code.
+	pub code: Vec<u8>,
+}
+
 decl_storage! {
 	trait Store for Module<T: Trait> as EVM {
-		Accounts get(fn accounts) config(): map hasher(blake2_128_concat) H160 => Account;
+		Accounts get(fn accounts): map hasher(blake2_128_concat) H160 => Account;
 		AccountCodes: map hasher(blake2_128_concat) H160 => Vec<u8>;
 		AccountStorages: double_map hasher(blake2_128_concat) H160, hasher(blake2_128_concat) H256 => H256;
 	}
+
+	add_extra_genesis {
+		config(accounts): std::collections::BTreeMap<H160, GenesisAccount>;
+		build(|config: &GenesisConfig| {
+			for (address, account) in &config.accounts {
+				Accounts::insert(address, Account {
+					balance: account.balance,
+					nonce: account.nonce,
+				});
+				AccountCodes::insert(address, &account.code);
+
+				for (index, value) in &account.storage {
+					AccountStorages::insert(address, index, value);
+				}
+			}
+		});
+	}
 }
 
 decl_event! {
-- 
GitLab