diff --git a/frame/ethereum/src/lib.rs b/frame/ethereum/src/lib.rs index 2038964f95..16a7ba9e71 100644 --- a/frame/ethereum/src/lib.rs +++ b/frame/ethereum/src/lib.rs @@ -30,6 +30,7 @@ use sp_runtime::{ traits::UniqueSaturatedInto, transaction_validity::{TransactionValidity, TransactionSource, ValidTransaction} }; +use rlp; use sha3::{Digest, Keccak256}; pub use frontier_rpc_primitives::TransactionStatus; diff --git a/rpc/core/src/eth.rs b/rpc/core/src/eth.rs index c6aebcd559..10b019ad47 100644 --- a/rpc/core/src/eth.rs +++ b/rpc/core/src/eth.rs @@ -77,7 +77,7 @@ pub trait EthApi { /// Returns content of the storage at given address. #[rpc(name = "eth_getStorageAt")] - fn storage_at(&self, _: H160, _: U256, _: Option) -> BoxFuture; + fn storage_at(&self, _: H160, _: U256, _: Option) -> Result; /// Returns block with given hash. #[rpc(name = "eth_getBlockByHash")] diff --git a/rpc/primitives/src/lib.rs b/rpc/primitives/src/lib.rs index 5ffa8ef55c..190a3bb2c0 100644 --- a/rpc/primitives/src/lib.rs +++ b/rpc/primitives/src/lib.rs @@ -42,6 +42,7 @@ sp_api::decl_runtime_apis! { fn gas_price() -> U256; fn account_code_at(address: H160) -> Vec; fn author() -> H160; + fn storage_at(address: H160, index: U256) -> H256; fn block_by_number(number: u32) -> Option; fn block_transaction_count_by_number(number: u32) -> Option; fn block_by_hash(hash: H256) -> Option; diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index 4c75affb71..9d2dc609f5 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -230,8 +230,23 @@ impl EthApiT for EthApi where unimplemented!("proof"); } - fn storage_at(&self, _: H160, _: U256, _: Option) -> BoxFuture { - unimplemented!("storage_at"); + fn storage_at(&self, address: H160, index: U256, number: Option) -> Result { + if let Some(number) = number { + if number != BlockNumber::Latest { + unimplemented!("fetch storage for past blocks is not yet supported"); + } + } + let header = self + .select_chain + .best_chain() + .map_err(|_| internal_err("fetch header failed"))?; + Ok( + self.client + .runtime_api() + .storage_at(&BlockId::Hash(header.hash()), address, index) + .map_err(|_| internal_err("fetch runtime chain id failed"))? + .into(), + ) } fn block_by_hash(&self, hash: H256, _: bool) -> Result> { diff --git a/template/runtime/src/lib.rs b/template/runtime/src/lib.rs index ab23dd4e60..6a10cab216 100644 --- a/template/runtime/src/lib.rs +++ b/template/runtime/src/lib.rs @@ -475,6 +475,12 @@ impl_runtime_apis! { } } + fn storage_at(address: H160, index: U256) -> H256 { + let mut tmp = [0u8; 32]; + index.to_big_endian(&mut tmp); + evm::Module::::account_storages(address, H256::from_slice(&tmp[..])) + } + fn block_by_number(number: u32) -> Option { >::block_by_number(number) }