From 7509e42d3bc53aa982dec4c5cf0e1950eef3f9f8 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 18 May 2022 16:49:32 +0200 Subject: [PATCH] fix: serialize eth_getStorageAt position param as quantity (#1281) * fix: serialize eth_getStorageAt position param as quantity * test: add quantity test --- ethers-providers/src/provider.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/ethers-providers/src/provider.rs b/ethers-providers/src/provider.rs index ef287a537..a2d4c48b7 100644 --- a/ethers-providers/src/provider.rs +++ b/ethers-providers/src/provider.rs @@ -728,12 +728,15 @@ impl Middleware for Provider

{ NameOrAddress::Address(addr) => addr, }; + // position is a QUANTITY according to the [spec](https://eth.wiki/json-rpc/API#eth_getstorageat): integer of the position in the storage, converting this to a U256 + // will make sure the number is formatted correctly as [quantity](https://eips.ethereum.org/EIPS/eip-1474#quantity) + let position = U256::from_big_endian(location.as_bytes()); + let position = utils::serialize(&position); let from = utils::serialize(&from); - let location = utils::serialize(&location); let block = utils::serialize(&block.unwrap_or_else(|| BlockNumber::Latest.into())); // get the hex encoded value. - let value: String = self.request("eth_getStorageAt", [from, location, block]).await?; + let value: String = self.request("eth_getStorageAt", [from, position, block]).await?; // get rid of the 0x prefix and left pad it with zeroes. let value = format!("{:0>64}", value.replace("0x", "")); Ok(H256::from_slice(&Vec::from_hex(value)?)) @@ -1526,6 +1529,22 @@ mod tests { }; use futures_util::StreamExt; + #[test] + fn convert_h256_u256_quantity() { + let hash: H256 = H256::zero(); + let quantity = U256::from_big_endian(hash.as_bytes()); + assert_eq!(format!("{quantity:#x}"), "0x0"); + assert_eq!(utils::serialize(&quantity).to_string(), "\"0x0\""); + + let address: Address = "0x295a70b2de5e3953354a6a8344e616ed314d7251".parse().unwrap(); + let block = BlockNumber::Latest; + let params = + [utils::serialize(&address), utils::serialize(&quantity), utils::serialize(&block)]; + + let params = serde_json::to_string(¶ms).unwrap(); + assert_eq!(params, r#"["0x295a70b2de5e3953354a6a8344e616ed314d7251","0x0","latest"]"#); + } + #[tokio::test] // Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2 async fn mainnet_resolve_name() {